Compare commits
No commits in common. "master" and "TeleportWork" have entirely different histories.
master
...
TeleportWo
.nant
OpenSim
Addons
Groups
Properties
OfflineIM
ApplicationPlugins
LoadRegions
RegionModulesController
RemoteController
Capabilities
Handlers
AvatarPickerSearch
FetchInventory2
GetAssets
Properties
UploadBakedTexture
WebFetchInventoryDescendents
ConsoleClient
Data
MSSQL
Properties
|
@ -1,6 +1,5 @@
|
|||
.project
|
||||
.settings
|
||||
.gitignore
|
||||
*.csproj
|
||||
*.csproj.user
|
||||
*.build
|
||||
|
@ -11,13 +10,6 @@
|
|||
*.pidb
|
||||
*.dll.build
|
||||
*.dll
|
||||
*.log
|
||||
|
||||
# Ignore .user and .suo files as these are user preference specific
|
||||
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
||||
*.suo
|
||||
*.user
|
||||
|
||||
*.VisualState.xml
|
||||
*/*/obj
|
||||
*/*/*/obj
|
||||
|
@ -31,8 +23,6 @@
|
|||
*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/*/bin
|
||||
.vs/
|
||||
addon-modules/
|
||||
bin/Debug/*.dll
|
||||
bin/*.dll.mdb
|
||||
bin/*.db
|
||||
|
@ -58,7 +48,6 @@ bin/Regions/*
|
|||
bin/UserAssets
|
||||
bin/assetcache
|
||||
bin/maptiles
|
||||
bin/bakes
|
||||
bin/estate_settings.xml
|
||||
bin/config-include/CenomeCache.ini
|
||||
bin/config-include/FlotsamCache.ini
|
||||
|
@ -71,17 +60,12 @@ 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.suo
|
||||
OpenSim.userprefs
|
||||
Prebuild/Prebuild.build
|
||||
Prebuild/Prebuild.sln
|
||||
|
@ -94,6 +78,7 @@ TAGS
|
|||
Makefile.local
|
||||
bin/.version
|
||||
compile.bat
|
||||
addon-modules
|
||||
OpenSim/Data/Tests/test-results/
|
||||
OpenSim/Framework/Serialization/Tests/test-results/
|
||||
OpenSim/Framework/Servers/Tests/test-results/
|
||||
|
@ -112,5 +97,3 @@ OpenSim/Tests/test-results/
|
|||
test-results/
|
||||
doc/html
|
||||
doc/doxygen.error.log
|
||||
|
||||
*.patch
|
||||
|
|
|
@ -113,12 +113,10 @@
|
|||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
||||
|
||||
<!--
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||
-->
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.framework.tests">
|
||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
||||
|
@ -145,11 +143,6 @@
|
|||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.permissions">
|
||||
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
|
||||
|
||||
<delete dir="%temp%"/>
|
||||
</target>
|
||||
|
||||
|
@ -233,12 +226,10 @@
|
|||
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<!--
|
||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
||||
<arg value="-xml=test-results/OpenSim.Region.OptionalModules.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
-->
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
|
||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
||||
|
@ -265,23 +256,17 @@
|
|||
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.tests.permissions">
|
||||
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
|
||||
<arg value="-xml=test-results/OpenSim.Tests.Permissions.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
||||
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" /> -->
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
|
||||
</target>
|
||||
|
||||
<target name="doxygen">
|
||||
|
|
29
BUILDING.md
29
BUILDING.md
|
@ -1,35 +1,34 @@
|
|||
# Building on Windows
|
||||
|
||||
Steps:
|
||||
|
||||
* runprebuild.bat
|
||||
* Load OpenSim.sln into Visual Studio .NET and build the solution.
|
||||
* chdir bin
|
||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||
* run OpenSim.exe
|
||||
|
||||
# Building on Linux / Mac
|
||||
# Building on Linux
|
||||
|
||||
Prereqs:
|
||||
|
||||
* Mono > 5.0
|
||||
* Mono >= 2.4.3
|
||||
* Nant >= 0.85
|
||||
* On some Linux distributions you may need to install additional packages.
|
||||
* msbuild or xbuild if still supported by the mono version
|
||||
* See http://opensimulator.org/wiki/Dependencies for more information.
|
||||
See http://opensimulator.org/wiki/Dependencies for more information.
|
||||
* May also use xbuild (included in mono distributions)
|
||||
* May use Monodevelop, a cross-platform IDE
|
||||
|
||||
From the distribution type:
|
||||
|
||||
* ./runprebuild.sh
|
||||
* type msbuild or xbuild
|
||||
* nant (or xbuild)
|
||||
* cd bin
|
||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||
* review and change those ini files according to your needs
|
||||
* windows: execute opensim.exe or opensim32.exe for small regions
|
||||
* linux: run ./opensim.sh
|
||||
* msbuild (xbuild) option switches
|
||||
* clean: msbuild /target:clean
|
||||
* debug: (default) msbuild /property:Configuration=Debug
|
||||
* release: msbuild /property:Configuration=Release
|
||||
* run mono OpenSim.exe
|
||||
|
||||
# Using Monodevelop
|
||||
|
||||
From the distribution type:
|
||||
* ./runprebuild.sh
|
||||
* type monodevelop OpenSim.sln
|
||||
|
||||
# References
|
||||
|
||||
|
|
103
CONTRIBUTORS.txt
103
CONTRIBUTORS.txt
|
@ -1,22 +1,39 @@
|
|||
The following people have contributed to OpenSim (Thank you for your effort!)
|
||||
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||
for your effort!)
|
||||
|
||||
= Current OpenSim Developers (in very rough order of appearance) =
|
||||
These folks represent the current core team for OpenSim, and are the
|
||||
people that make the day to day of OpenSim happen.
|
||||
|
||||
* justincc (OSVW Consulting, justincc.org)
|
||||
* chi11ken (Genkii)
|
||||
* dahlia
|
||||
* Melanie Thielker
|
||||
* Diva (Crista Lopes, University of California, Irvine)
|
||||
* Robert Adams (MisterBlue)
|
||||
* Kevin Cozens
|
||||
* Leal Duarte (Ubit Umarov)
|
||||
* Dan Lake (Intel)
|
||||
* Marck
|
||||
* Mic Bowman (Intel)
|
||||
* BlueWall (James Hughes)
|
||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||
* Snoopy Pfeffer
|
||||
* Robert Adams (Intel)
|
||||
|
||||
= Core Developers Following the White Rabbit =
|
||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||
They are in all similar to the active core developers, except that they haven't
|
||||
been that active lately, so their voting rights are awaiting their come back.
|
||||
|
||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||
* Alicia Raven
|
||||
* MW (Tribal Media AB)
|
||||
* Adam Frisby (DeepThink Pty Ltd)
|
||||
* lbsa71 (Tribal Media AB)
|
||||
* Teravus (w3z)
|
||||
* Ckrinke (Charles Krinke)
|
||||
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
||||
* mikem (3Di)
|
||||
* Homer_Horwitz
|
||||
* nlin (3Di)
|
||||
* Arthur Rodrigo S Valadares (IBM)
|
||||
* John Hurliman
|
||||
|
||||
= Past Open Sim Developers =
|
||||
These folks are alumns of the OpenSim core group, but are now
|
||||
|
@ -38,86 +55,50 @@ where we are today.
|
|||
* adjohn (Genkii)
|
||||
* idb (Ian Brown)
|
||||
* Johan Berntsson (3Di)
|
||||
* MW (Tribal Media AB)
|
||||
* Adam Frisby (DeepThink Pty Ltd)
|
||||
* lbsa71 (Tribal Media AB)
|
||||
* Ckrinke (Charles Krinke)
|
||||
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
||||
* mikem (3Di)
|
||||
* Homer_Horwitz
|
||||
* nlin (3Di)
|
||||
* John Hurliman
|
||||
* chi11ken (Genkii)
|
||||
* dahlia
|
||||
* justincc (OSVW Consulting, justincc.org)
|
||||
* Arthur Rodrigo S Valadares (IBM)
|
||||
* BlueWall (James Hughes)
|
||||
* Dan Lake
|
||||
* Marck
|
||||
* Mic Bowman
|
||||
* Oren Hurvitz (Kitely)
|
||||
* Snoopy Pfeffer
|
||||
* Teravus (w3z)
|
||||
|
||||
|
||||
= Additional OpenSim Contributors =
|
||||
These folks have contributed code patches or content to OpenSimulator to help make it
|
||||
what it is today.
|
||||
|
||||
* A_Biondi
|
||||
* aduffy70
|
||||
* Ai Austin
|
||||
* A_Biondi
|
||||
* alex_carnell
|
||||
* Alan Webb (IBM)
|
||||
* Aleric
|
||||
* Allen Kerensky
|
||||
* BigFootAg
|
||||
* Bill Blight
|
||||
* BlueWall Slade
|
||||
* bobshaffer2
|
||||
* brianw/Sir_Ahzz
|
||||
* CharlieO
|
||||
* ChrisDown
|
||||
* Chris Yeoh (IBM)
|
||||
* cinderblocks
|
||||
* controlbreak
|
||||
* coyled
|
||||
* ctrlaltdavid (David Rowe)
|
||||
* Daedius
|
||||
* daTwitch
|
||||
* Dev Random
|
||||
* devalnor-#708
|
||||
* dmiles (Daxtron Labs)
|
||||
* Dong Jun Lan (IBM)
|
||||
* DoranZemlja
|
||||
* Drake Arconis
|
||||
* dr0b3rts
|
||||
* dslake
|
||||
* eeyore
|
||||
* dslake (Intel)
|
||||
* FredoChaplin
|
||||
* FreakyTech
|
||||
* Garmin Kawaguichi
|
||||
* Gavin Hird
|
||||
* Gerhard
|
||||
* Godfrey
|
||||
* Greg C.
|
||||
* Grumly57
|
||||
* GuduleLapointe
|
||||
* Ewe Loon
|
||||
* Fernando Oliveira
|
||||
* Fly-Man
|
||||
* Flyte Xevious
|
||||
* Freaky Tech
|
||||
* Garmin Kawaguichi
|
||||
* Geir Noklebye
|
||||
* Glenn Martin (MOSES)
|
||||
* Gryc Ueusp
|
||||
* H-H-H (ginge264)
|
||||
* Hiro Lecker
|
||||
* Iain Oliver
|
||||
* Imaze Rhiano
|
||||
* Intimidated
|
||||
* Jak Daniels
|
||||
* Jeff Kelly
|
||||
* Jeremy Bongio (IBM)
|
||||
* jhurliman
|
||||
* John R Sohn (XenReborn)
|
||||
|
@ -125,36 +106,25 @@ what it is today.
|
|||
* Jon Cundill
|
||||
* Junta Kohime
|
||||
* Kayne
|
||||
* Kevin Cozens
|
||||
* kinoc (Daxtron Labs)
|
||||
* Kira
|
||||
* Kitto Flora
|
||||
* KittyLiu
|
||||
* Kurt Taylor (IBM)
|
||||
* Lani Global
|
||||
* lickx
|
||||
* lillith_xue
|
||||
* lkalif
|
||||
* LuciusSirnah
|
||||
* lulurun
|
||||
* M.Igarashi
|
||||
* Magnuz Binder
|
||||
* maimedleech
|
||||
* Mana Janus
|
||||
* Mandarinka Tasty
|
||||
* MarcelEdward
|
||||
* Matt Lehmann
|
||||
* mewtwo0641
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
* Michael Heilmann (MOSES)
|
||||
* Micheil Merlin
|
||||
* Mike Osias (IBM)
|
||||
* Mike Pitman (IBM)
|
||||
* Mike Rieker (Dreamnation)
|
||||
* mikemig
|
||||
* mikkopa/_someone - RealXtend
|
||||
* Misterblue
|
||||
* Misterblue (Intel)
|
||||
* Mircea Kitsune
|
||||
* mpallari
|
||||
* MrMonkE
|
||||
|
@ -163,42 +133,32 @@ what it is today.
|
|||
* nornalbion
|
||||
* Omar Vera Ustariz (IBM)
|
||||
* openlifegrid.com
|
||||
* Oren Hurvitz (Kitely)
|
||||
* otakup0pe
|
||||
* Pixel Tomsen
|
||||
* Quill Littlefeather
|
||||
* ralphos
|
||||
* RemedyTomm
|
||||
* Revolution
|
||||
* Richard Alimi (IBM)
|
||||
* Rick Alther (IBM)
|
||||
* Rob Smart (IBM)
|
||||
* Robert Louden (MOSES)
|
||||
* Roger Kirkman (zadark)
|
||||
* rtomita
|
||||
* Ruud Lathorp
|
||||
* SachaMagne
|
||||
* Salahzar Stenvaag
|
||||
* satguru p srivastava
|
||||
* sempuki
|
||||
* Shy Robbiani
|
||||
* SignpostMarv
|
||||
* SpotOn3D
|
||||
* Stefan_Boom / stoehr
|
||||
* Steven Zielinski (MOSES)
|
||||
* Stolen Ruby
|
||||
* Strawberry Fride
|
||||
* Talun
|
||||
* TechplexEngineer (Blake Bourque)
|
||||
* TBG Renfold
|
||||
* Terry Ford
|
||||
* tglion
|
||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||
* TomDataWorks
|
||||
* TomTheDragon (muckwaddle)
|
||||
* tyre
|
||||
* uriesk
|
||||
* Vegaslon <vegaslon@gmail.com>
|
||||
* Vincent Sylvester
|
||||
* VikingErik
|
||||
* Vytek
|
||||
* webmage (IBM)
|
||||
|
@ -210,18 +170,23 @@ what it is today.
|
|||
* Zha Ewry
|
||||
* ziah
|
||||
|
||||
|
||||
= LSL Devs =
|
||||
|
||||
* Alondria
|
||||
* CharlieO
|
||||
* Tedd
|
||||
* Melanie Thielker
|
||||
|
||||
|
||||
= Testers =
|
||||
|
||||
* Ai Austin
|
||||
* CharlieO (LSL)
|
||||
* Ckrinke
|
||||
* openlifegrid.com
|
||||
|
||||
|
||||
This software uses components from the following developers:
|
||||
* Sleepycat Software (Berkeley DB)
|
||||
* Aurora-Sim (http://aurora-sim.org)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,7 +30,6 @@ using System.Collections.Generic;
|
|||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace OpenSim.Groups
|
|||
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
||||
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
||||
else
|
||||
grec.ServiceLocation = string.Empty;
|
||||
grec.GroupName = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
||||
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
||||
|
|
|
@ -56,8 +56,8 @@ namespace OpenSim.Groups
|
|||
private IGroupsServicesConnector m_groupData = null;
|
||||
|
||||
// Config Options
|
||||
private bool m_groupMessagingEnabled;
|
||||
private bool m_debugEnabled;
|
||||
private bool m_groupMessagingEnabled = false;
|
||||
private bool m_debugEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
||||
|
@ -83,6 +83,7 @@ namespace OpenSim.Groups
|
|||
private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
|
||||
private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
|
||||
|
||||
|
||||
#region Region Module interfaceBase Members
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
|
@ -110,17 +111,9 @@ namespace OpenSim.Groups
|
|||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
||||
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
{
|
||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
|
||||
m_groupMessagingEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
|
||||
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
||||
|
@ -140,14 +133,6 @@ namespace OpenSim.Groups
|
|||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
|
||||
scene.AddCommand(
|
||||
"Debug",
|
||||
this,
|
||||
"debug groups messaging verbose",
|
||||
"debug groups messaging verbose <true|false>",
|
||||
"This setting turns on very verbose groups messaging debugging",
|
||||
HandleDebugGroupsMessagingVerbose);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
@ -187,8 +172,10 @@ namespace OpenSim.Groups
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_presenceService == null)
|
||||
m_presenceService = scene.PresenceService;
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
|
@ -235,25 +222,6 @@ namespace OpenSim.Groups
|
|||
|
||||
#endregion
|
||||
|
||||
private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
|
||||
{
|
||||
if (args.Length < 5)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
bool verbose = false;
|
||||
if (!bool.TryParse(args[4], out verbose))
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
m_debugEnabled = verbose;
|
||||
|
||||
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not really needed, but does confirm that the group exists.
|
||||
|
@ -277,20 +245,8 @@ namespace OpenSim.Groups
|
|||
|
||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
||||
{
|
||||
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
||||
}
|
||||
|
||||
public void SendMessageToGroup(
|
||||
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
||||
{
|
||||
int requestStartTick = Environment.TickCount;
|
||||
|
||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
||||
|
||||
// Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
|
||||
// is not necessary.
|
||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
|
||||
|
||||
int groupMembersCount = groupMembers.Count;
|
||||
PresenceInfo[] onlineAgents = null;
|
||||
|
||||
|
@ -298,7 +254,7 @@ namespace OpenSim.Groups
|
|||
// Sending to offline members is not an option.
|
||||
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
|
||||
|
||||
// We cache in order not to overwhelm the presence service on large grids with many groups. This does
|
||||
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
|
||||
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
|
||||
// (assuming this is the same across all grid simulators).
|
||||
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
|
||||
|
@ -317,6 +273,8 @@ namespace OpenSim.Groups
|
|||
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
||||
// groupID, groupMembersCount, groupMembers.Count());
|
||||
|
||||
int requestStartTick = Environment.TickCount;
|
||||
|
||||
im.imSessionID = groupID.Guid;
|
||||
im.fromGroup = true;
|
||||
IClientAPI thisClient = GetActiveClient(fromAgentID);
|
||||
|
@ -325,13 +283,6 @@ namespace OpenSim.Groups
|
|||
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
|
||||
}
|
||||
|
||||
if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
|
||||
{
|
||||
ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
|
||||
if (groupInfo != null)
|
||||
im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
|
||||
}
|
||||
|
||||
// Send to self first of all
|
||||
im.toAgentID = im.fromAgentID;
|
||||
im.fromGroup = true;
|
||||
|
@ -348,27 +299,12 @@ namespace OpenSim.Groups
|
|||
|
||||
if (clientsAlreadySent.Contains(member.AgentID))
|
||||
continue;
|
||||
|
||||
clientsAlreadySent.Add(member.AgentID);
|
||||
|
||||
if (sendCondition != null)
|
||||
{
|
||||
if (!sendCondition(member))
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
|
||||
member.AgentID);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||
if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||
{
|
||||
// Don't deliver messages to people who have dropped this session
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
||||
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -599,16 +535,13 @@ namespace OpenSim.Groups
|
|||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
||||
|
||||
UUID fromAgent = new UUID(msg.fromAgentID);
|
||||
// Force? open the group session dialog???
|
||||
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
||||
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
if (eq != null)
|
||||
{
|
||||
eq.ChatterboxInvitation(
|
||||
GroupID
|
||||
, groupInfo.GroupName
|
||||
, fromAgent
|
||||
, new UUID(msg.fromAgentID)
|
||||
, msg.message
|
||||
, AgentID
|
||||
, msg.fromAgentName
|
||||
|
@ -623,10 +556,14 @@ namespace OpenSim.Groups
|
|||
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
||||
);
|
||||
|
||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
||||
eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
|
||||
}
|
||||
eq.ChatterBoxSessionAgentListUpdates(
|
||||
new UUID(GroupID)
|
||||
, AgentID
|
||||
, new UUID(msg.toAgentID)
|
||||
, false //canVoiceChat
|
||||
, false //isModerator
|
||||
, false //text mute
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -661,12 +598,14 @@ namespace OpenSim.Groups
|
|||
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
|
||||
|
||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
if (queue != null)
|
||||
{
|
||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
||||
queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates);
|
||||
}
|
||||
queue.ChatterBoxSessionAgentListUpdates(
|
||||
GroupID
|
||||
, AgentID
|
||||
, new UUID(im.toAgentID)
|
||||
, false //canVoiceChat
|
||||
, false //isModerator
|
||||
, false //text mute
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,7 +647,11 @@ namespace OpenSim.Groups
|
|||
bodyMap.Add("session_info", sessionMap);
|
||||
|
||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
||||
|
||||
if (queue != null)
|
||||
{
|
||||
queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugGridInstantMessage(GridInstantMessage im)
|
||||
|
|
|
@ -38,13 +38,16 @@ using OpenSim.Framework;
|
|||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using PermissionMask = OpenSim.Framework.PermissionMask;
|
||||
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
|
||||
public class GroupsModule : ISharedRegionModule, IGroupsModule
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
|
@ -101,7 +104,7 @@ namespace OpenSim.Groups
|
|||
{
|
||||
scene.RegisterModuleInterface<IGroupsModule>(this);
|
||||
scene.AddCommand(
|
||||
"Debug",
|
||||
"debug",
|
||||
this,
|
||||
"debug groups verbose",
|
||||
"debug groups verbose <true|false>",
|
||||
|
@ -127,7 +130,7 @@ namespace OpenSim.Groups
|
|||
|
||||
m_debugEnabled = verbose;
|
||||
|
||||
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||
MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
@ -137,6 +140,13 @@ namespace OpenSim.Groups
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -175,11 +185,6 @@ namespace OpenSim.Groups
|
|||
m_sceneList.Add(scene);
|
||||
}
|
||||
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnMakeRootAgent += OnMakeRoot;
|
||||
scene.EventManager.OnMakeChildAgent += OnMakeChild;
|
||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
||||
scene.EventManager.OnClientClosed += OnClientClosed;
|
||||
|
||||
}
|
||||
|
||||
|
@ -194,7 +199,6 @@ namespace OpenSim.Groups
|
|||
scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
|
||||
scene.EventManager.OnMakeChildAgent -= OnMakeChild;
|
||||
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
|
||||
scene.EventManager.OnClientClosed -= OnClientClosed;
|
||||
|
||||
lock (m_sceneList)
|
||||
{
|
||||
|
@ -233,10 +237,9 @@ namespace OpenSim.Groups
|
|||
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
|
||||
//client.OnRequestAvatarProperties += OnRequestAvatarProperties;
|
||||
client.OnRequestAvatarProperties += OnRequestAvatarProperties;
|
||||
}
|
||||
|
||||
|
||||
private void OnMakeRoot(ScenePresence sp)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
@ -245,12 +248,8 @@ namespace OpenSim.Groups
|
|||
// Used for Notices and Group Invites/Accept/Reject
|
||||
sp.ControllingClient.OnInstantMessage += OnInstantMessage;
|
||||
|
||||
// Send out group data update for compatibility.
|
||||
// There might be some problem with the thread we're generating this on but not
|
||||
// doing the update at this time causes problems (Mantis #7920 and #7915)
|
||||
// TODO: move sending this update to a later time in the rootification of the client.
|
||||
if(!sp.m_haveGroupInformation)
|
||||
SendAgentGroupDataUpdate(sp.ControllingClient, false);
|
||||
// Send client their groups information.
|
||||
SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
|
||||
}
|
||||
|
||||
private void OnMakeChild(ScenePresence sp)
|
||||
|
@ -261,33 +260,28 @@ namespace OpenSim.Groups
|
|||
// 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);
|
||||
}
|
||||
*/
|
||||
private void OnClientClosed(UUID AgentId, Scene scene)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
ScenePresence sp = scene.GetScenePresence(AgentId);
|
||||
IClientAPI client = sp.ControllingClient;
|
||||
if (client != null)
|
||||
{
|
||||
client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
|
||||
//client.OnRequestAvatarProperties -= OnRequestAvatarProperties;
|
||||
// make child possible not called?
|
||||
client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
|
||||
client.OnInstantMessage -= OnInstantMessage;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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))
|
||||
|
@ -305,22 +299,31 @@ namespace OpenSim.Groups
|
|||
if (m_debugEnabled) m_log.WarnFormat("[Groups]: Client closed that wasn't registered here.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
|
||||
{
|
||||
// this a private message for own agent only
|
||||
if (dataForAgentID != GetRequestingAgentID(remoteClient))
|
||||
return;
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
SendAgentGroupDataUpdate(remoteClient, false);
|
||||
UUID activeGroupID = UUID.Zero;
|
||||
string activeGroupTitle = string.Empty;
|
||||
string activeGroupName = string.Empty;
|
||||
ulong activeGroupPowers = (ulong)GroupPowers.None;
|
||||
|
||||
// also current viewers do ignore it and ask later on a much nicer thread
|
||||
// its a info request not a change, so nothing is sent to others
|
||||
// they do get the group title with the avatar object update on arrivel to a region
|
||||
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)
|
||||
|
@ -344,24 +347,14 @@ namespace OpenSim.Groups
|
|||
|
||||
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups]: OnInstantMessage called");
|
||||
|
||||
if(remoteClient == null || !remoteClient.IsActive || remoteClient.AgentId == UUID.Zero)
|
||||
return;
|
||||
|
||||
Scene scene = (Scene)remoteClient.Scene;
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
string remoteAgentIDstr = remoteClient.AgentId.ToString();
|
||||
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(remoteAgentIDstr, inviteID);
|
||||
GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
|
||||
|
||||
if (inviteInfo == null)
|
||||
{
|
||||
|
@ -384,7 +377,7 @@ namespace OpenSim.Groups
|
|||
|
||||
// and the sessionid is the role
|
||||
string reason = string.Empty;
|
||||
if (!m_groupData.AddAgentToGroup(remoteAgentIDstr, invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason))
|
||||
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
|
||||
{
|
||||
|
@ -404,244 +397,127 @@ namespace OpenSim.Groups
|
|||
msg.binaryBucket = new byte[0];
|
||||
|
||||
OutgoingInstantMessage(msg, invitee);
|
||||
IClientAPI inviteeClient = GetActiveRootClient(invitee);
|
||||
if(inviteeClient !=null)
|
||||
{
|
||||
SendAgentGroupDataUpdate(inviteeClient,true);
|
||||
}
|
||||
|
||||
UpdateAllClientsWithGroupInfo(invitee);
|
||||
}
|
||||
|
||||
m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID);
|
||||
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.");
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups]: Received a reject invite notice.");
|
||||
m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
|
||||
|
||||
m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID);
|
||||
m_groupData.RemoveAgentFromGroup(remoteAgentIDstr, inviteInfo.AgentID, inviteInfo.GroupID);
|
||||
m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Group notices
|
||||
else if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
|
||||
if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
|
||||
{
|
||||
if (!m_groupNoticesEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UUID GroupID = new UUID(im.toAgentID);
|
||||
GroupMembershipData grpMemberData = m_groupData.GetAgentGroupMembership(remoteAgentIDstr, remoteAgentIDstr, GroupID);
|
||||
if (grpMemberData == null)
|
||||
if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null) != null)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Group membership not found", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((grpMemberData.GroupPowers & (ulong)GroupPowers.SendNotices) == 0)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("No permission to send notice to group", false);
|
||||
return;
|
||||
}
|
||||
|
||||
int index = im.message.IndexOf('|');
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
string Subject = im.message.Substring(0, index);
|
||||
string Message = im.message.Substring(index + 1);
|
||||
|
||||
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)
|
||||
{
|
||||
UUID itemID = UUID.Zero;
|
||||
UUID ownerID = UUID.Zero;
|
||||
try
|
||||
{
|
||||
string binBucket = Utils.BytesToString(im.binaryBucket);
|
||||
binBucket = binBucket.Substring(15); // remove extra LLSD pre header
|
||||
|
||||
OSDMap binBucketMAP = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
|
||||
itemID = binBucketMAP["item_id"].AsUUID();
|
||||
ownerID = binBucketMAP["owner_id"].AsUUID();
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.DebugFormat("[GROUPS]: failed to decode group notice bucket");
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemID != UUID.Zero && ownerID != UUID.Zero)
|
||||
{
|
||||
item = scene.InventoryService.GetItem(ownerID, itemID);
|
||||
if(item != null)
|
||||
{
|
||||
if ((item.CurrentPermissions & (uint)(PermissionMask.Transfer | PermissionMask.Copy)) !=
|
||||
(uint)(PermissionMask.Transfer | PermissionMask.Copy))
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Item must be have Copy and Transfer rights to attach to group notice", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
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(remoteAgentIDstr, GroupID, NoticeID, im.fromAgentName, Subject, Message,
|
||||
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()))
|
||||
{
|
||||
OnNewGroupNotice?.Invoke(GroupID, NoticeID);
|
||||
if (OnNewGroupNotice != null)
|
||||
{
|
||||
OnNewGroupNotice(GroupID, NoticeID);
|
||||
}
|
||||
|
||||
// Send notice out to everyone that wants notices
|
||||
foreach (GroupMembersData member in m_groupData.GetGroupMembers(remoteAgentIDstr, GroupID))
|
||||
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
|
||||
{
|
||||
GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)InstantMessageDialog.GroupNotice);
|
||||
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 (!m_groupNoticesEnabled)
|
||||
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);
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[xmlGROUPS]: Accepted notice {0} for {1}", noticeID, remoteClient.AgentId);
|
||||
|
||||
if (noticeID == UUID.Zero)
|
||||
return;
|
||||
|
||||
UUID folderID = UUID.Zero;
|
||||
try
|
||||
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID);
|
||||
if (notice != null)
|
||||
{
|
||||
if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
|
||||
folderID = new UUID(im.binaryBucket, 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.DebugFormat("[xmlGROUPS]: GroupNoticeInventoryAccepted failed to decode target folder");
|
||||
return;
|
||||
}
|
||||
|
||||
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID);
|
||||
if (notice == null)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
|
||||
noticeID, remoteClient.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
string tmp;
|
||||
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 = "Could not find group notice attached item";
|
||||
InventoryItemBase itemCopy = scene.GiveInventoryItem(remoteClient.AgentId,
|
||||
giver, notice.noticeData.AttachmentItemID, folderID, out message);
|
||||
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
|
||||
giver, notice.noticeData.AttachmentItemID);
|
||||
|
||||
if (itemCopy == null)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage(message, false);
|
||||
remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
|
||||
return;
|
||||
}
|
||||
|
||||
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
|
||||
}
|
||||
|
||||
else if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined)
|
||||
{
|
||||
if (!m_groupNoticesEnabled)
|
||||
return;
|
||||
|
||||
UUID noticeID = new UUID(im.imSessionID);
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[GROUPS]: Accepted notice {0} for {1}", noticeID, remoteAgentIDstr);
|
||||
|
||||
if (noticeID == UUID.Zero)
|
||||
return;
|
||||
|
||||
UUID remoteAgentID = remoteClient.AgentId;
|
||||
|
||||
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID);
|
||||
if (notice == null)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
|
||||
noticeID, remoteClient.AgentId);
|
||||
return;
|
||||
}
|
||||
string giver = notice.noticeData.AttachmentOwnerID;
|
||||
UUID attachmentUUID = notice.noticeData.AttachmentItemID;
|
||||
|
||||
if (attachmentUUID == null ||
|
||||
attachmentUUID == UUID.Zero ||
|
||||
giver == null ||
|
||||
giver == UUID.Zero.ToString()
|
||||
)
|
||||
return;
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[xmlGroups]: Deny inventory from {0} to {1}", giver, remoteAgentIDstr);
|
||||
|
||||
string message = String.Empty;
|
||||
|
||||
InventoryItemBase itemCopy = scene.InventoryService.GetItem(remoteAgentID, attachmentUUID);
|
||||
if (itemCopy == null)
|
||||
return;
|
||||
|
||||
InventoryFolderBase trash = scene.InventoryService.GetFolderForType(remoteAgentID, FolderType.Trash);
|
||||
if (trash == null)
|
||||
{
|
||||
m_log.DebugFormat("[GROUPS]: failed to find trash folder for {0} ", remoteAgentID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemCopy.Folder == trash.ID || remoteAgentIDstr == notice.noticeData.AttachmentOwnerID)
|
||||
return;
|
||||
|
||||
itemCopy.Folder = trash.ID;
|
||||
scene.InventoryService.MoveItems(itemCopy.Owner, new List<InventoryItemBase>() { itemCopy });
|
||||
|
||||
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
|
||||
else if ((im.dialog == 210))
|
||||
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
|
||||
|
@ -649,16 +525,14 @@ namespace OpenSim.Groups
|
|||
|
||||
UUID ejecteeID = new UUID(im.toAgentID);
|
||||
|
||||
im.imSessionID = UUID.Zero.Guid;
|
||||
im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
|
||||
OutgoingInstantMessage(im, ejecteeID);
|
||||
|
||||
IClientAPI ejectee = GetActiveRootClient(ejecteeID);
|
||||
IClientAPI ejectee = GetActiveClient(ejecteeID);
|
||||
if (ejectee != null)
|
||||
{
|
||||
UUID groupID = new UUID(im.imSessionID);
|
||||
ejectee.SendAgentDropGroup(groupID);
|
||||
SendAgentGroupDataUpdate(ejectee,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -678,7 +552,7 @@ namespace OpenSim.Groups
|
|||
case (byte)InstantMessageDialog.GroupInvitation:
|
||||
case (byte)InstantMessageDialog.GroupNotice:
|
||||
UUID toAgentID = new UUID(msg.toAgentID);
|
||||
IClientAPI localClient = GetActiveRootClient(toAgentID);
|
||||
IClientAPI localClient = GetActiveClient(toAgentID);
|
||||
if (localClient != null)
|
||||
{
|
||||
localClient.SendInstantMessage(msg);
|
||||
|
@ -714,7 +588,7 @@ namespace OpenSim.Groups
|
|||
// 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.
|
||||
SendAgentGroupDataUpdate(remoteClient, true);
|
||||
UpdateAllClientsWithGroupInfo(remoteClient.AgentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -761,6 +635,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID)
|
||||
|
@ -840,12 +715,6 @@ namespace OpenSim.Groups
|
|||
return m_groupData.GetAgentGroupMembership(UUID.Zero.ToString(), agentID.ToString(), groupID);
|
||||
}
|
||||
|
||||
public GroupMembershipData GetActiveMembershipData(UUID agentID)
|
||||
{
|
||||
string agentIDstr = agentID.ToString();
|
||||
return m_groupData.GetAgentActiveMembership(agentIDstr, agentIDstr);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -882,7 +751,7 @@ namespace OpenSim.Groups
|
|||
|
||||
if (avatar != null)
|
||||
{
|
||||
if (avatar.GodController.UserLevel < m_levelGroupCreate)
|
||||
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;
|
||||
|
@ -890,7 +759,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
// check funds
|
||||
// is there a money module present ?
|
||||
// is there is a money module present ?
|
||||
IMoneyModule money = scene.RequestModuleInterface<IMoneyModule>();
|
||||
if (money != null)
|
||||
{
|
||||
|
@ -907,13 +776,13 @@ namespace OpenSim.Groups
|
|||
|
||||
if (groupID != UUID.Zero)
|
||||
{
|
||||
if (money != null && money.GroupCreationCharge > 0)
|
||||
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name);
|
||||
if (money != null)
|
||||
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
|
||||
|
||||
remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully");
|
||||
remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly");
|
||||
|
||||
// Update the founder with new group information.
|
||||
SendAgentGroupDataUpdate(remoteClient, true);
|
||||
SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
else
|
||||
remoteClient.SendCreateGroupReply(groupID, false, reason);
|
||||
|
@ -966,7 +835,7 @@ namespace OpenSim.Groups
|
|||
// the client currently has set active, then we need to do a scene presence update too
|
||||
// if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID)
|
||||
|
||||
SendDataUpdate(remoteClient, true);
|
||||
UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1007,7 +876,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
// TODO: This update really should send out updates for everyone in the role that just got changed.
|
||||
SendDataUpdate(remoteClient, true);
|
||||
SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
|
||||
public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes)
|
||||
|
@ -1033,7 +902,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
// TODO: This update really should send out updates for everyone in the role that just got changed.
|
||||
SendDataUpdate(remoteClient, true);
|
||||
SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
|
||||
public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
|
||||
|
@ -1075,7 +944,6 @@ namespace OpenSim.Groups
|
|||
bucket = new byte[19 + name.Length];
|
||||
bucket[0] = 1; // has attachment?
|
||||
bucket[1] = info.noticeData.AttachmentType; // attachment type
|
||||
info.GroupID.ToBytes(bucket, 2);
|
||||
name.CopyTo(bucket, 18);
|
||||
}
|
||||
else
|
||||
|
@ -1086,6 +954,7 @@ namespace OpenSim.Groups
|
|||
bucket[18] = 0; // null terminated
|
||||
}
|
||||
|
||||
info.GroupID.ToBytes(bucket, 2);
|
||||
msg.binaryBucket = bucket;
|
||||
}
|
||||
else
|
||||
|
@ -1101,37 +970,27 @@ namespace OpenSim.Groups
|
|||
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);
|
||||
|
||||
GroupRecord groupRecord = GetGroupRecord(groupID);
|
||||
IMoneyModule money = remoteClient.Scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
// Should check to see if there's an outstanding invitation
|
||||
|
||||
if (money != null && groupRecord.MembershipFee > 0)
|
||||
{
|
||||
// Does the agent have the funds to cover the group join fee?
|
||||
if (!money.AmountCovered(remoteClient.AgentId, groupRecord.MembershipFee))
|
||||
{
|
||||
remoteClient.SendAlertMessage("Insufficient funds to join the group.");
|
||||
remoteClient.SendJoinGroupReply(groupID, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
if (money != null && groupRecord.MembershipFee > 0)
|
||||
money.ApplyCharge(remoteClient.AgentId, groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName);
|
||||
|
||||
remoteClient.SendJoinGroupReply(groupID, true);
|
||||
|
||||
// Should this send updates to everyone in the group?
|
||||
SendAgentGroupDataUpdate(remoteClient, true);
|
||||
SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
|
||||
|
||||
if (reason != string.Empty)
|
||||
// A warning
|
||||
|
@ -1153,7 +1012,7 @@ namespace OpenSim.Groups
|
|||
|
||||
// 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, true);
|
||||
SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
|
||||
public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID)
|
||||
|
@ -1212,31 +1071,10 @@ namespace OpenSim.Groups
|
|||
return;
|
||||
}
|
||||
|
||||
IClientAPI ejecteeClient = GetActiveRootClient(ejecteeID);
|
||||
|
||||
// Send Message to Ejectee
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
|
||||
// if local send a normal message
|
||||
if(ejecteeClient != null)
|
||||
{
|
||||
msg.imSessionID = UUID.Zero.Guid;
|
||||
msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
|
||||
// also execute and send update
|
||||
ejecteeClient.SendAgentDropGroup(groupID);
|
||||
SendAgentGroupDataUpdate(ejecteeClient,true);
|
||||
}
|
||||
else // send
|
||||
{
|
||||
// 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 presence 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.imSessionID = groupInfo.GroupID.Guid;
|
||||
msg.dialog = (byte)210; //interop
|
||||
}
|
||||
msg.fromAgentID = agentID.Guid;
|
||||
// msg.fromAgentID = info.GroupID;
|
||||
msg.toAgentID = ejecteeID.Guid;
|
||||
|
@ -1244,7 +1082,7 @@ namespace OpenSim.Groups
|
|||
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;
|
||||
|
@ -1254,7 +1092,11 @@ namespace OpenSim.Groups
|
|||
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;
|
||||
|
@ -1270,7 +1112,7 @@ namespace OpenSim.Groups
|
|||
{
|
||||
msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member");
|
||||
}
|
||||
msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
|
||||
msg.dialog = (byte)210; //interop
|
||||
msg.fromGroup = false;
|
||||
msg.offline = (byte)0;
|
||||
msg.ParentEstateID = 0;
|
||||
|
@ -1278,6 +1120,11 @@ namespace OpenSim.Groups
|
|||
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)
|
||||
|
@ -1334,24 +1181,12 @@ namespace OpenSim.Groups
|
|||
|
||||
public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
|
||||
{
|
||||
return m_groupData.FindGroups(remoteClient.AgentId.ToString(), query);
|
||||
return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Client/Update Tools
|
||||
private IClientAPI GetActiveRootClient(UUID agentID)
|
||||
{
|
||||
foreach (Scene scene in m_sceneList)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(agentID);
|
||||
if (sp != null && !sp.IsChildAgent && !sp.IsDeleted)
|
||||
{
|
||||
return sp.ControllingClient;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to find an active IClientAPI reference for agentID giving preference to root connections
|
||||
|
@ -1364,7 +1199,7 @@ namespace OpenSim.Groups
|
|||
foreach (Scene scene in m_sceneList)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(agentID);
|
||||
if (sp != null&& !sp.IsDeleted)
|
||||
if (sp != null)
|
||||
{
|
||||
if (!sp.IsChildAgent)
|
||||
{
|
||||
|
@ -1381,6 +1216,68 @@ namespace OpenSim.Groups
|
|||
return child;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'.
|
||||
/// </summary>
|
||||
private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data)
|
||||
{
|
||||
if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
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<IEventQueue>();
|
||||
|
||||
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);
|
||||
|
@ -1403,33 +1300,46 @@ namespace OpenSim.Groups
|
|||
}
|
||||
}
|
||||
|
||||
public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
|
||||
/// <summary>
|
||||
/// Send updates to all clients who might be interested in groups data for dataForClientID
|
||||
/// </summary>
|
||||
private void UpdateAllClientsWithGroupInfo(UUID dataForClientID)
|
||||
{
|
||||
SendAgentGroupDataUpdate(remoteClient, true);
|
||||
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); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell remoteClient about its agent groups, and optionally send title to others
|
||||
/// Update remoteClient with group information about dataForAgentID
|
||||
/// </summary>
|
||||
private void SendAgentGroupDataUpdate(IClientAPI remoteClient, bool tellOthers)
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
||||
// TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
|
||||
|
||||
UUID agentID = GetRequestingAgentID(remoteClient);
|
||||
OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero);
|
||||
|
||||
SendDataUpdate(remoteClient, tellOthers);
|
||||
// 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, agentID);
|
||||
|
||||
remoteClient.UpdateGroupMembership(membershipArray);
|
||||
remoteClient.SendAgentGroupDataUpdate(agentID, membershipArray);
|
||||
GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
|
||||
SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
|
||||
//remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
|
||||
if (remoteClient.AgentId == dataForAgentID)
|
||||
remoteClient.RefreshGroupMembership();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1481,49 +1391,27 @@ namespace OpenSim.Groups
|
|||
return membershipArray;
|
||||
}
|
||||
|
||||
//tell remoteClient about its agent group info, and optionally send title to others
|
||||
private void SendDataUpdate(IClientAPI remoteClient, bool tellOthers)
|
||||
{
|
||||
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;
|
||||
|
||||
UUID agentID = GetRequestingAgentID(remoteClient);
|
||||
GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID.ToString(), agentID.ToString());
|
||||
if (membership != null)
|
||||
private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
|
||||
{
|
||||
activeGroupID = membership.GroupID;
|
||||
activeGroupTitle = membership.GroupTitle;
|
||||
activeGroupPowers = membership.GroupPowers;
|
||||
activeGroupName = membership.GroupName;
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, agentID);
|
||||
string firstname, lastname;
|
||||
if (account != null)
|
||||
{
|
||||
firstname = account.FirstName;
|
||||
lastname = account.LastName;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstname = "Unknown";
|
||||
lastname = "Unknown";
|
||||
}
|
||||
|
||||
remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname,
|
||||
remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname,
|
||||
lastname, activeGroupPowers, activeGroupName,
|
||||
activeGroupTitle);
|
||||
|
||||
if (tellOthers)
|
||||
SendScenePresenceUpdate(agentID, activeGroupTitle);
|
||||
|
||||
ScenePresence sp = (ScenePresence)remoteClient.SceneAgent;
|
||||
if (sp != null)
|
||||
sp.Grouptitle = activeGroupTitle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -1534,7 +1422,7 @@ namespace OpenSim.Groups
|
|||
{
|
||||
if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
IClientAPI localClient = GetActiveRootClient(msgTo);
|
||||
IClientAPI localClient = GetActiveClient(msgTo);
|
||||
if (localClient != null)
|
||||
{
|
||||
if (m_debugEnabled) m_log.InfoFormat("[Groups]: MsgTo ({0}) is local, delivering directly", localClient.Name);
|
||||
|
@ -1572,4 +1460,5 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace OpenSim.Groups
|
|||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
if (GroupID != UUID.Zero)
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
if (!string.IsNullOrEmpty(GroupName))
|
||||
if (GroupName != null && GroupName != string.Empty)
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
@ -275,7 +275,7 @@ namespace OpenSim.Groups
|
|||
|
||||
//m_log.DebugFormat("[XXX]: reply was {0}", reply);
|
||||
|
||||
if (string.IsNullOrEmpty(reply))
|
||||
if (reply == string.Empty || reply == null)
|
||||
return null;
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -32,7 +32,6 @@ using System.Reflection;
|
|||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
@ -246,9 +245,9 @@ namespace OpenSim.Groups
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
return m_LocalGroupsConnector.FindGroups(RequestingAgentIDstr, search);
|
||||
return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
|
||||
}
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
|
@ -405,7 +404,7 @@ namespace OpenSim.Groups
|
|||
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.";
|
||||
reason = "You don't have have an accessible groups server in your home world. You membership to this group in only within this grid.";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -561,7 +560,7 @@ namespace OpenSim.Groups
|
|||
|
||||
// so we have the list of urls to send the notice to
|
||||
// this may take a long time...
|
||||
WorkManager.RunInThread(delegate
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
foreach (string u in urls)
|
||||
{
|
||||
|
@ -572,7 +571,7 @@ namespace OpenSim.Groups
|
|||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
||||
}
|
||||
}
|
||||
}, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -605,8 +604,14 @@ namespace OpenSim.Groups
|
|||
private string AgentUUI(string AgentIDStr)
|
||||
{
|
||||
UUID AgentID = UUID.Zero;
|
||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
||||
return UUID.Zero.ToString();
|
||||
try
|
||||
{
|
||||
AgentID = new UUID(AgentIDStr);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return AgentID.ToString();
|
||||
}
|
||||
|
||||
if (m_UserManagement.IsLocalGridUser(AgentID))
|
||||
return AgentID.ToString();
|
||||
|
@ -618,20 +623,23 @@ namespace OpenSim.Groups
|
|||
if (agent != null)
|
||||
break;
|
||||
}
|
||||
if (agent != null)
|
||||
if (agent == null) // oops
|
||||
return AgentID.ToString();
|
||||
|
||||
return Util.ProduceUserUniversalIdentifier(agent);
|
||||
|
||||
// we don't know anything about this foreign user
|
||||
// try asking the user management module, which may know more
|
||||
return m_UserManagement.GetUserUUI(AgentID);
|
||||
|
||||
}
|
||||
|
||||
private string AgentUUIForOutside(string AgentIDStr)
|
||||
{
|
||||
UUID AgentID = UUID.Zero;
|
||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
||||
return UUID.Zero.ToString();
|
||||
try
|
||||
{
|
||||
AgentID = new UUID(AgentIDStr);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return AgentID.ToString();
|
||||
}
|
||||
|
||||
AgentCircuitData agent = null;
|
||||
foreach (Scene scene in m_Scenes)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -115,10 +115,9 @@ namespace OpenSim.Groups
|
|||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
string body;
|
||||
using(StreamReader sr = new StreamReader(requestData))
|
||||
body = sr.ReadToEnd();
|
||||
|
||||
StreamReader sr = new StreamReader(requestData);
|
||||
string body = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
body = body.Trim();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||
|
@ -159,7 +158,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
|
@ -210,13 +209,11 @@ namespace OpenSim.Groups
|
|||
string agentID = request["AgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
|
||||
NullResult(result, "Internal error");
|
||||
else
|
||||
result["RESULT"] = "true";
|
||||
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Groups
|
|||
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
|
||||
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
|
||||
List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search);
|
||||
List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search);
|
||||
List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID);
|
||||
|
||||
bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);
|
||||
|
|
|
@ -34,7 +34,6 @@ using System.Text;
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
|
@ -173,9 +172,9 @@ namespace OpenSim.Groups
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
||||
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||
}
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
|
|
|
@ -30,7 +30,7 @@ using Mono.Addins;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: Addin("OpenSim.Groups", "0.1")]
|
||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
|
|
|
@ -32,12 +32,10 @@ using System.Reflection;
|
|||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Base;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
|
@ -46,33 +44,15 @@ namespace OpenSim.Groups
|
|||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI;
|
||||
private IServiceAuth m_Auth;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public GroupsServiceRemoteConnector(IConfigSource config)
|
||||
public GroupsServiceRemoteConnector(string url)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
||||
|
||||
m_ServerURI = url;
|
||||
if (!m_ServerURI.EndsWith("/"))
|
||||
m_ServerURI += "/";
|
||||
|
||||
/// This is from BaseServiceConnector
|
||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case "BasicHttpAuthentication":
|
||||
m_Auth = new BasicHttpAuthentication(config, "Groups");
|
||||
break;
|
||||
}
|
||||
///
|
||||
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
|
@ -126,7 +106,7 @@ namespace OpenSim.Groups
|
|||
sendData["OP"] = "UPDATE";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
|
@ -140,20 +120,20 @@ namespace OpenSim.Groups
|
|||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
if (GroupID != UUID.Zero)
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
if (!string.IsNullOrEmpty(GroupName))
|
||||
if (GroupName != null && GroupName != string.Empty)
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string query)
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
|
||||
{
|
||||
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
|
||||
if (string.IsNullOrEmpty(query))
|
||||
|
@ -161,7 +141,7 @@ namespace OpenSim.Groups
|
|||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["Query"] = query;
|
||||
sendData["RequestingAgentID"] = RequestingAgentIDstr;
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
|
||||
|
||||
|
@ -287,7 +267,6 @@ namespace OpenSim.Groups
|
|||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return members;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
||||
|
@ -378,7 +357,6 @@ namespace OpenSim.Groups
|
|||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return roles;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
||||
|
@ -679,8 +657,7 @@ namespace OpenSim.Groups
|
|||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "groups",
|
||||
ServerUtils.BuildQueryString(sendData),
|
||||
m_Auth);
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
if (reply == string.Empty)
|
||||
return null;
|
||||
|
@ -690,7 +667,7 @@ namespace OpenSim.Groups
|
|||
|
||||
return replyData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
|||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
|
@ -73,7 +72,12 @@ namespace OpenSim.Groups
|
|||
|
||||
private void Init(IConfigSource config)
|
||||
{
|
||||
m_GroupsService = new GroupsServiceRemoteConnector(config);
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
||||
|
||||
m_GroupsService = new GroupsServiceRemoteConnector(url);
|
||||
m_Scenes = new List<Scene>();
|
||||
|
||||
}
|
||||
|
@ -192,10 +196,10 @@ namespace OpenSim.Groups
|
|||
});
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
// TODO!
|
||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
||||
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||
}
|
||||
|
||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||
|
|
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
|||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
@ -53,26 +52,14 @@ namespace OpenSim.Groups
|
|||
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
string key = string.Empty;
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||
|
||||
IConfig groupsConfig = config.Configs[m_ConfigName];
|
||||
if (groupsConfig != null)
|
||||
{
|
||||
key = groupsConfig.GetString("SecretKey", string.Empty);
|
||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
|
||||
}
|
||||
// else
|
||||
// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
|
||||
|
||||
m_GroupsService = new GroupsService(config);
|
||||
|
||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
||||
|
||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
|
||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,8 +69,8 @@ namespace OpenSim.Groups
|
|||
|
||||
private GroupsService m_GroupsService;
|
||||
|
||||
public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
|
||||
base("POST", "/groups", auth)
|
||||
public GroupsServicePostHandler(GroupsService service) :
|
||||
base("POST", "/groups")
|
||||
{
|
||||
m_GroupsService = service;
|
||||
}
|
||||
|
@ -91,10 +78,9 @@ namespace OpenSim.Groups
|
|||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
string body;
|
||||
using(StreamReader sr = new StreamReader(requestData))
|
||||
body = sr.ReadToEnd();
|
||||
|
||||
StreamReader sr = new StreamReader(requestData);
|
||||
string body = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
body = body.Trim();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||
|
@ -110,7 +96,7 @@ namespace OpenSim.Groups
|
|||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
// m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||
m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||
switch (method)
|
||||
{
|
||||
case "PUTGROUP":
|
||||
|
@ -154,7 +140,7 @@ namespace OpenSim.Groups
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
|
||||
m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
|
@ -286,13 +272,11 @@ namespace OpenSim.Groups
|
|||
string agentID = request["AgentID"].ToString();
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
|
||||
NullResult(result, string.Format("Insufficient permissions. {0}", agentID));
|
||||
else
|
||||
result["RESULT"] = "true";
|
||||
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
|
@ -668,11 +652,7 @@ namespace OpenSim.Groups
|
|||
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||
new UUID(request["InviteID"].ToString()));
|
||||
|
||||
if (invite != null)
|
||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
||||
else
|
||||
result["RESULT"] = "NULL";
|
||||
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
|
@ -804,14 +784,6 @@ namespace OpenSim.Groups
|
|||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
private byte[] FailureResult(string reason)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
NullResult(result, reason);
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ using System.Reflection;
|
|||
using System.Threading;
|
||||
|
||||
using OpenSim.Framework;
|
||||
//using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
|
@ -144,8 +143,6 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
//group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
||||
group = d();
|
||||
|
@ -153,12 +150,8 @@ namespace OpenSim.Groups
|
|||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
|
||||
return (ExtendedGroupRecord)group;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupRecord)group;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -249,20 +242,14 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
membership = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -298,19 +285,13 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
membership = d();
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -345,19 +326,13 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
memberships = d();
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
|
||||
return (List<GroupMembershipData>)memberships;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupMembershipData>)memberships;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -393,8 +368,6 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ExtendedGroupMembersData> _members = d();
|
||||
|
||||
|
@ -407,15 +380,11 @@ namespace OpenSim.Groups
|
|||
{
|
||||
//m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
|
||||
m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
|
||||
return (List<GroupMembersData>)members;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
@ -527,8 +496,6 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
roles = d();
|
||||
if (roles != null)
|
||||
|
@ -536,15 +503,11 @@ namespace OpenSim.Groups
|
|||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupRolesData>)roles;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
@ -577,8 +540,6 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> _rmembers = d();
|
||||
|
||||
|
@ -595,12 +556,8 @@ namespace OpenSim.Groups
|
|||
// Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
|
||||
// I don't get it.
|
||||
m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
|
||||
return (List<GroupRoleMembersData>)rmembers;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupRoleMembersData>)rmembers;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -708,8 +665,6 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
roles = d();
|
||||
lock (m_Cache)
|
||||
|
@ -719,11 +674,6 @@ namespace OpenSim.Groups
|
|||
return (List<GroupRolesData>)roles;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
@ -816,20 +766,14 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
GroupNoticeInfo _notice = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
|
||||
return _notice;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return _notice;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -864,25 +808,21 @@ namespace OpenSim.Groups
|
|||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
try
|
||||
{
|
||||
notices = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
|
||||
return (List<ExtendedGroupNoticeData>)notices;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<ExtendedGroupNoticeData>)notices;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -43,8 +43,7 @@ namespace OpenSim.Groups
|
|||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public const GroupPowers DefaultEveryonePowers =
|
||||
GroupPowers.AllowSetHome |
|
||||
public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
|
||||
GroupPowers.Accountable |
|
||||
GroupPowers.JoinChat |
|
||||
GroupPowers.AllowVoiceChat |
|
||||
|
@ -52,23 +51,30 @@ namespace OpenSim.Groups
|
|||
GroupPowers.StartProposal |
|
||||
GroupPowers.VoteOnProposal;
|
||||
|
||||
public const GroupPowers OfficersPowers = DefaultEveryonePowers |
|
||||
public const GroupPowers OwnerPowers = GroupPowers.Accountable |
|
||||
GroupPowers.AllowEditLand |
|
||||
GroupPowers.AllowFly |
|
||||
GroupPowers.AllowLandmark |
|
||||
GroupPowers.AllowRez |
|
||||
GroupPowers.AllowSetHome |
|
||||
GroupPowers.AllowVoiceChat |
|
||||
GroupPowers.AssignMember |
|
||||
GroupPowers.AssignMemberLimited |
|
||||
GroupPowers.ChangeActions |
|
||||
GroupPowers.ChangeIdentity |
|
||||
GroupPowers.ChangeMedia |
|
||||
GroupPowers.ChangeOptions |
|
||||
GroupPowers.CreateRole |
|
||||
GroupPowers.DeedObject |
|
||||
GroupPowers.DeleteRole |
|
||||
GroupPowers.Eject |
|
||||
GroupPowers.FindPlaces |
|
||||
GroupPowers.Invite |
|
||||
GroupPowers.JoinChat |
|
||||
GroupPowers.LandChangeIdentity |
|
||||
GroupPowers.LandDeed |
|
||||
GroupPowers.LandDivideJoin |
|
||||
GroupPowers.LandEdit |
|
||||
GroupPowers.AllowEnvironment |
|
||||
GroupPowers.LandEjectAndFreeze |
|
||||
GroupPowers.LandGardening |
|
||||
GroupPowers.LandManageAllowed |
|
||||
|
@ -77,29 +83,19 @@ namespace OpenSim.Groups
|
|||
GroupPowers.LandOptions |
|
||||
GroupPowers.LandRelease |
|
||||
GroupPowers.LandSetSale |
|
||||
GroupPowers.MemberVisible |
|
||||
GroupPowers.ModerateChat |
|
||||
GroupPowers.ObjectManipulate |
|
||||
GroupPowers.ObjectSetForSale |
|
||||
GroupPowers.ReceiveNotices |
|
||||
GroupPowers.RemoveMember |
|
||||
GroupPowers.ReturnGroupOwned |
|
||||
GroupPowers.ReturnGroupSet |
|
||||
GroupPowers.ReturnNonGroup |
|
||||
GroupPowers.RoleProperties |
|
||||
GroupPowers.SendNotices |
|
||||
GroupPowers.SetLandingPoint;
|
||||
|
||||
public const GroupPowers OwnerPowers = OfficersPowers |
|
||||
GroupPowers.Accountable |
|
||||
GroupPowers.AllowEditLand |
|
||||
GroupPowers.AssignMember |
|
||||
GroupPowers.ChangeActions |
|
||||
GroupPowers.CreateRole |
|
||||
GroupPowers.DeleteRole |
|
||||
GroupPowers.ExperienceAdmin |
|
||||
GroupPowers.ExperienceCreator |
|
||||
GroupPowers.GroupBanAccess |
|
||||
GroupPowers.HostEvent |
|
||||
GroupPowers.RemoveMember;
|
||||
GroupPowers.SetLandingPoint |
|
||||
GroupPowers.StartProposal |
|
||||
GroupPowers.VoteOnProposal;
|
||||
|
||||
#region Daily Cleanup
|
||||
|
||||
|
@ -154,25 +150,20 @@ namespace OpenSim.Groups
|
|||
data.Data["ShowInList"] = showInList ? "1" : "0";
|
||||
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
||||
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
||||
UUID ownerRoleID = UUID.Random();
|
||||
data.Data["OwnerRoleID"] = ownerRoleID.ToString();
|
||||
data.Data["OwnerRoleID"] = UUID.Random().ToString();
|
||||
|
||||
if (!m_Database.StoreGroup(data))
|
||||
return UUID.Zero;
|
||||
|
||||
// Create Everyone role
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group is in the everyone role.", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
||||
|
||||
// Create Officers role
|
||||
UUID officersRoleID = UUID.Random();
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, officersRoleID, "Officers", "The officers of the group, with more powers than regular members.", "Officer of " + name, (ulong)OfficersPowers, true);
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
||||
|
||||
// Create Owner role
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, ownerRoleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
||||
UUID roleID = UUID.Random();
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
||||
|
||||
// Add founder to group
|
||||
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, ownerRoleID);
|
||||
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, officersRoleID);
|
||||
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
|
||||
|
||||
return data.GroupID;
|
||||
}
|
||||
|
@ -231,22 +222,15 @@ namespace OpenSim.Groups
|
|||
if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
|
||||
continue;
|
||||
|
||||
int nmembers = m_Database.MemberCount(d.GroupID);
|
||||
if(nmembers == 0)
|
||||
continue;
|
||||
|
||||
DirGroupsReplyData g = new DirGroupsReplyData();
|
||||
g.groupID = d.GroupID;
|
||||
|
||||
if (d.Data.ContainsKey("Name"))
|
||||
g.groupName = d.Data["Name"];
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: Key Name not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
g.groupID = d.GroupID;
|
||||
g.members = nmembers;
|
||||
g.members = m_Database.MemberCount(d.GroupID);
|
||||
|
||||
groups.Add(g);
|
||||
}
|
||||
|
@ -263,9 +247,6 @@ namespace OpenSim.Groups
|
|||
if (group == null)
|
||||
return members;
|
||||
|
||||
// Unfortunately this doesn't quite work on legacy group data because of a bug
|
||||
// that's also being fixed here on CreateGroup. The OwnerRoleID sent to the DB was wrong.
|
||||
// See how to find the ownerRoleID a few lines below.
|
||||
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
|
||||
|
||||
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
|
||||
|
@ -274,11 +255,6 @@ namespace OpenSim.Groups
|
|||
return members;
|
||||
List<RoleData> rolesList = new List<RoleData>(roles);
|
||||
|
||||
// Let's find the "real" ownerRoleID
|
||||
RoleData ownerRole = rolesList.Find(r => r.Data["Powers"] == ((long)OwnerPowers).ToString());
|
||||
if (ownerRole != null)
|
||||
ownerRoleID = ownerRole.RoleID;
|
||||
|
||||
// Check visibility?
|
||||
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
||||
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
|
||||
|
@ -315,33 +291,18 @@ namespace OpenSim.Groups
|
|||
{
|
||||
m.Title = selected.Data["Title"];
|
||||
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
|
||||
}
|
||||
|
||||
m.AgentID = d.PrincipalID;
|
||||
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
||||
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
||||
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
||||
|
||||
GridUserData gud = m_GridUserService.Get(d.PrincipalID);
|
||||
if (gud != null)
|
||||
{
|
||||
if (bool.Parse(gud.Data["Online"]))
|
||||
{
|
||||
m.OnlineStatus = @"Online";
|
||||
}
|
||||
else
|
||||
{
|
||||
int unixtime = int.Parse(gud.Data["Login"]);
|
||||
// The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates!
|
||||
m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
|
||||
}
|
||||
}
|
||||
|
||||
// Is this person an owner of the group?
|
||||
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
||||
|
||||
members.Add(m);
|
||||
}
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
@ -432,15 +393,13 @@ namespace OpenSim.Groups
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
// check perms
|
||||
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
|
||||
return false;
|
||||
return;
|
||||
|
||||
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
|
@ -500,8 +459,8 @@ namespace OpenSim.Groups
|
|||
|
||||
// check permissions
|
||||
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
||||
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
||||
if (!limited && !unlimited)
|
||||
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
|
||||
if (!limited || !unlimited)
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
||||
return false;
|
||||
|
@ -511,7 +470,7 @@ namespace OpenSim.Groups
|
|||
if (!unlimited && limited)
|
||||
{
|
||||
// check whether person's has this role
|
||||
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
|
||||
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
||||
if (rolemembership == null)
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
||||
|
@ -531,26 +490,13 @@ namespace OpenSim.Groups
|
|||
return false;
|
||||
|
||||
// check permissions
|
||||
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
||||
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
||||
if (!limited && !unlimited)
|
||||
if (!unlimited)
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
||||
return false;
|
||||
}
|
||||
|
||||
// AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
|
||||
if (!unlimited && limited)
|
||||
{
|
||||
// check whether person's has this role
|
||||
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
|
||||
if (rolemembership == null)
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
||||
|
||||
if (rolemember == null)
|
||||
|
@ -840,7 +786,7 @@ namespace OpenSim.Groups
|
|||
if (RoleID != UUID.Zero)
|
||||
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
|
||||
// Make this the active group
|
||||
// Make thit this active group
|
||||
PrincipalData pdata = new PrincipalData();
|
||||
pdata.PrincipalID = AgentID;
|
||||
pdata.ActiveGroupID = GroupID;
|
||||
|
@ -858,7 +804,7 @@ namespace OpenSim.Groups
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!add && data == null) // it doesn't exist, can't update
|
||||
if (!add && data == null) // it deosn't exist, can't update
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
|
||||
return false;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -38,7 +38,6 @@ namespace OpenSim.Groups
|
|||
public class GroupsServiceBase : ServiceBase
|
||||
{
|
||||
protected IGroupsData m_Database = null;
|
||||
protected IGridUserData m_GridUserService = null;
|
||||
|
||||
public GroupsServiceBase(IConfigSource config, string cName)
|
||||
: base(config)
|
||||
|
@ -46,7 +45,6 @@ namespace OpenSim.Groups
|
|||
string dllName = String.Empty;
|
||||
string connString = String.Empty;
|
||||
string realm = "os_groups";
|
||||
string usersRealm = "GridUser";
|
||||
string configName = (cName == string.Empty) ? "Groups" : cName;
|
||||
|
||||
//
|
||||
|
@ -81,21 +79,6 @@ namespace OpenSim.Groups
|
|||
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
|
||||
if (m_Database == null)
|
||||
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
||||
|
||||
//
|
||||
// [GridUserService] section overrides [DatabaseService], if it exists
|
||||
//
|
||||
IConfig usersConfig = config.Configs["GridUserService"];
|
||||
if (usersConfig != null)
|
||||
{
|
||||
dllName = usersConfig.GetString("StorageProvider", dllName);
|
||||
connString = usersConfig.GetString("ConnectionString", connString);
|
||||
usersRealm = usersConfig.GetString("Realm", usersRealm);
|
||||
}
|
||||
|
||||
m_GridUserService = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, usersRealm });
|
||||
if (m_GridUserService == null)
|
||||
throw new Exception("Could not find a storage inferface for the given users module " + dllName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -131,27 +131,19 @@ namespace OpenSim.Groups
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||
{
|
||||
// check the token
|
||||
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
||||
if (membership != null)
|
||||
{
|
||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
||||
{
|
||||
return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
}
|
||||
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.OfflineIM
|
|||
if (serviceLocation == string.Empty)
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
else
|
||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
|
||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
|
||||
|
||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
||||
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
||||
|
@ -114,6 +114,7 @@ namespace OpenSim.OfflineIM
|
|||
scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
||||
client.OnMuteListRequest -= OnMuteListRequest;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,6 +162,7 @@ namespace OpenSim.OfflineIM
|
|||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
||||
client.OnMuteListRequest += OnMuteListRequest;
|
||||
}
|
||||
|
||||
private void RetrieveInstantMessages(IClientAPI client)
|
||||
|
@ -192,6 +194,20 @@ namespace OpenSim.OfflineIM
|
|||
}
|
||||
}
|
||||
|
||||
// Apparently this is needed in order for the viewer to request the IMs.
|
||||
private void OnMuteListRequest(IClientAPI client, uint crc)
|
||||
{
|
||||
m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
|
||||
string filename = "mutes" + client.AgentId.ToString();
|
||||
|
||||
IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
|
||||
if (xfer != null)
|
||||
{
|
||||
xfer.AddNewFile(filename, new Byte[0]);
|
||||
client.SendMuteListUpdate(filename);
|
||||
}
|
||||
}
|
||||
|
||||
private void UndeliveredMessage(GridInstantMessage im)
|
||||
{
|
||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||
|
@ -210,6 +226,10 @@ namespace OpenSim.OfflineIM
|
|||
return;
|
||||
}
|
||||
|
||||
Scene scene = FindScene(new UUID(im.fromAgentID));
|
||||
if (scene == null)
|
||||
scene = m_SceneList[0];
|
||||
|
||||
string reason = string.Empty;
|
||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||
|
||||
|
@ -241,11 +261,6 @@ namespace OpenSim.OfflineIM
|
|||
return m_OfflineIMService.StoreMessage(im, out reason);
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
m_OfflineIMService.DeleteMessages(userID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ using Mono.Addins;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: Addin("OpenSim.OfflineIM", "0.1")]
|
||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
|
|
|
@ -32,7 +32,6 @@ using System.Reflection;
|
|||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
|
@ -47,7 +46,6 @@ namespace OpenSim.OfflineIM
|
|||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI = string.Empty;
|
||||
private IServiceAuth m_Auth;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public OfflineIMServiceRemoteConnector(string url)
|
||||
|
@ -67,18 +65,6 @@ namespace OpenSim.OfflineIM
|
|||
|
||||
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||
|
||||
/// This is from BaseServiceConnector
|
||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Messaging" }, "None");
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case "BasicHttpAuthentication":
|
||||
m_Auth = new BasicHttpAuthentication(config, "Messaging");
|
||||
break;
|
||||
}
|
||||
///
|
||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
|
||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||
}
|
||||
|
||||
#region IOfflineIMService
|
||||
|
@ -96,13 +82,8 @@ namespace OpenSim.OfflineIM
|
|||
if (!ret.ContainsKey("RESULT"))
|
||||
return ims;
|
||||
|
||||
string result = ret["RESULT"].ToString();
|
||||
if (result == "NULL" || result.ToLower() == "false")
|
||||
{
|
||||
string reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: GetMessages for {0} failed: {1}", principalID, reason);
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return ims;
|
||||
}
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
|
@ -129,21 +110,13 @@ namespace OpenSim.OfflineIM
|
|||
string result = ret["RESULT"].ToString();
|
||||
if (result == "NULL" || result.ToLower() == "false")
|
||||
{
|
||||
reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
||||
reason = ret["REASON"].ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["UserID"] = userID;
|
||||
|
||||
MakeRequest("DELETE", sendData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
@ -157,8 +130,7 @@ namespace OpenSim.OfflineIM
|
|||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/offlineim",
|
||||
ServerUtils.BuildQueryString(sendData),
|
||||
m_Auth);
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
reply);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
|||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
@ -60,9 +59,7 @@ namespace OpenSim.OfflineIM
|
|||
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
|
||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
||||
|
||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
|
||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,8 +69,8 @@ namespace OpenSim.OfflineIM
|
|||
|
||||
private IOfflineIMService m_OfflineIMService;
|
||||
|
||||
public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
|
||||
base("POST", "/offlineim", auth)
|
||||
public OfflineIMServicePostHandler(IOfflineIMService service) :
|
||||
base("POST", "/offlineim")
|
||||
{
|
||||
m_OfflineIMService = service;
|
||||
}
|
||||
|
@ -99,20 +96,19 @@ namespace OpenSim.OfflineIM
|
|||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
m_log.DebugFormat("[OfflineIM.V2.Handler]: {0}", method);
|
||||
switch (method)
|
||||
{
|
||||
case "GET":
|
||||
return HandleGet(request);
|
||||
case "STORE":
|
||||
return HandleStore(request);
|
||||
case "DELETE":
|
||||
return HandleDelete(request);
|
||||
}
|
||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[OFFLINE IM HANDLER]: Exception {0} ", e.Message), e);
|
||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
|
@ -163,21 +159,6 @@ namespace OpenSim.OfflineIM
|
|||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleDelete(Dictionary<string, object> request)
|
||||
{
|
||||
if (!request.ContainsKey("UserID"))
|
||||
{
|
||||
return FailureResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
UUID userID = new UUID(request["UserID"].ToString());
|
||||
m_OfflineIMService.DeleteMessages(userID);
|
||||
|
||||
return SuccessResult();
|
||||
}
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void NullResult(Dictionary<string, object> result, string reason)
|
||||
|
@ -215,7 +196,18 @@ namespace OpenSim.OfflineIM
|
|||
|
||||
rootElement.AppendChild(result);
|
||||
|
||||
return Util.DocToBytes(doc);
|
||||
return DocToBytes(doc);
|
||||
}
|
||||
|
||||
private byte[] DocToBytes(XmlDocument doc)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||
xw.Formatting = Formatting.Indented;
|
||||
doc.WriteTo(xw);
|
||||
xw.Flush();
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -91,7 +91,7 @@ namespace OpenSim.OfflineIM
|
|||
{
|
||||
reason = string.Empty;
|
||||
|
||||
// Check limits
|
||||
// TODO Check limits
|
||||
UUID principalID = new UUID(im.toAgentID);
|
||||
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
||||
if (count >= MAX_IM)
|
||||
|
@ -100,35 +100,32 @@ namespace OpenSim.OfflineIM
|
|||
return false;
|
||||
}
|
||||
|
||||
string imXml;
|
||||
string imXml = string.Empty;
|
||||
using (MemoryStream mstream = new MemoryStream())
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Util.UTF8NoBomEncoding;
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
||||
{
|
||||
m_serializer.Serialize(writer, im);
|
||||
writer.Flush();
|
||||
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
||||
|
||||
mstream.Position = 0;
|
||||
using (StreamReader sreader = new StreamReader(mstream))
|
||||
{
|
||||
imXml = sreader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OfflineIMData data = new OfflineIMData();
|
||||
data.PrincipalID = principalID;
|
||||
data.FromID = new UUID(im.fromAgentID);
|
||||
data.Data = new Dictionary<string, string>();
|
||||
data.Data["Message"] = imXml;
|
||||
|
||||
return m_Database.Store(data);
|
||||
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
m_Database.Delete("PrincipalID", userID.ToString());
|
||||
m_Database.Delete("FromID", userID.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,17 +32,16 @@ using System.Threading;
|
|||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.RegionLoader.Filesystem;
|
||||
using OpenSim.Framework.RegionLoader.Web;
|
||||
using OpenSim.Region.CoreModules.Agent.AssetTransaction;
|
||||
using OpenSim.Region.CoreModules.Avatar.InstantMessage;
|
||||
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
||||
using OpenSim.Region.CoreModules.Scripting.LoadImageURL;
|
||||
using OpenSim.Region.CoreModules.Scripting.XMLRPC;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
{
|
||||
[Extension(Path="/OpenSim/Startup", Id="LoadRegions", NodeName="Plugin")]
|
||||
public class LoadRegionsPlugin : IApplicationPlugin, IRegionCreator
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
@ -131,7 +130,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
|||
createdScenes.Add(scene);
|
||||
|
||||
if (changed)
|
||||
m_openSim.EstateDataService.StoreEstateSettings(regionsToLoad[i].EstateSettings);
|
||||
regionsToLoad[i].EstateSettings.Save();
|
||||
}
|
||||
|
||||
foreach (IScene scene in createdScenes)
|
||||
|
|
|
@ -27,17 +27,16 @@
|
|||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Addins;
|
||||
|
||||
// General information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly : AssemblyTitle("OpenSim.ApplicationPlugins.LoadRegions")]
|
||||
[assembly : AssemblyTitle("OpenSim.Addin")]
|
||||
[assembly : AssemblyDescription("")]
|
||||
[assembly : AssemblyConfiguration("")]
|
||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly : AssemblyProduct("OpenSim")]
|
||||
[assembly : AssemblyProduct("OpenSim.Addin")]
|
||||
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2009")]
|
||||
[assembly : AssemblyTrademark("")]
|
||||
[assembly : AssemblyCulture("")]
|
||||
|
@ -61,8 +60,6 @@ using Mono.Addins;
|
|||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
|
||||
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly : AssemblyVersion("0.7.6.*")]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<Addin id="OpenSim.ApplicationPlugins.LoadRegions" version="0.1">
|
||||
<Runtime>
|
||||
<Import assembly="OpenSim.ApplicationPlugins.LoadRegions.dll"/>
|
||||
</Runtime>
|
||||
<Dependencies>
|
||||
<Addin id="OpenSim" version="0.5" />
|
||||
</Dependencies>
|
||||
<Extension path = "/OpenSim/Startup">
|
||||
<Plugin id="LoadRegions" type="OpenSim.ApplicationPlugins.LoadRegions.LoadRegionsPlugin" />
|
||||
</Extension>
|
||||
</Addin>
|
|
@ -1,7 +1,6 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Addins;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
|
@ -30,7 +29,5 @@ using Mono.Addins;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||
|
|
|
@ -32,13 +32,11 @@ using log4net;
|
|||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenSim;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
{
|
||||
[Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
|
||||
public class RegionModulesControllerPlugin : IRegionModulesController,
|
||||
IApplicationPlugin
|
||||
{
|
||||
|
@ -47,12 +45,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether we load modules from Mono.Addins.
|
||||
/// </summary>
|
||||
/// <remarks>For debug purposes. Defaults to true.</remarks>
|
||||
public bool LoadModulesFromAddins { get; set; }
|
||||
|
||||
// Config access
|
||||
private OpenSimBase m_openSim;
|
||||
|
||||
|
@ -69,11 +61,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
private List<ISharedRegionModule> m_sharedInstances =
|
||||
new List<ISharedRegionModule>();
|
||||
|
||||
public RegionModulesControllerPlugin()
|
||||
{
|
||||
LoadModulesFromAddins = true;
|
||||
}
|
||||
|
||||
#region IApplicationPlugin implementation
|
||||
|
||||
public void Initialise (OpenSimBase openSim)
|
||||
|
@ -82,9 +69,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
|
||||
m_log.DebugFormat("[REGIONMODULES]: Initializing...");
|
||||
|
||||
if (!LoadModulesFromAddins)
|
||||
return;
|
||||
|
||||
// Who we are
|
||||
string id = AddinManager.CurrentAddin.Id;
|
||||
|
||||
|
@ -104,8 +88,40 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
|
||||
|
||||
// Scan modules and load all that aren't disabled
|
||||
foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
||||
AddNode(node, modulesConfig, loadedModules);
|
||||
foreach (TypeExtensionNode node in
|
||||
AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
||||
{
|
||||
IList<int> loadedModuleData;
|
||||
|
||||
if (!loadedModules.ContainsKey(node.Addin))
|
||||
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
||||
|
||||
loadedModuleData = loadedModules[node.Addin];
|
||||
|
||||
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_sharedModules.Add(node);
|
||||
loadedModuleData[0]++;
|
||||
}
|
||||
}
|
||||
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_nonSharedModules.Add(node);
|
||||
loadedModuleData[1]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
||||
loadedModuleData[2]++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
||||
{
|
||||
|
@ -131,9 +147,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
// Read the config again
|
||||
string moduleString =
|
||||
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
||||
// Test to see if we want this module
|
||||
if (moduleString == "disabled")
|
||||
continue;
|
||||
|
||||
// Get the port number, if there is one
|
||||
if (moduleString != String.Empty)
|
||||
|
@ -181,41 +194,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
|
||||
#region IPlugin implementation
|
||||
|
||||
private void AddNode(
|
||||
TypeExtensionNode node, IConfig modulesConfig, Dictionary<RuntimeAddin, IList<int>> loadedModules)
|
||||
{
|
||||
IList<int> loadedModuleData;
|
||||
|
||||
if (!loadedModules.ContainsKey(node.Addin))
|
||||
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
||||
|
||||
loadedModuleData = loadedModules[node.Addin];
|
||||
|
||||
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_sharedModules.Add(node);
|
||||
loadedModuleData[0]++;
|
||||
}
|
||||
}
|
||||
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_nonSharedModules.Add(node);
|
||||
loadedModuleData[1]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
||||
loadedModuleData[2]++;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't do that here
|
||||
//
|
||||
public void Initialise ()
|
||||
|
@ -237,7 +215,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
m_sharedInstances[0].Close();
|
||||
m_sharedInstances.RemoveAt(0);
|
||||
}
|
||||
|
||||
m_sharedModules.Clear();
|
||||
m_nonSharedModules.Clear();
|
||||
}
|
||||
|
@ -368,10 +345,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
string moduleString =
|
||||
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
||||
|
||||
// We may not want to load this at all
|
||||
if (moduleString == "disabled")
|
||||
continue;
|
||||
|
||||
// Get the port number, if there is one
|
||||
if (moduleString != String.Empty)
|
||||
{
|
||||
|
@ -509,8 +482,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|||
{
|
||||
module.RegionLoaded(scene);
|
||||
}
|
||||
|
||||
scene.AllModulesLoaded();
|
||||
}
|
||||
|
||||
public void RemoveRegionFromModules (Scene scene)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<Addin id="OpenSim.ApplicationPlugins.RegionModulesController" version="0.1">
|
||||
<Runtime>
|
||||
<Import assembly="OpenSim.ApplicationPlugins.RegionModulesController.dll"/>
|
||||
</Runtime>
|
||||
|
||||
<Dependencies>
|
||||
<Addin id="OpenSim" version="0.5" />
|
||||
</Dependencies>
|
||||
|
||||
<Extension path = "/OpenSim/Startup">
|
||||
<Plugin id="RegionModulesController" type="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin" />
|
||||
</Extension>
|
||||
</Addin>
|
|
@ -1,7 +1,6 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Addins;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
|
@ -30,7 +29,5 @@ using Mono.Addins;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
|
||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Net;
|
||||
|
@ -39,9 +38,9 @@ using log4net;
|
|||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
using OpenSim;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
@ -52,11 +51,9 @@ using OpenSim.Services.Interfaces;
|
|||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using PermissionMask = OpenSim.Framework.PermissionMask;
|
||||
using RegionInfo = OpenSim.Framework.RegionInfo;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
{
|
||||
[Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
|
||||
public class RemoteAdminPlugin : IApplicationPlugin
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
@ -74,7 +71,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
private string m_name = "RemoteAdminPlugin";
|
||||
private string m_version = "0.0";
|
||||
private string m_openSimVersion;
|
||||
|
||||
public string Version
|
||||
{
|
||||
|
@ -94,8 +90,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
public void Initialise(OpenSimBase openSim)
|
||||
{
|
||||
m_openSimVersion = openSim.GetVersionText();
|
||||
|
||||
m_configSource = openSim.ConfigSource.Source;
|
||||
try
|
||||
{
|
||||
|
@ -138,13 +132,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
|
||||
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
|
||||
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
|
||||
availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
|
||||
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
|
||||
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
|
||||
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
|
||||
|
||||
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
|
||||
|
||||
// Agent management
|
||||
availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
|
||||
availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
|
||||
|
@ -154,7 +145,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
availableMethods["admin_create_user_email"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod);
|
||||
availableMethods["admin_exists_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUserExistsMethod);
|
||||
availableMethods["admin_update_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUpdateUserAccountMethod);
|
||||
availableMethods["admin_authenticate_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAuthenticateUserMethod);
|
||||
|
||||
// Region state management
|
||||
availableMethods["admin_load_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadXMLMethod);
|
||||
|
@ -169,12 +159,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
||||
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
||||
|
||||
// Misc
|
||||
availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
|
||||
availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
|
||||
availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
|
||||
availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
|
||||
|
||||
// Either enable full remote functionality or just selected features
|
||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||
|
||||
|
@ -274,148 +258,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
try
|
||||
{
|
||||
Scene rebootedScene = null;
|
||||
bool restartAll = false;
|
||||
m_log.Info("[RADMIN]: Request to restart Region.");
|
||||
|
||||
IConfig startupConfig = m_configSource.Configs["Startup"];
|
||||
if (startupConfig != null)
|
||||
{
|
||||
if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
|
||||
{
|
||||
rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
|
||||
restartAll = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootedScene == null)
|
||||
{
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene rebootedScene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
|
||||
}
|
||||
|
||||
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
||||
|
||||
responseData["success"] = false;
|
||||
responseData["accepted"] = true;
|
||||
responseData["rebooting"] = true;
|
||||
|
||||
string message;
|
||||
List<int> times = new List<int>();
|
||||
|
||||
if (requestData.ContainsKey("alerts"))
|
||||
{
|
||||
string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
|
||||
if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Request to cancel restart.");
|
||||
|
||||
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
||||
if (restartModule != null)
|
||||
{
|
||||
message = "Restart has been cancelled";
|
||||
|
||||
if (requestData.ContainsKey("message"))
|
||||
message = requestData["message"].ToString();
|
||||
|
||||
restartModule.AbortRestart(message);
|
||||
List<int> times = new List<int> { 30, 15 };
|
||||
|
||||
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
|
||||
responseData["success"] = true;
|
||||
responseData["rebooting"] = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (string a in alertTimes)
|
||||
times.Add(Convert.ToInt32(a));
|
||||
}
|
||||
else
|
||||
{
|
||||
int timeout = 30;
|
||||
if (requestData.ContainsKey("milliseconds"))
|
||||
timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
|
||||
while (timeout > 0)
|
||||
{
|
||||
times.Add(timeout);
|
||||
if (timeout > 300)
|
||||
timeout -= 120;
|
||||
else if (timeout > 30)
|
||||
timeout -= 30;
|
||||
else
|
||||
timeout -= 15;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Request to restart Region.");
|
||||
|
||||
message = "Region is restarting in {0}. Please save what you are doing and log out.";
|
||||
|
||||
if (requestData.ContainsKey("message"))
|
||||
message = requestData["message"].ToString();
|
||||
|
||||
bool notice = true;
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string)requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
notice = false;
|
||||
}
|
||||
|
||||
if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false))
|
||||
{
|
||||
m_log.Info("[RADMIN]: Counting affected avatars");
|
||||
int agents = 0;
|
||||
|
||||
if (restartAll)
|
||||
{
|
||||
foreach (Scene s in m_application.SceneManager.Scenes)
|
||||
{
|
||||
foreach (ScenePresence sp in s.GetScenePresences())
|
||||
{
|
||||
if (!sp.IsChildAgent && !sp.IsNPC)
|
||||
agents++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ScenePresence sp in rebootedScene.GetScenePresences())
|
||||
{
|
||||
if (!sp.IsChildAgent && !sp.IsNPC)
|
||||
agents++;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents);
|
||||
|
||||
if (agents == 0)
|
||||
{
|
||||
m_log.Info("[RADMIN]: No avatars detected, shutting down without delay");
|
||||
|
||||
times.Clear();
|
||||
times.Add(0);
|
||||
}
|
||||
}
|
||||
|
||||
List<Scene> restartList;
|
||||
|
||||
if (restartAll)
|
||||
restartList = m_application.SceneManager.Scenes;
|
||||
else
|
||||
restartList = new List<Scene>() { rebootedScene };
|
||||
|
||||
foreach (Scene s in m_application.SceneManager.Scenes)
|
||||
{
|
||||
restartModule = s.RequestModuleInterface<IRestartModule>();
|
||||
if (restartModule != null)
|
||||
restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
|
||||
}
|
||||
responseData["success"] = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
|
||||
// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
|
||||
responseData["rebooting"] = false;
|
||||
|
||||
throw;
|
||||
throw e;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Restart Region request complete");
|
||||
|
@ -445,32 +313,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
m_log.Info("[RADMIN]: Alert request complete");
|
||||
}
|
||||
|
||||
public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
|
||||
m_log.Info("[RADMIN]: Dialog request started");
|
||||
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
string message = (string)requestData["message"];
|
||||
string fromuuid = (string)requestData["from"];
|
||||
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
|
||||
|
||||
responseData["accepted"] = true;
|
||||
responseData["success"] = true;
|
||||
|
||||
m_application.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
|
||||
});
|
||||
|
||||
m_log.Info("[RADMIN]: Dialog request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Load height maps request started");
|
||||
|
@ -485,14 +327,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
// k, (string)requestData[k], ((string)requestData[k]).Length);
|
||||
// }
|
||||
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename" });
|
||||
CheckStringParameters(requestData, responseData, new string[] {"filename", "regionid"});
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
string file = (string)requestData["filename"];
|
||||
|
||||
responseData["accepted"] = true;
|
||||
|
@ -500,11 +339,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
LoadHeightmap(file, scene.RegionInfo.RegionID);
|
||||
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Load height maps request complete");
|
||||
}
|
||||
|
@ -518,30 +352,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString());
|
||||
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename" });
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename", "regionid" });
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
Scene region = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out region);
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
string file = (string)requestData["filename"];
|
||||
m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file);
|
||||
|
||||
responseData["accepted"] = true;
|
||||
|
||||
ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
|
||||
ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>();
|
||||
if (null == terrainModule) throw new Exception("terrain module not available");
|
||||
|
||||
terrainModule.SaveToFile(file);
|
||||
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Save height maps request complete");
|
||||
}
|
||||
|
@ -574,23 +401,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
message = "Region is going down now.";
|
||||
}
|
||||
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string) requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
m_application.SceneManager.ForEachScene(
|
||||
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!requestData.ContainsKey("noticetype")
|
||||
|| ((string)requestData["noticetype"] != "none"))
|
||||
{
|
||||
m_application.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
|
@ -598,8 +408,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
if (dialogModule != null)
|
||||
dialogModule.SendGeneralAlert(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Perform shutdown
|
||||
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
|
||||
|
@ -868,7 +676,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
region.EstateSettings.EstateName = (string) requestData["estate_name"];
|
||||
region.EstateSettings.EstateOwner = userID;
|
||||
// Persistence does not seem to effect the need to save a new estate
|
||||
m_application.EstateDataService.StoreEstateSettings(region.EstateSettings);
|
||||
region.EstateSettings.Save();
|
||||
|
||||
if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
|
||||
throw new Exception("Failed to join estate.");
|
||||
|
@ -898,7 +706,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
// If an access specification was provided, use it.
|
||||
// Otherwise accept the default.
|
||||
newScene.RegionInfo.EstateSettings.PublicAccess = GetBoolean(requestData, "public", m_publicAccess);
|
||||
m_application.EstateDataService.StoreEstateSettings(newScene.RegionInfo.EstateSettings);
|
||||
newScene.RegionInfo.EstateSettings.Save();
|
||||
|
||||
// enable voice on newly created region if
|
||||
// requested by either the XmlRpc request or the
|
||||
|
@ -1084,7 +892,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
scene.RegionInfo.EstateSettings.PublicAccess =
|
||||
GetBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess);
|
||||
if (scene.RegionInfo.Persistent)
|
||||
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
|
||||
scene.RegionInfo.EstateSettings.Save();
|
||||
|
||||
if (requestData.ContainsKey("enable_voice"))
|
||||
{
|
||||
|
@ -1196,7 +1004,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home)
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
|
||||
|
@ -1426,7 +1234,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
if ((null != regionXLocation) && (null != regionYLocation))
|
||||
{
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
|
||||
} else {
|
||||
|
@ -1457,139 +1265,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate an user.
|
||||
/// <summary>
|
||||
/// <param name="request">incoming XML RPC request</param>
|
||||
/// <remarks>
|
||||
/// XmlRpcAuthenticateUserMethod takes the following XMLRPC
|
||||
/// parameters
|
||||
/// <list type="table">
|
||||
/// <listheader><term>parameter name</term><description>description</description></listheader>
|
||||
/// <item><term>password</term>
|
||||
/// <description>admin password as set in OpenSim.ini</description></item>
|
||||
/// <item><term>user_firstname</term>
|
||||
/// <description>avatar's first name</description></item>
|
||||
/// <item><term>user_lastname</term>
|
||||
/// <description>avatar's last name</description></item>
|
||||
/// <item><term>user_password</term>
|
||||
/// <description>MD5 hash of avatar's password</description></item>
|
||||
/// <item><term>token_lifetime</term>
|
||||
/// <description>the lifetime of the returned token (upper bounded to 30s)</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// XmlRpcAuthenticateUserMethod returns
|
||||
/// <list type="table">
|
||||
/// <listheader><term>name</term><description>description</description></listheader>
|
||||
/// <item><term>success</term>
|
||||
/// <description>true or false</description></item>
|
||||
/// <item><term>token</term>
|
||||
/// <description>the authentication token sent by OpenSim</description></item>
|
||||
/// <item><term>error</term>
|
||||
/// <description>error message if success is false</description></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
private void XmlRpcAuthenticateUserMethod(XmlRpcRequest request, XmlRpcResponse response,
|
||||
IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: AuthenticateUser: new request");
|
||||
|
||||
var responseData = (Hashtable)response.Value;
|
||||
var requestData = (Hashtable)request.Params[0];
|
||||
|
||||
lock (m_requestLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckStringParameters(requestData, responseData, new[]
|
||||
{
|
||||
"user_firstname",
|
||||
"user_lastname",
|
||||
"user_password",
|
||||
"token_lifetime"
|
||||
});
|
||||
|
||||
var firstName = (string)requestData["user_firstname"];
|
||||
var lastName = (string)requestData["user_lastname"];
|
||||
var password = (string)requestData["user_password"];
|
||||
|
||||
var scene = m_application.SceneManager.CurrentOrFirstScene;
|
||||
|
||||
if (scene.Equals(null))
|
||||
{
|
||||
m_log.Debug("scene does not exist");
|
||||
throw new Exception("Scene does not exist.");
|
||||
}
|
||||
|
||||
var scopeID = scene.RegionInfo.ScopeID;
|
||||
var account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName);
|
||||
|
||||
if (account.Equals(null) || account.PrincipalID.Equals(UUID.Zero))
|
||||
{
|
||||
m_log.DebugFormat("avatar {0} {1} does not exist", firstName, lastName);
|
||||
throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName));
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(password))
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: no password provided for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("no password provided for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
int lifetime;
|
||||
if (int.TryParse((string)requestData["token_lifetime"], NumberStyles.Integer, CultureInfo.InvariantCulture, out lifetime) == false)
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: no token lifetime provided for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("no token lifetime provided for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
// Upper bound on lifetime set to 30s.
|
||||
if (lifetime > 30)
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: token lifetime longer than 30s for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("token lifetime longer than 30s for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
var authModule = scene.RequestModuleInterface<IAuthenticationService>();
|
||||
if (authModule == null)
|
||||
{
|
||||
m_log.Debug("[RADMIN]: AuthenticateUser: no authentication module loded");
|
||||
throw new Exception("no authentication module loaded");
|
||||
}
|
||||
|
||||
var token = authModule.Authenticate(account.PrincipalID, password, lifetime);
|
||||
if (String.IsNullOrEmpty(token))
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: authentication failed for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("authentication failed for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: account for user {0} {1} identified with token {2}",
|
||||
firstName, lastName, token);
|
||||
|
||||
responseData["token"] = token;
|
||||
responseData["success"] = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
responseData["success"] = false;
|
||||
responseData["error"] = e.Message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: AuthenticateUser: request complete");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load an OAR file into a region..
|
||||
/// <summary>
|
||||
|
@ -1658,11 +1333,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
|
||||
if (mergeOar) archiveOptions.Add("merge", null);
|
||||
if (skipAssets) archiveOptions.Add("skipAssets", null);
|
||||
if (archiver != null)
|
||||
archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions);
|
||||
archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty);
|
||||
else
|
||||
throw new Exception("Archiver module not present for scene");
|
||||
|
||||
|
@ -1721,7 +1393,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
/// </remarks>
|
||||
private void XmlRpcSaveOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Save OAR Request");
|
||||
m_log.Info("[RADMIN]: Received Save OAR Administrator Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
@ -1767,14 +1439,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
if (archiver != null)
|
||||
{
|
||||
Guid requestId = Guid.NewGuid();
|
||||
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
|
||||
scene.Name, filename, requestId);
|
||||
|
||||
archiver.ArchiveRegion(filename, requestId, options);
|
||||
archiver.ArchiveRegion(filename, options);
|
||||
|
||||
lock (m_saveOarLock)
|
||||
Monitor.Wait(m_saveOarLock,5000);
|
||||
|
@ -1795,16 +1461,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
throw e;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Save OAR Request complete");
|
||||
m_log.Info("[RADMIN]: Save OAR Administrator Request complete");
|
||||
}
|
||||
|
||||
private void RemoteAdminOarSaveCompleted(Guid uuid, string name)
|
||||
{
|
||||
if (name != "")
|
||||
m_log.ErrorFormat("[RADMIN]: Saving of OAR file with request ID {0} failed with message {1}", uuid, name);
|
||||
else
|
||||
m_log.DebugFormat("[RADMIN]: Saved OAR file for request {0}", uuid);
|
||||
|
||||
m_log.DebugFormat("[RADMIN]: File processing complete for {0}", name);
|
||||
lock (m_saveOarLock)
|
||||
Monitor.Pulse(m_saveOarLock);
|
||||
}
|
||||
|
@ -1918,31 +1580,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
int flags = 0;
|
||||
string text = String.Empty;
|
||||
int health = 0;
|
||||
responseData["success"] = true;
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
try
|
||||
{
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
health = scene.GetHealth(out flags, out text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
responseData["error"] = null;
|
||||
}
|
||||
|
||||
int health = scene.GetHealth();
|
||||
responseData["health"] = health;
|
||||
|
||||
responseData["success"] = true;
|
||||
responseData["health"] = health;
|
||||
responseData["flags"] = flags;
|
||||
responseData["message"] = text;
|
||||
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
|
@ -1976,7 +1628,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
|
||||
|
||||
if (scene.RegionInfo.Persistent)
|
||||
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
|
||||
scene.RegionInfo.EstateSettings.Save();
|
||||
|
||||
m_log.Info("[RADMIN]: Access List Clear Request complete");
|
||||
}
|
||||
|
@ -2022,7 +1674,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
}
|
||||
scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
|
||||
if (scene.RegionInfo.Persistent)
|
||||
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
|
||||
scene.RegionInfo.EstateSettings.Save();
|
||||
}
|
||||
|
||||
responseData["added"] = addedUsers;
|
||||
|
@ -2071,7 +1723,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
}
|
||||
scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
|
||||
if (scene.RegionInfo.Persistent)
|
||||
m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
|
||||
scene.RegionInfo.EstateSettings.Save();
|
||||
}
|
||||
|
||||
responseData["removed"] = removedUsers;
|
||||
|
@ -2247,143 +1899,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
string musicURL = string.Empty;
|
||||
UUID groupID = UUID.Zero;
|
||||
uint flags = 0;
|
||||
bool set_group = false, set_music = false, set_flags = false;
|
||||
|
||||
if (requestData.Contains("group") && requestData["group"] != null)
|
||||
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
|
||||
if (requestData.Contains("music") && requestData["music"] != null)
|
||||
{
|
||||
|
||||
musicURL = requestData["music"].ToString();
|
||||
set_music = true;
|
||||
}
|
||||
|
||||
if (requestData.Contains("flags") && requestData["flags"] != null)
|
||||
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
|
||||
|
||||
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
|
||||
(set_group ? groupID.ToString() : "unchanged"),
|
||||
(set_music ? musicURL : "unchanged"),
|
||||
(set_flags ? flags.ToString() : "unchanged"));
|
||||
|
||||
m_application.SceneManager.ForEachScene(delegate (Scene s)
|
||||
{
|
||||
List<ILandObject> parcels = s.LandChannel.AllParcels();
|
||||
foreach (ILandObject p in parcels)
|
||||
{
|
||||
if (set_music)
|
||||
p.LandData.MusicURL = musicURL;
|
||||
if (set_group)
|
||||
p.LandData.GroupID = groupID;
|
||||
if (set_flags)
|
||||
p.LandData.Flags = flags;
|
||||
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
|
||||
}
|
||||
}
|
||||
);
|
||||
responseData["success"] = true;
|
||||
m_log.Info("[RADMIN]: Reset Land Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Refresh Search Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
|
||||
if (searchModule != null)
|
||||
{
|
||||
searchModule.Refresh();
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Refresh Search Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Refresh Map Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
|
||||
if (mapTileModule != null)
|
||||
{
|
||||
Util.FireAndForget((x) =>
|
||||
{
|
||||
mapTileModule.UploadMapTile(scene);
|
||||
});
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Refresh Map Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
|
||||
responseData["version"] = m_openSimVersion;
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Get Agent Count Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
if (scene == null)
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["count"] = scene.GetRootAgentCount();
|
||||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Get Agent Count Request complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a float with the given parameter name from a request data hash table.
|
||||
/// </summary>
|
||||
|
@ -2559,6 +2074,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
{
|
||||
account.ServiceURLs = new Dictionary<string, object>();
|
||||
account.ServiceURLs["HomeURI"] = string.Empty;
|
||||
account.ServiceURLs["GatekeeperURI"] = string.Empty;
|
||||
account.ServiceURLs["InventoryServerURI"] = string.Empty;
|
||||
account.ServiceURLs["AssetServerURI"] = string.Empty;
|
||||
}
|
||||
|
@ -2805,8 +2321,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
try
|
||||
{
|
||||
Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>();
|
||||
CopyInventoryFolders(destination, source, FolderType.Clothing, inventoryMap, avatarAppearance);
|
||||
CopyInventoryFolders(destination, source, FolderType.BodyPart, inventoryMap, avatarAppearance);
|
||||
CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance);
|
||||
CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance);
|
||||
|
||||
AvatarWearable[] wearables = avatarAppearance.Wearables;
|
||||
|
||||
|
@ -2842,20 +2358,20 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
||||
|
||||
// Get Clothing folder of receiver
|
||||
InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, FolderType.Clothing);
|
||||
InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, AssetType.Clothing);
|
||||
|
||||
if (destinationFolder == null)
|
||||
throw new Exception("Cannot locate folder(s)");
|
||||
|
||||
// Missing destination folder? This should *never* be the case
|
||||
if (destinationFolder.Type != (short)FolderType.Clothing)
|
||||
if (destinationFolder.Type != (short)AssetType.Clothing)
|
||||
{
|
||||
destinationFolder = new InventoryFolderBase();
|
||||
|
||||
destinationFolder.ID = UUID.Random();
|
||||
destinationFolder.Name = "Clothing";
|
||||
destinationFolder.Owner = destination;
|
||||
destinationFolder.Type = (short)FolderType.Clothing;
|
||||
destinationFolder.Type = (short)AssetType.Clothing;
|
||||
destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
|
||||
destinationFolder.Version = 1;
|
||||
inventoryService.AddFolder(destinationFolder); // store base record
|
||||
|
@ -2872,7 +2388,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
if (wearable[0].ItemID != UUID.Zero)
|
||||
{
|
||||
// Get inventory item and copy it
|
||||
InventoryItemBase item = inventoryService.GetItem(source, wearable[0].ItemID);
|
||||
InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source);
|
||||
item = inventoryService.GetItem(item);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
|
@ -2925,7 +2442,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
if (itemID != UUID.Zero)
|
||||
{
|
||||
// Get inventory item and copy it
|
||||
InventoryItemBase item = inventoryService.GetItem(source, itemID);
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, source);
|
||||
item = inventoryService.GetItem(item);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
|
@ -2971,7 +2489,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
/// This method is called by establishAppearance to copy inventory folders to make
|
||||
/// copies of Clothing and Bodyparts inventory folders and attaches worn attachments
|
||||
/// </summary>
|
||||
private void CopyInventoryFolders(UUID destination, UUID source, FolderType assetType, Dictionary<UUID, UUID> inventoryMap,
|
||||
private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap,
|
||||
AvatarAppearance avatarAppearance)
|
||||
{
|
||||
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
||||
|
@ -2987,12 +2505,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
{
|
||||
sourceFolder = new InventoryFolderBase();
|
||||
sourceFolder.ID = UUID.Random();
|
||||
if (assetType == FolderType.Clothing)
|
||||
{
|
||||
if (assetType == AssetType.Clothing) {
|
||||
sourceFolder.Name = "Clothing";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sourceFolder.Name = "Body Parts";
|
||||
}
|
||||
sourceFolder.Owner = source;
|
||||
|
@ -3008,7 +2523,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
{
|
||||
destinationFolder = new InventoryFolderBase();
|
||||
destinationFolder.ID = UUID.Random();
|
||||
if (assetType == FolderType.Clothing)
|
||||
if (assetType == AssetType.Clothing)
|
||||
{
|
||||
destinationFolder.Name = "Clothing";
|
||||
}
|
||||
|
@ -3087,13 +2602,15 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
/// </summary>
|
||||
private void ApplyNextOwnerPermissions(InventoryItemBase item)
|
||||
{
|
||||
if (item.InvType == (int)InventoryType.Object)
|
||||
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
|
||||
{
|
||||
uint perms = item.CurrentPermissions;
|
||||
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
|
||||
item.CurrentPermissions = perms;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
|
||||
}
|
||||
|
||||
item.CurrentPermissions &= item.NextPermissions;
|
||||
item.BasePermissions &= item.NextPermissions;
|
||||
item.EveryOnePermissions &= item.NextPermissions;
|
||||
|
@ -3205,7 +2722,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
|
||||
} else {
|
||||
|
@ -3247,16 +2764,16 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
// m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
|
||||
// uic.folders.Count, uic.items.Count);
|
||||
|
||||
InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, FolderType.Clothing);
|
||||
InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, AssetType.Clothing);
|
||||
|
||||
// This should *never* be the case
|
||||
if (clothingFolder == null || clothingFolder.Type != (short)FolderType.Clothing)
|
||||
if (clothingFolder == null || clothingFolder.Type != (short)AssetType.Clothing)
|
||||
{
|
||||
clothingFolder = new InventoryFolderBase();
|
||||
clothingFolder.ID = UUID.Random();
|
||||
clothingFolder.Name = "Clothing";
|
||||
clothingFolder.Owner = ID;
|
||||
clothingFolder.Type = (short)FolderType.Clothing;
|
||||
clothingFolder.Type = (short)AssetType.Clothing;
|
||||
clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID;
|
||||
clothingFolder.Version = 1;
|
||||
inventoryService.AddFolder(clothingFolder); // store base record
|
||||
|
@ -3302,7 +2819,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
extraFolder.ID = UUID.Random();
|
||||
extraFolder.Name = outfitName;
|
||||
extraFolder.Owner = ID;
|
||||
extraFolder.Type = (short)FolderType.Clothing;
|
||||
extraFolder.Type = (short)AssetType.Clothing;
|
||||
extraFolder.Version = 1;
|
||||
extraFolder.ParentID = clothingFolder.ID;
|
||||
inventoryService.AddFolder(extraFolder);
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<Addin id="OpenSim.ApplicationPlugins.RemoteController" version="0.1">
|
||||
<Runtime>
|
||||
<Import assembly="OpenSim.ApplicationPlugins.RemoteController.dll"/>
|
||||
</Runtime>
|
||||
<Dependencies>
|
||||
<Addin id="OpenSim" version="0.5" />
|
||||
</Dependencies>
|
||||
<Extension path = "/OpenSim/Startup">
|
||||
<Plugin id="RemoteController" type="OpenSim.ApplicationPlugins.RemoteController.RemoteAdminPlugin" />
|
||||
</Extension>
|
||||
</Addin>
|
|
@ -28,10 +28,8 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
|
@ -50,9 +48,10 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// </summary>
|
||||
public delegate IClientAPI GetClientDelegate(UUID agentID);
|
||||
|
||||
public class Caps : IDisposable
|
||||
public class Caps
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_httpListenerHostName;
|
||||
private uint m_httpListenPort;
|
||||
|
@ -65,15 +64,14 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
private CapsHandlers m_capsHandlers;
|
||||
|
||||
private ConcurrentDictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||
= new ConcurrentDictionary<string, PollServiceEventArgs>();
|
||||
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||
= new Dictionary<string, PollServiceEventArgs>();
|
||||
|
||||
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
||||
|
||||
private IHttpServer m_httpListener;
|
||||
private UUID m_agentID;
|
||||
private string m_regionName;
|
||||
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
|
||||
|
||||
public UUID AgentID
|
||||
{
|
||||
|
@ -120,19 +118,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
get { return m_externalCapsHandlers; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CapsFlags:uint
|
||||
{
|
||||
None = 0,
|
||||
SentSeeds = 1,
|
||||
|
||||
ObjectAnim = 0x100,
|
||||
WLEnv = 0x200,
|
||||
AdvEnv = 0x400
|
||||
}
|
||||
|
||||
public CapsFlags Flags { get; set;}
|
||||
|
||||
public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
|
||||
UUID agent, string regionName)
|
||||
{
|
||||
|
@ -150,37 +135,8 @@ namespace OpenSim.Framework.Capabilities
|
|||
}
|
||||
|
||||
m_agentID = agent;
|
||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
|
||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||
m_regionName = regionName;
|
||||
Flags = CapsFlags.None;
|
||||
m_capsActive.Reset();
|
||||
}
|
||||
|
||||
~Caps()
|
||||
{
|
||||
Flags = CapsFlags.None;
|
||||
if (m_capsActive!= null)
|
||||
{
|
||||
m_capsActive.Dispose();
|
||||
m_capsActive = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
Flags = CapsFlags.None;
|
||||
if (m_capsActive != null)
|
||||
{
|
||||
DeregisterHandlers();
|
||||
m_capsActive.Dispose();
|
||||
m_capsActive = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -194,27 +150,11 @@ namespace OpenSim.Framework.Capabilities
|
|||
m_capsHandlers[capName] = handler;
|
||||
}
|
||||
|
||||
public void RegisterSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
|
||||
{
|
||||
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
|
||||
m_capsHandlers.AddSimpleHandler(capName, handler, addToListener);
|
||||
}
|
||||
|
||||
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
||||
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
||||
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||
|
||||
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[CAPS]: Handler with name {0} already registered (ulr {1}, agent {2}, region {3}",
|
||||
capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
||||
return;
|
||||
}
|
||||
|
||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler);
|
||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||
|
||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
// string protocol = "http";
|
||||
|
@ -254,9 +194,8 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
||||
{
|
||||
m_httpListener.RemovePollServiceHTTPHandler(handler.Url);
|
||||
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
|
||||
}
|
||||
m_pollServiceHandlers.Clear();
|
||||
}
|
||||
|
||||
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
||||
|
@ -295,6 +234,9 @@ namespace OpenSim.Framework.Capabilities
|
|||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
//
|
||||
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
|
||||
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
||||
}
|
||||
}
|
||||
|
@ -308,19 +250,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
caps[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
m_capsActive.Set();
|
||||
}
|
||||
|
||||
public bool WaitForActivation()
|
||||
{
|
||||
// Wait for 30s. If that elapses, return false and run without caps
|
||||
return m_capsActive.WaitOne(120000);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
|
@ -41,7 +40,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
public class CapsHandlers
|
||||
{
|
||||
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
||||
private ConcurrentDictionary<string, ISimpleStreamHandler> m_capsSimpleHandlers = new ConcurrentDictionary<string, ISimpleStreamHandler>();
|
||||
private IHttpServer m_httpListener;
|
||||
private string m_httpListenerHostName;
|
||||
private uint m_httpListenerPort;
|
||||
|
@ -55,15 +53,31 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// <param name="httpListener">base HTTP server</param>
|
||||
/// <param name="httpListenerHostname">host name of the HTTP server</param>
|
||||
/// <param name="httpListenerPort">HTTP port</param>
|
||||
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
||||
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
||||
: this(httpListener,httpListenerHostname,httpListenerPort, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary></summary>
|
||||
/// CapsHandlers is a cap handler container but also takes
|
||||
/// care of adding and removing cap handlers to and from the
|
||||
/// supplied BaseHttpServer.
|
||||
/// </summary>
|
||||
/// <param name="httpListener">base HTTP server</param>
|
||||
/// <param name="httpListenerHostname">host name of the HTTP
|
||||
/// server</param>
|
||||
/// <param name="httpListenerPort">HTTP port</param>
|
||||
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https)
|
||||
{
|
||||
m_httpListener = httpListener;
|
||||
m_httpListenerHostName = httpListenerHostname;
|
||||
m_httpListenerPort = httpListenerPort;
|
||||
if (httpListener != null && httpListener.UseSSL)
|
||||
m_useSSL = true;
|
||||
else
|
||||
m_useSSL = false;
|
||||
m_useSSL = https;
|
||||
if (httpListener != null && m_useSSL)
|
||||
{
|
||||
m_httpListenerHostName = httpListener.SSLCommonName;
|
||||
m_httpListenerPort = httpListener.SSLPort;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -74,36 +88,17 @@ namespace OpenSim.Framework.Capabilities
|
|||
public void Remove(string capsName)
|
||||
{
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
if(m_capsHandlers.ContainsKey(capsName))
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[capsName].Path);
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
}
|
||||
if(m_capsSimpleHandlers.TryRemove(capsName, out ISimpleStreamHandler hdr))
|
||||
{
|
||||
m_httpListener.RemoveSimpleStreamHandler(hdr.Path);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
|
||||
{
|
||||
if(ContainsCap(capName))
|
||||
Remove(capName);
|
||||
if(m_capsSimpleHandlers.TryAdd(capName, handler) && addToListener)
|
||||
m_httpListener.AddSimpleStreamHandler(handler);
|
||||
}
|
||||
|
||||
public bool ContainsCap(string cap)
|
||||
{
|
||||
lock (m_capsHandlers)
|
||||
if (m_capsHandlers.ContainsKey(cap))
|
||||
return true;
|
||||
return m_capsSimpleHandlers.ContainsKey(cap);
|
||||
return m_capsHandlers.ContainsKey(cap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -130,9 +125,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
if (m_capsHandlers.ContainsKey(idx))
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
|
||||
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[idx].Path);
|
||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[idx].Path);
|
||||
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[idx].Path);
|
||||
m_capsHandlers.Remove(idx);
|
||||
}
|
||||
|
||||
|
@ -154,9 +146,8 @@ namespace OpenSim.Framework.Capabilities
|
|||
{
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
|
||||
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
||||
m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
|
||||
return __keys;
|
||||
}
|
||||
}
|
||||
|
@ -170,39 +161,24 @@ namespace OpenSim.Framework.Capabilities
|
|||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||
{
|
||||
Hashtable caps = new Hashtable();
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_useSSL)
|
||||
protocol = "https://";
|
||||
|
||||
string protocol = m_useSSL ? "https://" : "http://";
|
||||
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
||||
|
||||
if (requestedCaps == null)
|
||||
{
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
foreach (KeyValuePair<string, ISimpleStreamHandler> kvp in m_capsSimpleHandlers)
|
||||
caps[kvp.Key] = baseUrl + kvp.Value.Path;
|
||||
foreach (KeyValuePair<string, IRequestHandler> kvp in m_capsHandlers)
|
||||
caps[kvp.Key] = baseUrl + kvp.Value.Path;
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
lock (m_capsHandlers)
|
||||
foreach (string capsName in m_capsHandlers.Keys)
|
||||
{
|
||||
for(int i = 0; i < requestedCaps.Count; ++i)
|
||||
{
|
||||
string capsName = requestedCaps[i];
|
||||
if (excludeSeed && "SEED" == capsName)
|
||||
continue;
|
||||
|
||||
if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
|
||||
{
|
||||
caps[capsName] = baseUrl + shdr.Path;
|
||||
if (requestedCaps != null && !requestedCaps.Contains(capsName))
|
||||
continue;
|
||||
}
|
||||
if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
|
||||
{
|
||||
caps[capsName] = baseUrl + chdr.Path;
|
||||
}
|
||||
|
||||
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
//using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class AvatarPickerSearchHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private IPeople m_PeopleService;
|
||||
|
||||
public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_PeopleService = peopleService;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string names = query.GetOne("names");
|
||||
string psize = query.GetOne("page_size");
|
||||
string pnumber = query.GetOne("page");
|
||||
|
||||
if (m_PeopleService == null)
|
||||
return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
|
||||
|
||||
if (string.IsNullOrEmpty(names) || names.Length < 3)
|
||||
return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
|
||||
|
||||
m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
|
||||
|
||||
int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
|
||||
int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
|
||||
|
||||
// Full content request
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
//httpResponse.ContentLength = ??;
|
||||
httpResponse.ContentType = "application/llsd+xml";
|
||||
|
||||
List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
|
||||
|
||||
LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
|
||||
osdReply.next_page_url = httpRequest.RawUrl;
|
||||
foreach (UserData u in users)
|
||||
osdReply.agents.Array.Add(ConvertUserData(u));
|
||||
|
||||
string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
|
||||
return System.Text.Encoding.UTF8.GetBytes(reply);
|
||||
}
|
||||
|
||||
private LLSDPerson ConvertUserData(UserData user)
|
||||
{
|
||||
LLSDPerson p = new LLSDPerson();
|
||||
p.legacy_first_name = user.FirstName;
|
||||
p.legacy_last_name = user.LastName;
|
||||
p.display_name = user.FirstName + " " + user.LastName;
|
||||
if (user.LastName.StartsWith("@"))
|
||||
p.username = user.FirstName.ToLower() + user.LastName.ToLower();
|
||||
else
|
||||
p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
|
||||
p.id = user.Id;
|
||||
p.is_display_name_default = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return System.Text.Encoding.UTF8.GetBytes(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,449 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class FetchInvDescHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
|
||||
private IInventoryService m_InventoryService;
|
||||
private ILibraryService m_LibraryService;
|
||||
private IScene m_Scene;
|
||||
|
||||
public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
|
||||
{
|
||||
m_InventoryService = invService;
|
||||
m_LibraryService = libService;
|
||||
m_Scene = s;
|
||||
}
|
||||
|
||||
public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
|
||||
|
||||
List<LLSDFetchInventoryDescendents> folders = null;
|
||||
List<UUID> bad_folders = new List<UUID>();
|
||||
try
|
||||
{
|
||||
OSDArray foldersrequested = null;
|
||||
OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
|
||||
OSDMap map = (OSDMap)tmp;
|
||||
if(map.TryGetValue("folders", out tmp) && tmp is OSDArray)
|
||||
foldersrequested = tmp as OSDArray;
|
||||
|
||||
if (foldersrequested == null || foldersrequested.Count == 0)
|
||||
{
|
||||
httpResponse.RawBuffer = EmptyResponse;
|
||||
return;
|
||||
}
|
||||
|
||||
folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
|
||||
for (int i = 0; i < foldersrequested.Count; i++)
|
||||
{
|
||||
OSDMap mfolder = foldersrequested[i] as OSDMap;
|
||||
UUID id = mfolder["folder_id"].AsUUID();
|
||||
if(BadRequests.ContainsKey(id))
|
||||
{
|
||||
bad_folders.Add(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
|
||||
try
|
||||
{
|
||||
llsdRequest.folder_id = id;
|
||||
llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
|
||||
llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
|
||||
llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
|
||||
llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message);
|
||||
continue;
|
||||
}
|
||||
folders.Add(llsdRequest);
|
||||
}
|
||||
}
|
||||
foldersrequested = null;
|
||||
tmp = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[FETCH INV DESC]: fail parsing request: {0}", e.Message);
|
||||
httpResponse.RawBuffer = EmptyResponse;
|
||||
return;
|
||||
}
|
||||
|
||||
if (folders == null || folders.Count == 0)
|
||||
{
|
||||
if(bad_folders.Count == 0)
|
||||
{
|
||||
httpResponse.RawBuffer = EmptyResponse;
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = osStringBuilderCache.Acquire();
|
||||
sb.Append("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
|
||||
foreach (UUID bad in bad_folders)
|
||||
{
|
||||
sb.Append("<map><key>folder_id</key><uuid>");
|
||||
sb.Append(bad.ToString());
|
||||
sb.Append("</uuid><key>error</key><string>Unknown</string></map>");
|
||||
}
|
||||
sb.Append("</array></map></llsd>");
|
||||
httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
|
||||
}
|
||||
|
||||
int total_folders = 0;
|
||||
int total_items = 0;
|
||||
|
||||
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders, ref total_folders, ref total_items);
|
||||
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
|
||||
|
||||
int invcollSetCount = 0;
|
||||
if (invcollSet != null)
|
||||
invcollSetCount = invcollSet.Count;
|
||||
|
||||
int mem = 8192 + ((256 * invcollSetCount +
|
||||
384 * total_folders +
|
||||
1024 * total_items +
|
||||
128 * bad_folders.Count) & 0x7ffff000);
|
||||
|
||||
StringBuilder lastresponse = new StringBuilder(mem);
|
||||
lastresponse.Append("<llsd>");
|
||||
|
||||
if (invcollSetCount > 0)
|
||||
{
|
||||
lastresponse.Append("<map><key>folders</key><array>");
|
||||
int i = 0;
|
||||
InventoryCollection thiscoll;
|
||||
for (i = 0; i < invcollSetCount; i++)
|
||||
{
|
||||
thiscoll = invcollSet[i];
|
||||
invcollSet[i] = null;
|
||||
|
||||
LLSDxmlEncode.AddMap(lastresponse);
|
||||
LLSDxmlEncode.AddElem("agent_id", thiscoll.OwnerID, lastresponse);
|
||||
LLSDxmlEncode.AddElem("descendents", thiscoll.Descendents, lastresponse);
|
||||
LLSDxmlEncode.AddElem("folder_id", thiscoll.FolderID, lastresponse);
|
||||
|
||||
if (thiscoll.Folders == null || thiscoll.Folders.Count == 0)
|
||||
LLSDxmlEncode.AddEmptyArray("categories", lastresponse);
|
||||
else
|
||||
{
|
||||
LLSDxmlEncode.AddArray("categories", lastresponse);
|
||||
foreach (InventoryFolderBase invFolder in thiscoll.Folders)
|
||||
{
|
||||
LLSDxmlEncode.AddMap(lastresponse);
|
||||
|
||||
LLSDxmlEncode.AddElem("folder_id", invFolder.ID, lastresponse);
|
||||
LLSDxmlEncode.AddElem("parent_id", invFolder.ParentID, lastresponse);
|
||||
LLSDxmlEncode.AddElem("name", invFolder.Name, lastresponse);
|
||||
LLSDxmlEncode.AddElem("type", invFolder.Type, lastresponse);
|
||||
LLSDxmlEncode.AddElem("preferred_type", (int)-1, lastresponse);
|
||||
LLSDxmlEncode.AddElem("version", invFolder.Version, lastresponse);
|
||||
|
||||
LLSDxmlEncode.AddEndMap(lastresponse);
|
||||
}
|
||||
LLSDxmlEncode.AddEndArray(lastresponse);
|
||||
}
|
||||
|
||||
if (thiscoll.Items == null || thiscoll.Items.Count == 0)
|
||||
LLSDxmlEncode.AddEmptyArray("items", lastresponse);
|
||||
else
|
||||
{
|
||||
LLSDxmlEncode.AddArray("items", lastresponse);
|
||||
foreach (InventoryItemBase invItem in thiscoll.Items)
|
||||
{
|
||||
invItem.ToLLSDxml(lastresponse);
|
||||
}
|
||||
|
||||
LLSDxmlEncode.AddEndArray(lastresponse);
|
||||
}
|
||||
|
||||
LLSDxmlEncode.AddElem("owner_id", thiscoll.OwnerID, lastresponse);
|
||||
LLSDxmlEncode.AddElem("version", thiscoll.Version, lastresponse);
|
||||
|
||||
LLSDxmlEncode.AddEndMap(lastresponse);
|
||||
invcollSet[i] = null;
|
||||
}
|
||||
lastresponse.Append("</array></map>");
|
||||
thiscoll = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastresponse.Append("<map><key>folders</key><array /></map>");
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
|
||||
if (bad_folders.Count > 0)
|
||||
{
|
||||
lastresponse.Append("<map><key>bad_folders</key><array>");
|
||||
foreach (UUID bad in bad_folders)
|
||||
{
|
||||
BadRequests.Add(bad);
|
||||
lastresponse.Append("<map><key>folder_id</key><uuid>");
|
||||
lastresponse.Append(bad.ToString());
|
||||
lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");
|
||||
}
|
||||
lastresponse.Append("</array></map>");
|
||||
}
|
||||
lastresponse.Append("</llsd>");
|
||||
|
||||
httpResponse.RawBuffer = Util.UTF8NBGetbytes(lastresponse.ToString());
|
||||
}
|
||||
|
||||
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result, ref int total_folders, ref int total_items)
|
||||
{
|
||||
InventoryFolderImpl fold;
|
||||
if (m_LibraryService == null || m_LibraryService.LibraryRootFolder == null)
|
||||
return;
|
||||
|
||||
foreach (LLSDFetchInventoryDescendents f in libFolders)
|
||||
{
|
||||
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
|
||||
{
|
||||
InventoryCollection Collection = new InventoryCollection();
|
||||
// ret.Collection.Folders = new List<InventoryFolderBase>();
|
||||
Collection.Folders = fold.RequestListOfFolders();
|
||||
Collection.Items = fold.RequestListOfItems();
|
||||
Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
|
||||
Collection.FolderID = f.folder_id;
|
||||
Collection.Version = fold.Version;
|
||||
|
||||
Collection.Descendents = Collection.Items.Count + Collection.Folders.Count;
|
||||
total_folders += Collection.Folders.Count;
|
||||
total_items += Collection.Items.Count;
|
||||
result.Add(Collection);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders, ref int total_folders, ref int total_items)
|
||||
{
|
||||
//m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
|
||||
|
||||
// FIXME MAYBE: We're not handling sortOrder!
|
||||
|
||||
List<InventoryCollection> result = new List<InventoryCollection>(32);
|
||||
List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>(32);
|
||||
List<LLSDFetchInventoryDescendents> otherFolders = new List<LLSDFetchInventoryDescendents>(32);
|
||||
HashSet<UUID> libIDs = new HashSet<UUID>();
|
||||
HashSet<UUID> otherIDs = new HashSet<UUID>();
|
||||
|
||||
bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
|
||||
UUID libOwner = UUID.Zero;
|
||||
if(dolib)
|
||||
libOwner = m_LibraryService.LibraryRootFolder.Owner;
|
||||
|
||||
// Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
|
||||
// and can kill the sim (all root folders have parent_id Zero)
|
||||
// send something.
|
||||
bool doneZeroID = false;
|
||||
foreach(LLSDFetchInventoryDescendents f in fetchFolders)
|
||||
{
|
||||
if (f.folder_id == UUID.Zero)
|
||||
{
|
||||
if(doneZeroID)
|
||||
continue;
|
||||
doneZeroID = true;
|
||||
InventoryCollection Collection = new InventoryCollection();
|
||||
Collection.OwnerID = f.owner_id;
|
||||
Collection.Version = 0;
|
||||
Collection.FolderID = f.folder_id;
|
||||
Collection.Descendents = 0;
|
||||
result.Add(Collection);
|
||||
continue;
|
||||
}
|
||||
if(dolib && f.owner_id == libOwner)
|
||||
{
|
||||
if(libIDs.Contains(f.folder_id))
|
||||
continue;
|
||||
libIDs.Add(f.folder_id);
|
||||
libFolders.Add(f);
|
||||
continue;
|
||||
}
|
||||
if(otherIDs.Contains(f.folder_id))
|
||||
continue;
|
||||
|
||||
otherIDs.Add(f.folder_id);
|
||||
otherFolders.Add(f);
|
||||
}
|
||||
|
||||
fetchFolders.Clear();
|
||||
|
||||
if(otherFolders.Count > 0)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
//m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
|
||||
|
||||
InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());
|
||||
|
||||
if (fetchedContents == null)
|
||||
return null;
|
||||
|
||||
if (fetchedContents.Length == 0)
|
||||
{
|
||||
foreach (LLSDFetchInventoryDescendents freq in otherFolders)
|
||||
BadFolder(freq, null, bad_folders);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
// Do some post-processing. May need to fetch more from inv server for links
|
||||
foreach (InventoryCollection contents in fetchedContents)
|
||||
{
|
||||
// Find the original request
|
||||
LLSDFetchInventoryDescendents freq = otherFolders[i];
|
||||
otherFolders[i]=null;
|
||||
i++;
|
||||
|
||||
if (BadFolder(freq, contents, bad_folders))
|
||||
continue;
|
||||
|
||||
if(!freq.fetch_folders)
|
||||
contents.Folders.Clear();
|
||||
if(!freq.fetch_items)
|
||||
contents.Items.Clear();
|
||||
|
||||
contents.Descendents = contents.Items.Count + contents.Folders.Count;
|
||||
|
||||
// Next: link management
|
||||
ProcessLinks(freq, contents);
|
||||
|
||||
total_folders += contents.Folders.Count;
|
||||
total_items += contents.Items.Count;
|
||||
result.Add(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dolib && libFolders.Count > 0)
|
||||
{
|
||||
AddLibraryFolders(libFolders, result, ref total_folders, ref total_items);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
|
||||
{
|
||||
if (contents == null)
|
||||
{
|
||||
bad_folders.Add(freq.folder_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
// The inventory server isn't sending FolderID in the collection...
|
||||
// Must fetch it individually
|
||||
if (contents.FolderID == UUID.Zero)
|
||||
{
|
||||
InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id);
|
||||
if (containingFolder == null)
|
||||
{
|
||||
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
|
||||
bad_folders.Add(freq.folder_id);
|
||||
return true;
|
||||
}
|
||||
contents.FolderID = containingFolder.ID;
|
||||
contents.OwnerID = containingFolder.Owner;
|
||||
contents.Version = containingFolder.Version;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollection contents)
|
||||
{
|
||||
if (contents.Items == null || contents.Items.Count == 0)
|
||||
return;
|
||||
|
||||
// viewers are lasy and want a copy of the linked item sent before the link to it
|
||||
|
||||
// look for item links
|
||||
List<UUID> itemIDs = new List<UUID>();
|
||||
foreach (InventoryItemBase item in contents.Items)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType);
|
||||
if (item.AssetType == (int)AssetType.Link)
|
||||
itemIDs.Add(item.AssetID);
|
||||
}
|
||||
|
||||
// get the linked if any
|
||||
if (itemIDs.Count > 0)
|
||||
{
|
||||
InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
|
||||
|
||||
if (linked != null)
|
||||
{
|
||||
List<InventoryItemBase> linkedItems = new List<InventoryItemBase>(linked.Length);
|
||||
// check for broken
|
||||
foreach (InventoryItemBase linkedItem in linked)
|
||||
{
|
||||
// Take care of genuinely broken links where the target doesn't exist
|
||||
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// rather than having to keep track of every folder requested in the recursion.
|
||||
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
{
|
||||
linkedItems.Add(linkedItem);
|
||||
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
|
||||
}
|
||||
}
|
||||
// insert them
|
||||
if(linkedItems.Count > 0)
|
||||
contents.Items.InsertRange(0, linkedItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class FetchInventory2Handler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IInventoryService m_inventoryService;
|
||||
private UUID m_agentID;
|
||||
|
||||
public FetchInventory2Handler(IInventoryService invService, UUID agentId)
|
||||
{
|
||||
m_inventoryService = invService;
|
||||
m_agentID = agentId;
|
||||
}
|
||||
|
||||
public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
|
||||
|
||||
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
|
||||
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
||||
|
||||
UUID[] itemIDs = new UUID[itemsRequested.Count];
|
||||
int i = 0;
|
||||
|
||||
foreach (OSDMap osdItemId in itemsRequested)
|
||||
{
|
||||
itemIDs[i++] = osdItemId["item_id"].AsUUID();
|
||||
}
|
||||
|
||||
InventoryItemBase[] items = null;
|
||||
|
||||
if (m_agentID != UUID.Zero)
|
||||
{
|
||||
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
|
||||
}
|
||||
else
|
||||
{
|
||||
items = new InventoryItemBase[itemsRequested.Count];
|
||||
foreach (UUID id in itemIDs)
|
||||
items[i++] = m_inventoryService.GetItem(UUID.Zero, id);
|
||||
}
|
||||
|
||||
StringBuilder lsl = LLSDxmlEncode.Start(4096);
|
||||
LLSDxmlEncode.AddMap(lsl);
|
||||
|
||||
if(m_agentID == UUID.Zero && items.Length > 0)
|
||||
LLSDxmlEncode.AddElem("agent_id", items[0].Owner, lsl);
|
||||
else
|
||||
LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
|
||||
|
||||
if(items == null || items.Length == 0)
|
||||
{
|
||||
LLSDxmlEncode.AddEmptyArray("items", lsl);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSDxmlEncode.AddArray("items", lsl);
|
||||
foreach (InventoryItemBase item in items)
|
||||
{
|
||||
if (item != null)
|
||||
item.ToLLSDxml(lsl, 0xff);
|
||||
}
|
||||
LLSDxmlEncode.AddEndArray(lsl);
|
||||
}
|
||||
|
||||
LLSDxmlEncode.AddEndMap(lsl);
|
||||
return LLSDxmlEncode.End(lsl);
|
||||
}
|
||||
|
||||
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
|
||||
{
|
||||
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
|
||||
|
||||
if(BadRequests == null)
|
||||
{
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
||||
|
||||
UUID[] itemIDs = new UUID[itemsRequested.Count];
|
||||
int i = 0;
|
||||
foreach (OSDMap osdItemId in itemsRequested)
|
||||
{
|
||||
UUID id = osdItemId["item_id"].AsUUID();
|
||||
if(!BadRequests.ContainsKey(id))
|
||||
itemIDs[i++] = id;
|
||||
}
|
||||
|
||||
InventoryItemBase[] items = null;
|
||||
try
|
||||
{
|
||||
// badrequests still not filled
|
||||
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
|
||||
}
|
||||
catch{ }
|
||||
|
||||
StringBuilder lsl = LLSDxmlEncode.Start(4096);
|
||||
LLSDxmlEncode.AddMap(lsl);
|
||||
|
||||
LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
|
||||
|
||||
if (items == null || items.Length == 0)
|
||||
{
|
||||
LLSDxmlEncode.AddEmptyArray("items", lsl);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSDxmlEncode.AddArray("items", lsl);
|
||||
foreach (InventoryItemBase item in items)
|
||||
{
|
||||
if (item != null)
|
||||
item.ToLLSDxml(lsl, 0xff);
|
||||
}
|
||||
LLSDxmlEncode.AddEndArray(lsl);
|
||||
}
|
||||
|
||||
LLSDxmlEncode.AddEndMap(lsl);
|
||||
httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(lsl));
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class FetchInventory2HandlerTests : OpenSimTestCase
|
||||
{
|
||||
private UUID m_userID = UUID.Random();
|
||||
private Scene m_scene;
|
||||
private UUID m_rootFolderID;
|
||||
private UUID m_notecardsFolder;
|
||||
private UUID m_objectsFolder;
|
||||
|
||||
private void Init()
|
||||
{
|
||||
// Create an inventory that looks like this:
|
||||
//
|
||||
// /My Inventory
|
||||
// <other system folders>
|
||||
// /Objects
|
||||
// Object 1
|
||||
// Object 2
|
||||
// Object 3
|
||||
// /Notecards
|
||||
// Notecard 1
|
||||
// Notecard 2
|
||||
// Notecard 3
|
||||
// Notecard 4
|
||||
// Notecard 5
|
||||
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
|
||||
m_scene.InventoryService.CreateUserInventory(m_userID);
|
||||
|
||||
m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
|
||||
|
||||
InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
|
||||
m_objectsFolder = of.ID;
|
||||
|
||||
// Add 3 objects
|
||||
InventoryItemBase item;
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-0000000000b" + i), m_userID);
|
||||
item.AssetID = UUID.Random();
|
||||
item.AssetType = (int)AssetType.Object;
|
||||
item.Folder = m_objectsFolder;
|
||||
item.Name = "Object " + i;
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
}
|
||||
|
||||
InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
|
||||
m_notecardsFolder = ncf.ID;
|
||||
|
||||
// Add 5 notecards
|
||||
for (int i = 1; i <= 5; i++)
|
||||
{
|
||||
item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-00000000000" + i), m_userID);
|
||||
item.AssetID = UUID.Random();
|
||||
item.AssetType = (int)AssetType.Notecard;
|
||||
item.Folder = m_notecardsFolder;
|
||||
item.Name = "Notecard " + i;
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_001_RequestOne()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Init();
|
||||
|
||||
FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
|
||||
string request = "<llsd><map><key>items</key><array><map><key>item_id</key><uuid>";
|
||||
request += "10000000-0000-0000-0000-000000000001"; // Notecard 1
|
||||
request += "</uuid></map></array></map></llsd>";
|
||||
|
||||
string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
|
||||
|
||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
||||
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain item uuid");
|
||||
Assert.That(llsdresponse.Contains("Notecard 1"), Is.True, "Response does not contain item Name");
|
||||
Console.WriteLine(llsdresponse);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_002_RequestMany()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Init();
|
||||
|
||||
FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
|
||||
string request = "<llsd><map><key>items</key><array>";
|
||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000001</uuid></map>"; // Notecard 1
|
||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000002</uuid></map>"; // Notecard 2
|
||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000003</uuid></map>"; // Notecard 3
|
||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000004</uuid></map>"; // Notecard 4
|
||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000005</uuid></map>"; // Notecard 5
|
||||
request += "</array></map></llsd>";
|
||||
|
||||
string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
|
||||
|
||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
||||
|
||||
Console.WriteLine(llsdresponse);
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain notecard 1");
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000002"), Is.True, "Response does not contain notecard 2");
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000003"), Is.True, "Response does not contain notecard 3");
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000004"), Is.True, "Response does not contain notecard 4");
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000005"), Is.True, "Response does not contain notecard 5");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,300 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase
|
||||
{
|
||||
private UUID m_userID = new UUID("00000000-0000-0000-0000-000000000001");
|
||||
private Scene m_scene;
|
||||
private UUID m_rootFolderID;
|
||||
private int m_rootDescendents;
|
||||
private UUID m_notecardsFolder;
|
||||
private UUID m_objectsFolder;
|
||||
|
||||
private void Init()
|
||||
{
|
||||
// Create an inventory that looks like this:
|
||||
//
|
||||
// /My Inventory
|
||||
// <other system folders>
|
||||
// /Objects
|
||||
// Some Object
|
||||
// /Notecards
|
||||
// Notecard 1
|
||||
// Notecard 2
|
||||
// /Test Folder
|
||||
// Link to notecard -> /Notecards/Notecard 2
|
||||
// Link to Objects folder -> /Objects
|
||||
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
|
||||
m_scene.InventoryService.CreateUserInventory(m_userID);
|
||||
|
||||
m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
|
||||
|
||||
InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
|
||||
m_objectsFolder = of.ID;
|
||||
|
||||
// Add an object
|
||||
InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID);
|
||||
item.AssetID = UUID.Random();
|
||||
item.AssetType = (int)AssetType.Object;
|
||||
item.Folder = m_objectsFolder;
|
||||
item.Name = "Some Object";
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
|
||||
InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
|
||||
m_notecardsFolder = ncf.ID;
|
||||
|
||||
// Add a notecard
|
||||
item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);
|
||||
item.AssetID = UUID.Random();
|
||||
item.AssetType = (int)AssetType.Notecard;
|
||||
item.Folder = m_notecardsFolder;
|
||||
item.Name = "Test Notecard 1";
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
// Add another notecard
|
||||
item.ID = new UUID("20000000-0000-0000-0000-000000000002");
|
||||
item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a");
|
||||
item.Name = "Test Notecard 2";
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
|
||||
// Add a folder
|
||||
InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID);
|
||||
folder.Type = (short)FolderType.None;
|
||||
m_scene.InventoryService.AddFolder(folder);
|
||||
|
||||
// Add a link to notecard 2 in Test Folder
|
||||
item.AssetID = item.ID; // use item ID of notecard 2
|
||||
item.ID = new UUID("40000000-0000-0000-0000-000000000004");
|
||||
item.AssetType = (int)AssetType.Link;
|
||||
item.Folder = folder.ID;
|
||||
item.Name = "Link to notecard";
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
|
||||
// Add a link to the Objects folder in Test Folder
|
||||
item.AssetID = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object).ID; // use item ID of Objects folder
|
||||
item.ID = new UUID("50000000-0000-0000-0000-000000000005");
|
||||
item.AssetType = (int)AssetType.LinkFolder;
|
||||
item.Folder = folder.ID;
|
||||
item.Name = "Link to Objects folder";
|
||||
m_scene.InventoryService.AddItem(item);
|
||||
|
||||
InventoryCollection coll = m_scene.InventoryService.GetFolderContent(m_userID, m_rootFolderID);
|
||||
m_rootDescendents = coll.Items.Count + coll.Folders.Count;
|
||||
Console.WriteLine("Number of descendents: " + m_rootDescendents);
|
||||
}
|
||||
|
||||
private string dorequest(FetchInvDescHandler handler, string request)
|
||||
{
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
using(ExpiringKey<UUID> bad = new ExpiringKey<UUID>(5000)) // bad but this is test
|
||||
using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
|
||||
{
|
||||
req.InputStream = ms;
|
||||
handler.FetchInventoryDescendentsRequest(req, resp, bad);
|
||||
}
|
||||
return Util.UTF8.GetString(resp.RawBuffer);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_001_SimpleFolder()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Init();
|
||||
|
||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
||||
|
||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_rootFolderID;
|
||||
request += "</uuid><key>owner_id</key><uuid>";
|
||||
request += m_userID.ToString();
|
||||
request += "</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
||||
|
||||
string llsdresponse = dorequest(handler, request);
|
||||
|
||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
||||
|
||||
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
|
||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents");
|
||||
Console.WriteLine(llsdresponse);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_002_MultipleFolders()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
||||
|
||||
string request = "<llsd><map><key>folders</key><array>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_rootFolderID;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_notecardsFolder;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "</array></map></llsd>";
|
||||
|
||||
string llsdresponse = dorequest(handler, request);
|
||||
Console.WriteLine(llsdresponse);
|
||||
|
||||
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
|
||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for root folder");
|
||||
descendents = "descendents</key><integer>2</integer>";
|
||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Notecard folder");
|
||||
|
||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Notecard 1 is missing from response");
|
||||
Assert.That(llsdresponse.Contains("20000000-0000-0000-0000-000000000002"), Is.True, "Notecard 2 is missing from response");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_003_Links()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
||||
|
||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += "f0000000-0000-0000-0000-00000000000f";
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
||||
|
||||
string llsdresponse = dorequest(handler, request);
|
||||
Console.WriteLine(llsdresponse);
|
||||
|
||||
string descendents = "descendents</key><integer>2</integer>";
|
||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Test Folder");
|
||||
|
||||
// Make sure that the note card link is included
|
||||
Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing");
|
||||
|
||||
//Make sure the notecard item itself is included
|
||||
Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing");
|
||||
|
||||
// Make sure that the source item is before the link item
|
||||
int pos1 = llsdresponse.IndexOf("Test Notecard 2");
|
||||
int pos2 = llsdresponse.IndexOf("Link to notecard");
|
||||
Assert.Less(pos1, pos2, "Source of link is after link");
|
||||
|
||||
// Make sure the folder link is included
|
||||
Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing");
|
||||
|
||||
/* contents of link folder are not supposed to be listed
|
||||
// Make sure the objects inside the Objects folder are included
|
||||
// Note: I'm not entirely sure this is needed, but that's what I found in the implementation
|
||||
Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing");
|
||||
*/
|
||||
// Make sure that the source item is before the link item
|
||||
pos1 = llsdresponse.IndexOf("Some Object");
|
||||
pos2 = llsdresponse.IndexOf("Link to Objects folder");
|
||||
Assert.Less(pos1, pos2, "Contents of source of folder link is after folder link");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_004_DuplicateFolders()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
||||
|
||||
string request = "<llsd><map><key>folders</key><array>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_rootFolderID;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_notecardsFolder;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_rootFolderID;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += m_notecardsFolder;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
||||
request += "</array></map></llsd>";
|
||||
|
||||
string llsdresponse = dorequest(handler, request);
|
||||
Console.WriteLine(llsdresponse);
|
||||
|
||||
string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
|
||||
string notecards_folder = "<key>folder_id</key><uuid>" + m_notecardsFolder + "</uuid>";
|
||||
|
||||
Assert.That(llsdresponse.Contains(root_folder), "Missing root folder");
|
||||
Assert.That(llsdresponse.Contains(notecards_folder), "Missing notecards folder");
|
||||
int count = Regex.Matches(llsdresponse, root_folder).Count;
|
||||
Assert.AreEqual(1, count, "More than 1 root folder in response");
|
||||
count = Regex.Matches(llsdresponse, notecards_folder).Count;
|
||||
Assert.AreEqual(2, count, "More than 1 notecards folder in response"); // Notecards will also be under root, so 2
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_005_FolderZero()
|
||||
{
|
||||
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Init();
|
||||
|
||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
||||
|
||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
||||
request += UUID.Zero;
|
||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
||||
|
||||
string llsdresponse = dorequest(handler, request);
|
||||
|
||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
||||
// we do return a answer now
|
||||
//Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder");
|
||||
|
||||
Console.WriteLine(llsdresponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class FetchInventory2Handler
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IInventoryService m_inventoryService;
|
||||
|
||||
public FetchInventory2Handler(IInventoryService invService)
|
||||
{
|
||||
m_inventoryService = invService;
|
||||
}
|
||||
|
||||
public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capabilty request");
|
||||
|
||||
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
|
||||
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
||||
|
||||
string reply;
|
||||
LLSDFetchInventory llsdReply = new LLSDFetchInventory();
|
||||
|
||||
foreach (OSDMap osdItemId in itemsRequested)
|
||||
{
|
||||
UUID itemId = osdItemId["item_id"].AsUUID();
|
||||
|
||||
InventoryItemBase item = m_inventoryService.GetItem(new InventoryItemBase(itemId));
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
// We don't know the agent that this request belongs to so we'll use the agent id of the item
|
||||
// which will be the same for all items.
|
||||
llsdReply.agent_id = item.Owner;
|
||||
|
||||
llsdReply.items.Array.Add(ConvertInventoryItem(item));
|
||||
}
|
||||
}
|
||||
|
||||
reply = LLSDHelpers.SerialiseLLSDReply(llsdReply);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an internal inventory item object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invItem"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
|
||||
{
|
||||
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
|
||||
llsdItem.asset_id = invItem.AssetID;
|
||||
llsdItem.created_at = invItem.CreationDate;
|
||||
llsdItem.desc = invItem.Description;
|
||||
llsdItem.flags = (int)invItem.Flags;
|
||||
llsdItem.item_id = invItem.ID;
|
||||
llsdItem.name = invItem.Name;
|
||||
llsdItem.parent_id = invItem.Folder;
|
||||
llsdItem.type = invItem.AssetType;
|
||||
llsdItem.inv_type = invItem.InvType;
|
||||
|
||||
llsdItem.permissions = new LLSDPermissions();
|
||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||
llsdItem.permissions.group_id = invItem.GroupID;
|
||||
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||
llsdItem.permissions.owner_id = invItem.Owner;
|
||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.sale_info = new LLSDSaleInfo();
|
||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||
|
||||
return llsdItem;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (m_InventoryService == null)
|
||||
throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
|
||||
|
||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero);
|
||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler(
|
||||
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetAssetsHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly Dictionary<string, AssetType> queryTypes = new Dictionary<string, AssetType>()
|
||||
{
|
||||
{"texture_id", AssetType.Texture},
|
||||
{"sound_id", AssetType.Sound},
|
||||
{"callcard_id", AssetType.CallingCard},
|
||||
{"landmark_id", AssetType.Landmark},
|
||||
{"script_id", AssetType.LSLText},
|
||||
{"clothing_id", AssetType.Clothing},
|
||||
{"object_id", AssetType.Object},
|
||||
{"notecard_id", AssetType.Notecard},
|
||||
{"lsltext_id", AssetType.LSLText},
|
||||
{"lslbyte_id", AssetType.LSLBytecode},
|
||||
{"txtr_tga_id", AssetType.TextureTGA},
|
||||
{"bodypart_id", AssetType.Bodypart},
|
||||
{"snd_wav_id", AssetType.SoundWAV},
|
||||
{"img_tga_id", AssetType.ImageTGA},
|
||||
{"jpeg_id", AssetType.ImageJPEG},
|
||||
{"animatn_id", AssetType.Animation},
|
||||
{"gesture_id", AssetType.Gesture},
|
||||
{"mesh_id", AssetType.Mesh},
|
||||
{"settings_id", AssetType.Settings}
|
||||
};
|
||||
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public GetAssetsHandler(IAssetService assService)
|
||||
{
|
||||
m_assetService = assService;
|
||||
}
|
||||
|
||||
public void Handle(OSHttpRequest req, OSHttpResponse response)
|
||||
{
|
||||
response.ContentType = "text/plain";
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
|
||||
response.KeepAlive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
|
||||
var queries = req.QueryAsDictionary;
|
||||
if(queries.Count == 0)
|
||||
return;
|
||||
|
||||
AssetType type = AssetType.Unknown;
|
||||
string assetStr = string.Empty;
|
||||
foreach (KeyValuePair<string,string> kvp in queries)
|
||||
{
|
||||
if (queryTypes.ContainsKey(kvp.Key))
|
||||
{
|
||||
type = queryTypes[kvp.Key];
|
||||
assetStr = kvp.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == AssetType.Unknown)
|
||||
{
|
||||
//m_log.Warn("[GETASSET]: Unknown type: " + query);
|
||||
m_log.Warn("[GETASSET]: Unknown type");
|
||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(assetStr))
|
||||
return;
|
||||
|
||||
UUID assetID = UUID.Zero;
|
||||
if(!UUID.TryParse(assetStr, out assetID))
|
||||
return;
|
||||
|
||||
AssetBase asset = m_assetService.Get(assetID.ToString());
|
||||
if(asset == null)
|
||||
{
|
||||
// m_log.Warn("[GETASSET]: not found: " + query + " " + assetStr);
|
||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
if (asset.Type != (sbyte)type)
|
||||
return;
|
||||
|
||||
int len = asset.Data.Length;
|
||||
|
||||
string range = null;
|
||||
if (req.Headers["Range"] != null)
|
||||
range = req.Headers["Range"];
|
||||
else if (req.Headers["range"] != null)
|
||||
range = req.Headers["range"];
|
||||
|
||||
// range request
|
||||
int start, end;
|
||||
if (Util.TryParseHttpRange(range, out start, out end))
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= asset.Data.Length)
|
||||
{
|
||||
response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
return;
|
||||
}
|
||||
|
||||
if (end == -1)
|
||||
end = asset.Data.Length - 1;
|
||||
else
|
||||
end = Utils.Clamp(end, 0, asset.Data.Length - 1);
|
||||
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
len = end - start + 1;
|
||||
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length));
|
||||
response.StatusCode = (int)HttpStatusCode.PartialContent;
|
||||
response.RawBufferStart = start;
|
||||
}
|
||||
else
|
||||
response.StatusCode = (int)HttpStatusCode.OK;
|
||||
|
||||
response.ContentType = asset.Metadata.ContentType;
|
||||
response.RawBuffer = asset.Data;
|
||||
response.RawBufferLen = len;
|
||||
if (type == AssetType.Mesh || type == AssetType.Texture)
|
||||
{
|
||||
if(len > 8196)
|
||||
{
|
||||
//if(type == AssetType.Texture && ((asset.Flags & AssetFlags.AvatarBake)!= 0))
|
||||
// responsedata["prio"] = 1;
|
||||
//else
|
||||
response.Priority = 2;
|
||||
}
|
||||
else
|
||||
response.Priority = 1;
|
||||
}
|
||||
else
|
||||
response.Priority = -1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,110 +45,71 @@ namespace OpenSim.Capabilities.Handlers
|
|||
{
|
||||
public class GetMeshHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public const string DefaultFormat = "vnd.ll.mesh";
|
||||
|
||||
public GetMeshHandler(IAssetService assService)
|
||||
{
|
||||
m_assetService = assService;
|
||||
}
|
||||
public Hashtable Handle(Hashtable request)
|
||||
{
|
||||
return ProcessGetMesh(request, UUID.Zero, null); ;
|
||||
}
|
||||
|
||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
Hashtable responsedata = new Hashtable();
|
||||
if (m_assetService == null)
|
||||
{
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable;
|
||||
responsedata["str_response_string"] = "The asset service is unavailable";
|
||||
responsedata["keepalive"] = false;
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["int_bytes"] = 0;
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Request wasn't what was expected";
|
||||
|
||||
string meshStr = string.Empty;
|
||||
|
||||
if (request.ContainsKey("mesh_id"))
|
||||
meshStr = request["mesh_id"].ToString();
|
||||
|
||||
if (String.IsNullOrEmpty(meshStr))
|
||||
return responsedata;
|
||||
|
||||
UUID meshID = UUID.Zero;
|
||||
if(!UUID.TryParse(meshStr, out meshID))
|
||||
if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
|
||||
{
|
||||
if (m_assetService == null)
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
||||
if(mesh == null)
|
||||
|
||||
if (mesh != null)
|
||||
{
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
responsedata["str_response_string"] = "Mesh not found.";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
if (mesh.Type != (SByte)AssetType.Mesh)
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
{
|
||||
responsedata["str_response_string"] = "Asset isn't a mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
string range = String.Empty;
|
||||
|
||||
if (((Hashtable)request["headers"])["range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["range"];
|
||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["Range"];
|
||||
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
if (String.IsNullOrEmpty(range))
|
||||
responsedata["int_response_code"] = 200;
|
||||
}
|
||||
// Optionally add additional mesh types here
|
||||
else
|
||||
{
|
||||
// full mesh
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
// range request
|
||||
int start, end;
|
||||
if (Util.TryParseHttpRange(range, out start, out end))
|
||||
}
|
||||
else
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= mesh.Data.Length)
|
||||
{
|
||||
responsedata["str_response_string"] = "This range doesnt exist.";
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
Hashtable headers = new Hashtable();
|
||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length);
|
||||
responsedata["headers"] = headers;
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
|
||||
byte[] d = new byte[len];
|
||||
Array.Copy(mesh.Data, start, d, 0, len);
|
||||
responsedata["bin_response_data"] = d;
|
||||
responsedata["int_bytes"] = len;
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,16 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Nini.Config;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
|
@ -62,17 +65,15 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
string rurl = serverConfig.GetString("GetMeshRedirectURL");
|
||||
|
||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler(
|
||||
"GET",
|
||||
"/" + UUID.Random(),
|
||||
"/CAPS/" + UUID.Random(),
|
||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||
"GetMesh",
|
||||
null);
|
||||
server.AddStreamHandler(reqHandler); ;
|
||||
server.AddStreamHandler(reqHandler);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,34 +47,36 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
|||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetTextureHandler
|
||||
public class GetTextureHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public const string DefaultFormat = "x-j2c";
|
||||
|
||||
public GetTextureHandler(IAssetService assService)
|
||||
// TODO: Change this to a config option
|
||||
const string REDIRECT_URL = null;
|
||||
|
||||
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_assetService = assService;
|
||||
}
|
||||
|
||||
public Hashtable Handle(Hashtable request)
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
Hashtable ret = new Hashtable();
|
||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
ret["content_type"] = "text/plain";
|
||||
ret["int_bytes"] = 0;
|
||||
string textureStr = (string)request["texture_id"];
|
||||
string format = (string)request["format"];
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("texture_id");
|
||||
string format = query.GetOne("format");
|
||||
|
||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
UUID textureID;
|
||||
|
@ -83,45 +85,36 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
||||
|
||||
string[] formats;
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
if (format != null && format != string.Empty)
|
||||
{
|
||||
formats = new string[1] { format.ToLower() };
|
||||
}
|
||||
else
|
||||
{
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
if (((Hashtable)request["headers"])["Accept"] != null)
|
||||
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
|
||||
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
||||
if (formats.Length == 0)
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
|
||||
}
|
||||
// OK, we have an array with preferred formats, possibly with only one entry
|
||||
bool foundtexture = false;
|
||||
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
foreach (string f in formats)
|
||||
{
|
||||
foundtexture = FetchTexture(request, ret, textureID, f);
|
||||
if (foundtexture)
|
||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||
break;
|
||||
}
|
||||
if (!foundtexture)
|
||||
{
|
||||
ret["int_response_code"] = 404;
|
||||
ret["error_status_text"] = "not found";
|
||||
ret["str_response_string"] = "not found";
|
||||
ret["content_type"] = "text/plain";
|
||||
ret["int_bytes"] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||
return ret;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -132,7 +125,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
/// <param name="textureID"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
||||
private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
|
||||
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
||||
AssetBase texture;
|
||||
|
@ -141,6 +134,30 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (format != DefaultFormat)
|
||||
fullID = fullID + "-" + format;
|
||||
|
||||
if (!String.IsNullOrEmpty(REDIRECT_URL))
|
||||
{
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
string textureUrl = REDIRECT_URL + textureID.ToString();
|
||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||
httpResponse.RedirectLocation = textureUrl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else // no redirect
|
||||
{
|
||||
// try the cache
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
|
@ -154,11 +171,13 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
|
||||
}
|
||||
if (format == DefaultFormat)
|
||||
{
|
||||
WriteTextureData(request, response, texture, format);
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -172,7 +191,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
newTexture.Temporary = true;
|
||||
newTexture.Local = true;
|
||||
m_assetService.Store(newTexture);
|
||||
WriteTextureData(request, response, newTexture, format);
|
||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -180,37 +199,26 @@ namespace OpenSim.Capabilities.Handlers
|
|||
else // it was on the cache
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
||||
WriteTextureData(request, response, texture, format);
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
|
||||
//response = new Hashtable();
|
||||
|
||||
|
||||
//WriteTextureData(request,response,null,format);
|
||||
// not found
|
||||
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
|
||||
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
|
||||
{
|
||||
Hashtable headers = new Hashtable();
|
||||
response["headers"] = headers;
|
||||
|
||||
string range = String.Empty;
|
||||
|
||||
if (((Hashtable)request["headers"])["range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["range"];
|
||||
|
||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["Range"];
|
||||
string range = request.Headers.GetOne("Range");
|
||||
|
||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||
{
|
||||
// Range request
|
||||
int start, end;
|
||||
if (Util.TryParseHttpRange(range, out start, out end))
|
||||
if (TryParseRange(range, out start, out end))
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
|
@ -232,8 +240,10 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
||||
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
// viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -248,35 +258,41 @@ namespace OpenSim.Capabilities.Handlers
|
|||
|
||||
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
response["content-type"] = texture.Metadata.ContentType;
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
|
||||
// Always return PartialContent, even if the range covered the entire data length
|
||||
// We were accidentally sending back 404 before in this situation
|
||||
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||
//
|
||||
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
||||
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
||||
// if (end > maxEnd)
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
// else
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
|
||||
byte[] d = new byte[len];
|
||||
Array.Copy(texture.Data, start, d, 0, len);
|
||||
response["bin_response_data"] = d;
|
||||
response["int_bytes"] = len;
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else // JP2's or other formats
|
||||
{
|
||||
// Full content request
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.ContentLength = texture.Data.Length;
|
||||
if (format == DefaultFormat)
|
||||
response["content_type"] = texture.Metadata.ContentType;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
else
|
||||
response["content_type"] = "image/" + format;
|
||||
|
||||
response["bin_response_data"] = texture.Data;
|
||||
response["int_bytes"] = texture.Data.Length;
|
||||
|
||||
// response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
response.ContentType = "image/" + format;
|
||||
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
}
|
||||
|
||||
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
||||
|
@ -289,28 +305,73 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a range header.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
|
||||
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
|
||||
/// Where there is no value, -1 is returned.
|
||||
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
|
||||
/// for start.</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='header'></param>
|
||||
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
|
||||
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
{
|
||||
start = end = 0;
|
||||
|
||||
if (header.StartsWith("bytes="))
|
||||
{
|
||||
string[] rangeValues = header.Substring(6).Split('-');
|
||||
|
||||
if (rangeValues.Length == 2)
|
||||
{
|
||||
if (!Int32.TryParse(rangeValues[0], out start))
|
||||
return false;
|
||||
|
||||
string rawEnd = rangeValues[1];
|
||||
|
||||
if (rawEnd == "")
|
||||
{
|
||||
end = -1;
|
||||
return true;
|
||||
}
|
||||
else if (Int32.TryParse(rawEnd, out end))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start = end = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||
{
|
||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||
byte[] data = new byte[0];
|
||||
|
||||
MemoryStream imgstream = new MemoryStream();
|
||||
Bitmap mTexture = null;
|
||||
ManagedImage managedImage = null;
|
||||
Image image = null;
|
||||
Bitmap mTexture = new Bitmap(1, 1);
|
||||
ManagedImage managedImage;
|
||||
Image image = (Image)mTexture;
|
||||
|
||||
try
|
||||
{
|
||||
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
||||
|
||||
imgstream = new MemoryStream();
|
||||
|
||||
// Decode image to System.Drawing.Image
|
||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
|
||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
|
||||
{
|
||||
// Save to bitmap
|
||||
mTexture = new Bitmap(image);
|
||||
|
||||
using(EncoderParameters myEncoderParameters = new EncoderParameters())
|
||||
{
|
||||
EncoderParameters myEncoderParameters = new EncoderParameters();
|
||||
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
|
||||
|
||||
// Save bitmap to stream
|
||||
|
@ -323,7 +384,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
}
|
||||
else
|
||||
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -340,11 +401,12 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (image != null)
|
||||
image.Dispose();
|
||||
|
||||
if(managedImage != null)
|
||||
managedImage.Clear();
|
||||
if (imgstream != null)
|
||||
{
|
||||
imgstream.Close();
|
||||
imgstream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1,394 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetTextureRobustHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public const string DefaultFormat = "x-j2c";
|
||||
|
||||
// TODO: Change this to a config option
|
||||
private string m_RedirectURL = null;
|
||||
|
||||
public GetTextureRobustHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_assetService = assService;
|
||||
m_RedirectURL = redirectURL;
|
||||
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
|
||||
m_RedirectURL += "/";
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("texture_id");
|
||||
string format = query.GetOne("format");
|
||||
|
||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID textureID;
|
||||
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
||||
|
||||
string[] formats;
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
{
|
||||
formats = new string[1] { format.ToLower() };
|
||||
}
|
||||
else
|
||||
{
|
||||
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
||||
if (formats.Length == 0)
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
|
||||
}
|
||||
// OK, we have an array with preferred formats, possibly with only one entry
|
||||
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
foreach (string f in formats)
|
||||
{
|
||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpRequest"></param>
|
||||
/// <param name="httpResponse"></param>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
||||
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
||||
if(!String.IsNullOrEmpty(m_RedirectURL))
|
||||
{
|
||||
string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
|
||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.Moved;
|
||||
httpResponse.AddHeader("Location:", textureUrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fetch, Misses or invalid return a 404
|
||||
AssetBase texture = m_assetService.Get(textureID.ToString());
|
||||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
if (format == DefaultFormat)
|
||||
{
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
// need to convert format
|
||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
||||
newTexture.Data = ConvertTextureData(texture, format);
|
||||
if (newTexture.Data.Length == 0)
|
||||
return false; // !!! Caller try another codec, please!
|
||||
|
||||
newTexture.Flags = AssetFlags.Collectable;
|
||||
newTexture.Temporary = true;
|
||||
newTexture.Local = true;
|
||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
// not found
|
||||
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
|
||||
{
|
||||
string range = request.Headers.GetOne("Range");
|
||||
|
||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||
{
|
||||
// Range request
|
||||
int start, end;
|
||||
if (TryParseRange(range, out start, out end))
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= texture.Data.Length)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
|
||||
// texture.ID, start, texture.Data.Length);
|
||||
|
||||
// Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
|
||||
// Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
|
||||
// of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
|
||||
// received a very small texture may attempt to fetch bytes from the server past the
|
||||
// range of data that it received originally. Whether this happens appears to depend on whether
|
||||
// the viewer's estimation of how large a request it needs to make for certain discard levels
|
||||
// (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
|
||||
// level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
|
||||
// here will cause the viewer to treat the texture as bad and never display the full resolution
|
||||
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
||||
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle the case where no second range value was given. This is equivalent to requesting
|
||||
// the rest of the entity.
|
||||
if (end == -1)
|
||||
end = int.MaxValue;
|
||||
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
|
||||
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
// Always return PartialContent, even if the range covered the entire data length
|
||||
// We were accidentally sending back 404 before in this situation
|
||||
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||
//
|
||||
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
||||
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
||||
// if (end > maxEnd)
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
// else
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
response.RawBuffer = texture.Data;
|
||||
response.RawBufferStart = start;
|
||||
response.RawBufferLen = len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else // JP2's or other formats
|
||||
{
|
||||
// Full content request
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.ContentLength = texture.Data.Length;
|
||||
if (format == DefaultFormat)
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
else
|
||||
response.ContentType = "image/" + format;
|
||||
response.RawBuffer = texture.Data;
|
||||
response.RawBufferStart = 0;
|
||||
response.RawBufferLen = texture.Data.Length;
|
||||
}
|
||||
|
||||
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
||||
// m_log.WarnFormat(
|
||||
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
|
||||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||
// else
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
|
||||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a range header.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
|
||||
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
|
||||
/// Where there is no value, -1 is returned.
|
||||
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
|
||||
/// for start.</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='header'></param>
|
||||
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
|
||||
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
{
|
||||
start = end = 0;
|
||||
|
||||
if (header.StartsWith("bytes="))
|
||||
{
|
||||
string[] rangeValues = header.Substring(6).Split('-');
|
||||
|
||||
if (rangeValues.Length == 2)
|
||||
{
|
||||
if (!Int32.TryParse(rangeValues[0], out start))
|
||||
return false;
|
||||
|
||||
string rawEnd = rangeValues[1];
|
||||
|
||||
if (rawEnd == "")
|
||||
{
|
||||
end = -1;
|
||||
return true;
|
||||
}
|
||||
else if (Int32.TryParse(rawEnd, out end))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start = end = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||
{
|
||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||
byte[] data = new byte[0];
|
||||
|
||||
MemoryStream imgstream = new MemoryStream();
|
||||
Bitmap mTexture = null;
|
||||
ManagedImage managedImage = null;
|
||||
Image image = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
||||
// Decode image to System.Drawing.Image
|
||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
|
||||
{
|
||||
// Save to bitmap
|
||||
mTexture = new Bitmap(image);
|
||||
|
||||
using(EncoderParameters myEncoderParameters = new EncoderParameters())
|
||||
{
|
||||
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
|
||||
|
||||
// Save bitmap to stream
|
||||
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
|
||||
if (codec != null)
|
||||
{
|
||||
mTexture.Save(imgstream, codec, myEncoderParameters);
|
||||
// Write the stream to a byte array for output
|
||||
data = imgstream.ToArray();
|
||||
}
|
||||
else
|
||||
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Reclaim memory, these are unmanaged resources
|
||||
// If we encountered an exception, one or more of these will be null
|
||||
if (mTexture != null)
|
||||
mTexture.Dispose();
|
||||
|
||||
if (image != null)
|
||||
image.Dispose();
|
||||
|
||||
if(managedImage != null)
|
||||
managedImage.Clear();
|
||||
|
||||
if (imgstream != null)
|
||||
imgstream.Dispose();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// From msdn
|
||||
private static ImageCodecInfo GetEncoderInfo(String mimeType)
|
||||
{
|
||||
ImageCodecInfo[] encoders;
|
||||
encoders = ImageCodecInfo.GetImageEncoders();
|
||||
for (int j = 0; j < encoders.Length; ++j)
|
||||
{
|
||||
if (encoders[j].MimeType == mimeType)
|
||||
return encoders[j];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,6 @@ using OpenSim.Framework.Servers.HttpServer;
|
|||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetTextureServerConnector : ServiceConnector
|
||||
|
@ -63,11 +62,8 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
||||
;
|
||||
server.AddStreamHandler(
|
||||
new GetTextureRobustHandler("/CAPS/GetTexture", m_AssetService, "GetTexture", null, rurl));
|
||||
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ using OpenSim.Framework;
|
|||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
/*
|
||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
|
@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
|||
// Overkill - we only really need the asset service, not a whole scene.
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
|
||||
GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||
|
@ -61,4 +61,3 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class UploadBakedTextureHandler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Caps m_HostCapsObj;
|
||||
private IAssetService m_assetService;
|
||||
private bool m_persistBakedTextures;
|
||||
|
||||
public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures)
|
||||
{
|
||||
m_HostCapsObj = caps;
|
||||
m_assetService = assetService;
|
||||
m_persistBakedTextures = persistBakedTextures;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a request from the client for a Uri to upload a baked texture.
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="httpRequest"></param>
|
||||
/// <param name="httpResponse"></param>
|
||||
/// <returns>The upload response if the request is successful, null otherwise.</returns>
|
||||
public string UploadBakedTexture(
|
||||
string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
try
|
||||
{
|
||||
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||
|
||||
BakedTextureUploader uploader =
|
||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
||||
uploader.OnUpLoad += BakedTextureUploaded;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler(
|
||||
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_HostCapsObj.SSLCaps)
|
||||
protocol = "https://";
|
||||
|
||||
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
|
||||
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
|
||||
|
||||
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
|
||||
uploadResponse.uploader = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
|
||||
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a baked texture has been successfully uploaded by a client.
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="data"></param>
|
||||
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||
{
|
||||
// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||
asset.Data = data;
|
||||
asset.Temporary = true;
|
||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||
m_assetService.Store(asset);
|
||||
}
|
||||
}
|
||||
|
||||
class BakedTextureUploader
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public event Action<UUID, byte[]> OnUpLoad;
|
||||
|
||||
private string uploaderPath = String.Empty;
|
||||
private UUID newAssetID;
|
||||
private IHttpServer httpListener;
|
||||
|
||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
||||
{
|
||||
newAssetID = UUID.Random();
|
||||
uploaderPath = path;
|
||||
httpListener = httpServer;
|
||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle raw uploaded baked texture data.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public string uploaderCaps(byte[] data, string path, string param)
|
||||
{
|
||||
Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
|
||||
|
||||
// Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
|
||||
// on another thread which might send out avatar updates before the asset has been put into the asset
|
||||
// service.
|
||||
if (handlerUpLoad != null)
|
||||
handlerUpLoad(newAssetID, data);
|
||||
|
||||
string res = String.Empty;
|
||||
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
|
||||
uploadComplete.new_asset = newAssetID.ToString();
|
||||
uploadComplete.new_inventory_item = UUID.Zero;
|
||||
uploadComplete.state = "complete";
|
||||
|
||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||
|
||||
httpListener.RemoveStreamHandler("POST", uploaderPath);
|
||||
|
||||
// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,18 +29,18 @@ using System;
|
|||
using Nini.Config;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Server.Handlers.BakedTextures
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class XBakesConnector : ServiceConnector
|
||||
public class UploadBakedTextureServerConnector : ServiceConnector
|
||||
{
|
||||
private IBakedTextureService m_BakesService;
|
||||
private string m_ConfigName = "BakedTextureService";
|
||||
private IAssetService m_AssetService;
|
||||
private string m_ConfigName = "CapsService";
|
||||
|
||||
public XBakesConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
|
@ -50,20 +50,27 @@ namespace OpenSim.Server.Handlers.BakedTextures
|
|||
if (serverConfig == null)
|
||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
||||
|
||||
string assetService = serverConfig.GetString("LocalServiceModule",
|
||||
String.Empty);
|
||||
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
||||
|
||||
if (assetService == String.Empty)
|
||||
throw new Exception("No BakedTextureService in config file");
|
||||
throw new Exception("No AssetService in config file");
|
||||
|
||||
Object[] args = new Object[] { config };
|
||||
m_BakesService =
|
||||
ServerUtils.LoadPlugin<IBakedTextureService>(assetService, args);
|
||||
m_AssetService =
|
||||
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
||||
|
||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
||||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
// NEED TO FIX THIS
|
||||
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
|
||||
server.AddStreamHandler(new RestStreamHandler(
|
||||
"POST",
|
||||
"/CAPS/UploadBakedTexture/",
|
||||
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
|
||||
"UploadBakedTexture",
|
||||
"Upload Baked Texture Capability"));
|
||||
|
||||
server.AddStreamHandler(new BakesServerGetHandler(m_BakesService, auth));
|
||||
server.AddStreamHandler(new BakesServerPostHandler(m_BakesService, auth));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class WebFetchInvDescHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IInventoryService m_InventoryService;
|
||||
private ILibraryService m_LibraryService;
|
||||
// private object m_fetchLock = new Object();
|
||||
|
||||
public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService)
|
||||
{
|
||||
m_InventoryService = invService;
|
||||
m_LibraryService = libService;
|
||||
}
|
||||
|
||||
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// lock (m_fetchLock)
|
||||
// {
|
||||
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
|
||||
|
||||
// nasty temporary hack here, the linden client falsely
|
||||
// identifies the uuid 00000000-0000-0000-0000-000000000000
|
||||
// as a string which breaks us
|
||||
//
|
||||
// correctly mark it as a uuid
|
||||
//
|
||||
request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
|
||||
|
||||
// another hack <integer>1</integer> results in a
|
||||
// System.ArgumentException: Object type System.Int32 cannot
|
||||
// be converted to target type: System.Boolean
|
||||
//
|
||||
request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
|
||||
request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
|
||||
|
||||
Hashtable hash = new Hashtable();
|
||||
try
|
||||
{
|
||||
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||
}
|
||||
catch (LLSD.LLSDParseException e)
|
||||
{
|
||||
m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
|
||||
m_log.Error("Request: " + request);
|
||||
}
|
||||
|
||||
ArrayList foldersrequested = (ArrayList)hash["folders"];
|
||||
|
||||
string response = "";
|
||||
|
||||
for (int i = 0; i < foldersrequested.Count; i++)
|
||||
{
|
||||
string inventoryitemstr = "";
|
||||
Hashtable inventoryhash = (Hashtable)foldersrequested[i];
|
||||
|
||||
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
|
||||
|
||||
try
|
||||
{
|
||||
LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
|
||||
}
|
||||
LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
|
||||
|
||||
inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
|
||||
inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
|
||||
inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
|
||||
|
||||
response += inventoryitemstr;
|
||||
}
|
||||
|
||||
if (response.Length == 0)
|
||||
{
|
||||
// Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
|
||||
// Therefore, I'm concluding that the client only has so many threads available to do requests
|
||||
// and when a thread stalls.. is stays stalled.
|
||||
// Therefore we need to return something valid
|
||||
response = "<llsd><map><key>folders</key><array /></map></llsd>";
|
||||
}
|
||||
else
|
||||
{
|
||||
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
|
||||
//m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
|
||||
|
||||
return response;
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an LLSD reply packet to a CAPS inventory request
|
||||
/// </summary>
|
||||
/// <param name="invFetch"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
|
||||
{
|
||||
LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
|
||||
LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
|
||||
contents.agent_id = invFetch.owner_id;
|
||||
contents.owner_id = invFetch.owner_id;
|
||||
contents.folder_id = invFetch.folder_id;
|
||||
|
||||
reply.folders.Array.Add(contents);
|
||||
InventoryCollection inv = new InventoryCollection();
|
||||
inv.Folders = new List<InventoryFolderBase>();
|
||||
inv.Items = new List<InventoryItemBase>();
|
||||
int version = 0;
|
||||
int descendents = 0;
|
||||
|
||||
inv
|
||||
= Fetch(
|
||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||
|
||||
if (inv != null && inv.Folders != null)
|
||||
{
|
||||
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||
{
|
||||
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||
}
|
||||
|
||||
descendents += inv.Folders.Count;
|
||||
}
|
||||
|
||||
if (inv != null && inv.Items != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in inv.Items)
|
||||
{
|
||||
contents.items.Array.Add(ConvertInventoryItem(invItem));
|
||||
}
|
||||
}
|
||||
|
||||
contents.descendents = descendents;
|
||||
contents.version = version;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
|
||||
// invFetch.folder_id,
|
||||
// invFetch.fetch_items,
|
||||
// invFetch.fetch_folders,
|
||||
// contents.items.Array.Count,
|
||||
// contents.categories.Array.Count,
|
||||
// invFetch.owner_id);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the caps inventory descendents fetch.
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="folderID"></param>
|
||||
/// <param name="ownerID"></param>
|
||||
/// <param name="fetchFolders"></param>
|
||||
/// <param name="fetchItems"></param>
|
||||
/// <param name="sortOrder"></param>
|
||||
/// <param name="version"></param>
|
||||
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
||||
private InventoryCollection Fetch(
|
||||
UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||
// fetchFolders, fetchItems, folderID, agentID);
|
||||
|
||||
// FIXME MAYBE: We're not handling sortOrder!
|
||||
|
||||
version = 0;
|
||||
descendents = 0;
|
||||
|
||||
InventoryFolderImpl fold;
|
||||
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
||||
{
|
||||
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
|
||||
{
|
||||
InventoryCollection ret = new InventoryCollection();
|
||||
ret.Folders = new List<InventoryFolderBase>();
|
||||
ret.Items = fold.RequestListOfItems();
|
||||
descendents = ret.Folders.Count + ret.Items.Count;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
InventoryCollection contents = new InventoryCollection();
|
||||
|
||||
if (folderID != UUID.Zero)
|
||||
{
|
||||
contents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||
InventoryFolderBase containingFolder = new InventoryFolderBase();
|
||||
containingFolder.ID = folderID;
|
||||
containingFolder.Owner = agentID;
|
||||
containingFolder = m_InventoryService.GetFolder(containingFolder);
|
||||
|
||||
if (containingFolder != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
|
||||
// containingFolder.Name, containingFolder.ID, agentID);
|
||||
|
||||
version = containingFolder.Version;
|
||||
|
||||
if (fetchItems)
|
||||
{
|
||||
List<InventoryItemBase> itemsToReturn = contents.Items;
|
||||
List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
|
||||
|
||||
// descendents must only include the links, not the linked items we add
|
||||
descendents = originalItems.Count;
|
||||
|
||||
// Add target items for links in this folder before the links themselves.
|
||||
foreach (InventoryItemBase item in originalItems)
|
||||
{
|
||||
if (item.AssetType == (int)AssetType.Link)
|
||||
{
|
||||
InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
|
||||
// Take care of genuinely broken links where the target doesn't exist
|
||||
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// rather than having to keep track of every folder requested in the recursion.
|
||||
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Now scan for folder links and insert the items they target and those links at the head of the return data
|
||||
foreach (InventoryItemBase item in originalItems)
|
||||
{
|
||||
if (item.AssetType == (int)AssetType.LinkFolder)
|
||||
{
|
||||
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
|
||||
List<InventoryItemBase> links = linkedFolderContents.Items;
|
||||
|
||||
itemsToReturn.InsertRange(0, links);
|
||||
|
||||
foreach (InventoryItemBase link in linkedFolderContents.Items)
|
||||
{
|
||||
// Take care of genuinely broken links where the target doesn't exist
|
||||
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// rather than having to keep track of every folder requested in the recursion.
|
||||
if (link != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
|
||||
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
|
||||
|
||||
InventoryItemBase linkedItem
|
||||
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
|
||||
|
||||
if (linkedItem != null)
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
|
||||
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
|
||||
// }
|
||||
|
||||
// =====
|
||||
|
||||
//
|
||||
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
|
||||
// linkedItem.Name, folderID, agentID);
|
||||
//
|
||||
// contents.Items.Add(linkedItem);
|
||||
// }
|
||||
//
|
||||
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
|
||||
// // will be broken in the viewer.
|
||||
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// if (item.AssetType == (int)AssetType.Link)
|
||||
// {
|
||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
//
|
||||
// // Take care of genuinely broken links where the target doesn't exist
|
||||
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// // rather than having to keep track of every folder requested in the recursion.
|
||||
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
// {
|
||||
// // We don't need to send the folder if source and destination of the link are in the same
|
||||
// // folder.
|
||||
// if (linkedItem.Folder != containingFolder.ID)
|
||||
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
|
||||
// linkedItemFolderId, folderID, agentID);
|
||||
//
|
||||
// int dummyVersion;
|
||||
// InventoryCollection linkedCollection
|
||||
// = Fetch(
|
||||
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
|
||||
//
|
||||
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
|
||||
// linkedFolder.Owner = agentID;
|
||||
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
|
||||
//
|
||||
//// contents.Folders.AddRange(linkedCollection.Folders);
|
||||
//
|
||||
// contents.Folders.Add(linkedFolder);
|
||||
// contents.Items.AddRange(linkedCollection.Items);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lost items don't really need a version
|
||||
version = 1;
|
||||
}
|
||||
|
||||
return contents;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Convert an internal inventory folder object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invFolder"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
|
||||
{
|
||||
LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
|
||||
llsdFolder.folder_id = invFolder.ID;
|
||||
llsdFolder.parent_id = invFolder.ParentID;
|
||||
llsdFolder.name = invFolder.Name;
|
||||
llsdFolder.type = invFolder.Type;
|
||||
llsdFolder.preferred_type = -1;
|
||||
|
||||
return llsdFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an internal inventory item object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invItem"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
|
||||
{
|
||||
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
|
||||
llsdItem.asset_id = invItem.AssetID;
|
||||
llsdItem.created_at = invItem.CreationDate;
|
||||
llsdItem.desc = invItem.Description;
|
||||
llsdItem.flags = (int)invItem.Flags;
|
||||
llsdItem.item_id = invItem.ID;
|
||||
llsdItem.name = invItem.Name;
|
||||
llsdItem.parent_id = invItem.Folder;
|
||||
llsdItem.type = invItem.AssetType;
|
||||
llsdItem.inv_type = invItem.InvType;
|
||||
|
||||
llsdItem.permissions = new LLSDPermissions();
|
||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||
llsdItem.permissions.group_id = invItem.GroupID;
|
||||
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||
llsdItem.permissions.owner_id = invItem.Owner;
|
||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.sale_info = new LLSDSaleInfo();
|
||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||
|
||||
return llsdItem;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,22 +29,19 @@ using System;
|
|||
using Nini.Config;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class FetchInvDescServerConnector : ServiceConnector
|
||||
public class WebFetchInvDescServerConnector : ServiceConnector
|
||||
{
|
||||
private IInventoryService m_InventoryService;
|
||||
private ILibraryService m_LibraryService;
|
||||
private string m_ConfigName = "CapsService";
|
||||
|
||||
public FetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
|
@ -70,16 +67,16 @@ namespace OpenSim.Capabilities.Handlers
|
|||
m_LibraryService =
|
||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
||||
|
||||
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
|
||||
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler(
|
||||
"POST",
|
||||
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
|
||||
webFetchHandler.FetchInventoryDescendentsRequest,
|
||||
"WebFetchInvDesc",
|
||||
null);
|
||||
server.AddStreamHandler(reqHandler);
|
||||
}
|
||||
|
||||
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
|
||||
ISimpleStreamHandler reqHandler
|
||||
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
|
||||
});
|
||||
|
||||
server.AddSimpleStreamHandler(reqHandler);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,10 +68,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// <returns></returns>
|
||||
public static object LLSDDeserialize(byte[] b)
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream(b, false))
|
||||
{
|
||||
return LLSDDeserialize(ms);
|
||||
}
|
||||
return LLSDDeserialize(new MemoryStream(b, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -81,8 +78,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// <returns></returns>
|
||||
public static object LLSDDeserialize(Stream st)
|
||||
{
|
||||
using (XmlTextReader reader = new XmlTextReader(st))
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(st);
|
||||
reader.Read();
|
||||
SkipWS(reader);
|
||||
|
||||
|
@ -98,7 +94,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -107,18 +102,18 @@ namespace OpenSim.Framework.Capabilities
|
|||
/// <returns></returns>
|
||||
public static byte[] LLSDSerialize(object obj)
|
||||
{
|
||||
using(StringWriter sw = new StringWriter())
|
||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
XmlTextWriter writer = new XmlTextWriter(sw);
|
||||
writer.Formatting = Formatting.None;
|
||||
|
||||
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
||||
LLSDWriteOne(writer, obj);
|
||||
writer.WriteEndElement();
|
||||
writer.Flush();
|
||||
|
||||
writer.Close();
|
||||
|
||||
return Util.UTF8.GetBytes(sw.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -566,7 +561,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
endPos = FindEnd(llsd, 1);
|
||||
|
||||
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
|
||||
Culture.NumberFormatInfo, out value))
|
||||
Utils.EnUsCulture.NumberFormat, out value))
|
||||
return value;
|
||||
else
|
||||
throw new LLSDParseException("Failed to parse double value type");
|
||||
|
|
|
@ -30,20 +30,13 @@ using OpenMetaverse;
|
|||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
|
||||
[LLSDType("MAP")]
|
||||
public class LLSDAssetUploadComplete
|
||||
{
|
||||
public string new_asset = String.Empty;
|
||||
public UUID new_inventory_item = UUID.Zero;
|
||||
// public UUID new_texture_folder_id = UUID.Zero;
|
||||
public string state = String.Empty;
|
||||
public LLSDAssetUploadError error = null;
|
||||
//public bool success = false;
|
||||
public int new_next_owner_mask = 0;
|
||||
public int new_group_mask = 0;
|
||||
public int new_everyone_mask = 0;
|
||||
public int inventory_item_flags = 0;
|
||||
|
||||
public LLSDAssetUploadComplete()
|
||||
{
|
||||
|
|
|
@ -30,28 +30,15 @@ using OpenMetaverse;
|
|||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDAssetResource
|
||||
{
|
||||
public OSDArray instance_list = new OSDArray();
|
||||
public OSDArray texture_list = new OSDArray();
|
||||
public OSDArray mesh_list = new OSDArray();
|
||||
public string metric = String.Empty;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadRequest
|
||||
{
|
||||
public string asset_type = String.Empty;
|
||||
public string description = String.Empty;
|
||||
public UUID folder_id = UUID.Zero;
|
||||
public UUID texture_folder_id = UUID.Zero;
|
||||
public int next_owner_mask = 0;
|
||||
public int group_mask = 0;
|
||||
public int everyone_mask = 0;
|
||||
public string inventory_type = String.Empty;
|
||||
public string name = String.Empty;
|
||||
public LLSDAssetResource asset_resources = new LLSDAssetResource();
|
||||
|
||||
public LLSDAssetUploadRequest()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -26,51 +26,20 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadError
|
||||
{
|
||||
public string message = String.Empty;
|
||||
public UUID identifier = UUID.Zero;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponsePricebrkDown
|
||||
{
|
||||
public int mesh_streaming;
|
||||
public int mesh_physics;
|
||||
public int mesh_instance;
|
||||
public int texture;
|
||||
public int model;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponseData
|
||||
{
|
||||
public double resource_cost;
|
||||
public double model_streaming_cost;
|
||||
public double simulation_cost;
|
||||
public double physics_cost;
|
||||
public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponse
|
||||
{
|
||||
public string uploader = String.Empty;
|
||||
public string state = String.Empty;
|
||||
public int upload_price = 0;
|
||||
public LLSDAssetUploadResponseData data = null;
|
||||
public LLSDAssetUploadError error = null;
|
||||
|
||||
public LLSDAssetUploadResponse()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
|
||||
{
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDEnvironmentRequest
|
||||
{
|
||||
public UUID messageID;
|
||||
public UUID regionID;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDEnvironmentSetResponse
|
||||
{
|
||||
public UUID regionID;
|
||||
public UUID messageID;
|
||||
public Boolean success;
|
||||
public String fail_reason;
|
||||
}
|
||||
|
||||
public class EnvironmentSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// generates a empty llsd settings response for viewer
|
||||
/// </summary>
|
||||
/// <param name="messageID">the message UUID</param>
|
||||
/// <param name="regionID">the region UUID</param>
|
||||
public static string EmptySettings(UUID messageID, UUID regionID)
|
||||
{
|
||||
OSDArray arr = new OSDArray();
|
||||
LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
|
||||
msg.messageID = messageID;
|
||||
msg.regionID = regionID;
|
||||
arr.Array.Add(msg);
|
||||
return LLSDHelpers.SerialiseLLSDReply(arr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,6 @@ using System.Collections;
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
|
@ -41,33 +40,18 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
public static string SerialiseLLSDReply(object obj)
|
||||
{
|
||||
using(StringWriter sw = new StringWriter())
|
||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
XmlTextWriter writer = new XmlTextWriter(sw);
|
||||
writer.Formatting = Formatting.None;
|
||||
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
||||
SerializeOSDType(writer, obj);
|
||||
writer.WriteEndElement();
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
|
||||
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
|
||||
|
||||
return sw.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string SerialiseLLSDReplyNoHeader(object obj)
|
||||
{
|
||||
using(StringWriter sw = new StringWriter())
|
||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
||||
{
|
||||
writer.Formatting = Formatting.None;
|
||||
SerializeOSDType(writer, obj);
|
||||
writer.Flush();
|
||||
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
|
||||
|
||||
return sw.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SerializeOSDType(XmlTextWriter writer, object obj)
|
||||
{
|
||||
|
@ -173,22 +157,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
// the LLSD map/array types in the array need to be deserialised
|
||||
// but first we need to know the right class to deserialise them into.
|
||||
}
|
||||
else if(enumerator.Value is Boolean && field.FieldType == typeof(int) )
|
||||
{
|
||||
int i = (bool)enumerator.Value ? 1 : 0;
|
||||
field.SetValue(obj, i);
|
||||
}
|
||||
else if(field.FieldType == typeof(bool) && enumerator.Value is int)
|
||||
{
|
||||
bool b = (int)enumerator.Value != 0;
|
||||
field.SetValue(obj, b);
|
||||
}
|
||||
else if(field.FieldType == typeof(UUID) && enumerator.Value is string)
|
||||
{
|
||||
UUID u;
|
||||
UUID.TryParse((string)enumerator.Value, out u);
|
||||
field.SetValue(obj, u);
|
||||
}
|
||||
else
|
||||
{
|
||||
field.SetValue(obj, enumerator.Value);
|
||||
|
|
|
@ -37,6 +37,5 @@ namespace OpenSim.Framework.Capabilities
|
|||
public string name;
|
||||
public int type;
|
||||
public int preferred_type;
|
||||
public int version;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace Robust32
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
class Program
|
||||
[OSDMap]
|
||||
public class LLSDItemUpdate
|
||||
{
|
||||
static void Main(string[] args)
|
||||
public UUID item_id;
|
||||
|
||||
public LLSDItemUpdate()
|
||||
{
|
||||
global::OpenSim.Server.OpenSimServer.Main(args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDParcelVoiceInfoResponse
|
||||
{
|
||||
public int parcel_local_id;
|
||||
public string region_name;
|
||||
public Hashtable voice_credentials;
|
||||
|
||||
public LLSDParcelVoiceInfoResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public LLSDParcelVoiceInfoResponse(string region, int localID, Hashtable creds)
|
||||
{
|
||||
region_name = region;
|
||||
parcel_local_id = localID;
|
||||
voice_credentials = creds;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[LLSDType("MAP")]
|
||||
public class LLSDRemoteParcelResponse
|
||||
{
|
||||
public UUID parcel_id;
|
||||
|
||||
public LLSDRemoteParcelResponse()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,9 +61,6 @@ namespace OpenSim.Framework.Capabilities
|
|||
// OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
|
||||
|
||||
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
|
||||
if(hash == null)
|
||||
return new byte[0];
|
||||
|
||||
TRequest llsdRequest = new TRequest();
|
||||
LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDTaskScriptUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// The item containing the script to update
|
||||
/// </summary>
|
||||
public UUID item_id;
|
||||
|
||||
/// <summary>
|
||||
/// The task containing the script
|
||||
/// </summary>
|
||||
public UUID task_id;
|
||||
|
||||
/// <summary>
|
||||
/// Signals whether the script is currently active
|
||||
/// </summary>
|
||||
public int is_script_running;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDVoiceAccountResponse
|
||||
{
|
||||
public string username;
|
||||
public string password;
|
||||
public string voice_sip_uri_hostname;
|
||||
public string voice_account_server_name;
|
||||
|
||||
public LLSDVoiceAccountResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public LLSDVoiceAccountResponse(string user, string pass)
|
||||
{
|
||||
username = user;
|
||||
password = pass;
|
||||
}
|
||||
|
||||
public LLSDVoiceAccountResponse(string user, string pass, string sipUriHost, string accountServer)
|
||||
{
|
||||
username = user;
|
||||
password = pass;
|
||||
voice_sip_uri_hostname = sipUriHost;
|
||||
voice_account_server_name = accountServer;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ namespace OpenSim.ConsoleClient
|
|||
while (m_Server.Running)
|
||||
{
|
||||
System.Threading.Thread.Sleep(500);
|
||||
MainConsole.Instance.Prompt();
|
||||
// MainConsole.Instance.Prompt();
|
||||
}
|
||||
|
||||
if (pidFile != String.Empty)
|
||||
|
|
|
@ -37,8 +37,9 @@ namespace OpenSim.Data
|
|||
public abstract class AssetDataBase : IAssetDataPlugin
|
||||
{
|
||||
public abstract AssetBase GetAsset(UUID uuid);
|
||||
public abstract bool StoreAsset(AssetBase asset);
|
||||
public abstract bool[] AssetsExist(UUID[] uuids);
|
||||
|
||||
public abstract void StoreAsset(AssetBase asset);
|
||||
public abstract bool ExistsAsset(UUID uuid);
|
||||
|
||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
|
||||
|
|
|
@ -47,25 +47,24 @@ namespace OpenSim.Data
|
|||
if ((id == null) || (id == DBNull.Value))
|
||||
return UUID.Zero;
|
||||
|
||||
Type idtype = id.GetType();
|
||||
|
||||
if (idtype == typeof(Guid))
|
||||
if (id.GetType() == typeof(Guid))
|
||||
return new UUID((Guid)id);
|
||||
|
||||
if (id.GetType() == typeof(string))
|
||||
if (id.GetType() == typeof(byte[]))
|
||||
{
|
||||
Guid gg;
|
||||
if (Guid.TryParse((string)id, out gg))
|
||||
return new UUID(gg);
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
if (idtype == typeof(byte[]))
|
||||
{
|
||||
if (((byte[])id).Length < 16)
|
||||
if (((byte[])id).Length == 0)
|
||||
return UUID.Zero;
|
||||
else if (((byte[])id).Length == 16)
|
||||
return new UUID((byte[])id, 0);
|
||||
}
|
||||
else if (id.GetType() == typeof(string))
|
||||
{
|
||||
if (((string)id).Length == 0)
|
||||
return UUID.Zero;
|
||||
else if (((string)id).Length == 36)
|
||||
return new UUID((string)id);
|
||||
}
|
||||
|
||||
throw new Exception("Failed to convert db value to UUID: " + id.ToString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace OpenSim.Data
|
|||
public interface IAssetDataPlugin : IPlugin
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
bool StoreAsset(AssetBase asset);
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
public delegate string FSStoreDelegate(AssetBase asset, bool force);
|
||||
|
||||
public interface IFSAssetDataPlugin : IPlugin
|
||||
{
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
void Initialise(string connect, string realm, int SkipAccessTimeDays);
|
||||
bool Delete(string id);
|
||||
|
||||
AssetMetadata Get(string id, out string hash);
|
||||
bool Store(AssetMetadata metadata, string hash);
|
||||
void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store);
|
||||
int Count();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -34,7 +34,6 @@ namespace OpenSim.Data
|
|||
public class OfflineIMData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
public UUID FromID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ namespace OpenSim.Data
|
|||
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
||||
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
|
||||
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
|
||||
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserAppData(ref UserAppData props, ref string result);
|
||||
bool SetUserAppData(UserAppData props, ref string result);
|
||||
OSDArray GetUserImageAssets(UUID avatarId);
|
||||
|
|
|
@ -52,14 +52,14 @@ namespace OpenSim.Data
|
|||
public int sizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Return the x-coordinate of this region in region units.
|
||||
/// Return the x-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
||||
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the y-coordinate of this region in region units.
|
||||
/// Return the y-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
||||
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||
|
||||
public Dictionary<string, object> Data;
|
||||
}
|
||||
|
@ -71,8 +71,6 @@ namespace OpenSim.Data
|
|||
{
|
||||
RegionData Get(UUID regionID, UUID ScopeID);
|
||||
List<RegionData> Get(string regionName, UUID ScopeID);
|
||||
RegionData GetSpecific(string regionName, UUID ScopeID);
|
||||
|
||||
RegionData Get(int x, int y, UUID ScopeID);
|
||||
List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
|
||||
|
||||
|
@ -83,7 +81,6 @@ namespace OpenSim.Data
|
|||
bool Delete(UUID regionID);
|
||||
|
||||
List<RegionData> GetDefaultRegions(UUID scopeID);
|
||||
List<RegionData> GetDefaultHypergridRegions(UUID scopeID);
|
||||
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
||||
List<RegionData> GetHyperlinks(UUID scopeID);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,5 @@ namespace OpenSim.Data
|
|||
bool Store(UserAccountData data);
|
||||
bool Delete(string field, string val);
|
||||
UserAccountData[] GetUsers(UUID scopeID, string query);
|
||||
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data
|
|||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
|
|
|
@ -48,57 +48,9 @@ namespace OpenSim.Data
|
|||
public ulong everyonePowers;
|
||||
public ulong ownersPowers;
|
||||
|
||||
public Dictionary<UUID, XGroupMember> members = new Dictionary<UUID, XGroupMember>();
|
||||
public Dictionary<UUID, XGroupNotice> notices = new Dictionary<UUID, XGroupNotice>();
|
||||
|
||||
public XGroup Clone()
|
||||
{
|
||||
XGroup clone = (XGroup)MemberwiseClone();
|
||||
clone.members = new Dictionary<UUID, XGroupMember>();
|
||||
clone.notices = new Dictionary<UUID, XGroupNotice>();
|
||||
|
||||
foreach (KeyValuePair<UUID, XGroupMember> kvp in members)
|
||||
clone.members[kvp.Key] = kvp.Value.Clone();
|
||||
|
||||
foreach (KeyValuePair<UUID, XGroupNotice> kvp in notices)
|
||||
clone.notices[kvp.Key] = kvp.Value.Clone();
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
public class XGroupMember
|
||||
{
|
||||
public UUID agentID;
|
||||
public UUID groupID;
|
||||
public UUID roleID;
|
||||
public bool acceptNotices = true;
|
||||
public bool listInProfile = true;
|
||||
|
||||
public XGroupMember Clone()
|
||||
{
|
||||
return (XGroupMember)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
public class XGroupNotice
|
||||
{
|
||||
public UUID groupID;
|
||||
public UUID noticeID;
|
||||
public uint timestamp;
|
||||
public string fromName;
|
||||
public string subject;
|
||||
public string message;
|
||||
public byte[] binaryBucket;
|
||||
public bool hasAttachment;
|
||||
public int assetType;
|
||||
|
||||
public XGroupNotice Clone()
|
||||
{
|
||||
XGroupNotice clone = (XGroupNotice)MemberwiseClone();
|
||||
clone.binaryBucket = (byte[])binaryBucket.Clone();
|
||||
|
||||
return clone;
|
||||
return (XGroup)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,13 +58,14 @@ namespace OpenSim.Data
|
|||
/// Early stub interface for groups data, not final.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently in-use only for regression test purposes.
|
||||
/// Currently in-use only for regression test purposes. Needs to be filled out over time.
|
||||
/// </remarks>
|
||||
public interface IXGroupData
|
||||
{
|
||||
bool StoreGroup(XGroup group);
|
||||
XGroup GetGroup(UUID groupID);
|
||||
Dictionary<UUID, XGroup> GetGroups();
|
||||
bool DeleteGroup(UUID groupID);
|
||||
XGroup[] GetGroups(string field, string val);
|
||||
XGroup[] GetGroups(string[] fields, string[] vals);
|
||||
bool DeleteGroups(string field, string val);
|
||||
bool DeleteGroups(string[] fields, string[] vals);
|
||||
}
|
||||
}
|
|
@ -27,20 +27,19 @@
|
|||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A PGSQL Interface for the Asset server
|
||||
/// A MSSQL Interface for the Asset server
|
||||
/// </summary>
|
||||
public class PGSQLAssetData : AssetDataBase
|
||||
public class MSSQLAssetData : AssetDataBase
|
||||
{
|
||||
private const string _migrationStore = "AssetStore";
|
||||
|
||||
|
@ -49,14 +48,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <summary>
|
||||
/// Database manager
|
||||
/// </summary>
|
||||
private PGSQLManager m_database;
|
||||
private MSSQLManager m_database;
|
||||
private string m_connectionString;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
#region IPlugin Members
|
||||
|
||||
override public void Dispose() { }
|
||||
|
@ -67,7 +61,7 @@ namespace OpenSim.Data.PGSQL
|
|||
// [Obsolete("Cannot be default-initialized!")]
|
||||
override public void Initialise()
|
||||
{
|
||||
m_log.Info("[PGSQLAssetData]: " + Name + " cannot be default-initialized!");
|
||||
m_log.Info("[MSSQLAssetData]: " + Name + " cannot be default-initialized!");
|
||||
throw new PluginNotInitialisedException(Name);
|
||||
}
|
||||
|
||||
|
@ -82,7 +76,7 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
|
||||
|
||||
m_database = new PGSQLManager(connectionString);
|
||||
m_database = new MSSQLManager(connectionString);
|
||||
m_connectionString = connectionString;
|
||||
|
||||
//New migration to check for DB changes
|
||||
|
@ -102,7 +96,7 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </summary>
|
||||
override public string Name
|
||||
{
|
||||
get { return "PGSQL Asset storage engine"; }
|
||||
get { return "MSSQL Asset storage engine"; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -116,13 +110,13 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns></returns>
|
||||
override public AssetBase GetAsset(UUID assetID)
|
||||
{
|
||||
string sql = "SELECT * FROM assets WHERE id = :id";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM assets WHERE id = @id";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -149,42 +143,42 @@ namespace OpenSim.Data.PGSQL
|
|||
/// Create asset in m_database
|
||||
/// </summary>
|
||||
/// <param name="asset">the asset</param>
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
|
||||
string sql =
|
||||
@"UPDATE assets set name = :name, description = :description, " + "\"assetType\" " + @" = :assetType,
|
||||
local = :local, temporary = :temporary, creatorid = :creatorid, data = :data
|
||||
WHERE id=:id;
|
||||
|
||||
@"IF EXISTS(SELECT * FROM assets WHERE id=@id)
|
||||
UPDATE assets set name = @name, description = @description, assetType = @assetType,
|
||||
local = @local, temporary = @temporary, creatorid = @creatorid, data = @data
|
||||
WHERE id=@id
|
||||
ELSE
|
||||
INSERT INTO assets
|
||||
(id, name, description, " + "\"assetType\" " + @", local,
|
||||
temporary, create_time, access_time, creatorid, asset_flags, data)
|
||||
Select :id, :name, :description, :assetType, :local,
|
||||
:temporary, :create_time, :access_time, :creatorid, :asset_flags, :data
|
||||
Where not EXISTS(SELECT * FROM assets WHERE id=:id)
|
||||
";
|
||||
([id], [name], [description], [assetType], [local],
|
||||
[temporary], [create_time], [access_time], [creatorid], [asset_flags], [data])
|
||||
VALUES
|
||||
(@id, @name, @description, @assetType, @local,
|
||||
@temporary, @create_time, @access_time, @creatorid, @asset_flags, @data)";
|
||||
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
if (asset.Name.Length > 64)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||
{
|
||||
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||
command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
|
||||
|
@ -205,21 +199,20 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql);
|
||||
m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Commented out since currently unused - this probably should be called in GetAsset()
|
||||
// private void UpdateAccessTime(AssetBase asset)
|
||||
// {
|
||||
// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = :access_time WHERE id=:id"))
|
||||
// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = @access_time WHERE id=@id"))
|
||||
// {
|
||||
// int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||
// cmd.Parameters.AddWithValue(":id", asset.FullID.ToString());
|
||||
// cmd.Parameters.AddWithValue(":access_time", now);
|
||||
// cmd.Parameters.AddWithValue("@id", asset.FullID.ToString());
|
||||
// cmd.Parameters.AddWithValue("@access_time", now);
|
||||
// try
|
||||
// {
|
||||
// cmd.ExecuteNonQuery();
|
||||
|
@ -232,38 +225,17 @@ namespace OpenSim.Data.PGSQL
|
|||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Check if the assets exist in the database.
|
||||
/// Check if asset exist in m_database
|
||||
/// </summary>
|
||||
/// <param name="uuids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public override bool[] AssetsExist(UUID[] uuids)
|
||||
/// <param name="uuid"></param>
|
||||
/// <returns>true if exist.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
{
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
if (GetAsset(uuid) != null)
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(reader["id"]);
|
||||
exist.Add(id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
return results;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -277,19 +249,23 @@ namespace OpenSim.Data.PGSQL
|
|||
public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
|
||||
{
|
||||
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
||||
string sql = @" SELECT id, name, description, " + "\"assetType\"" + @", temporary, creatorid
|
||||
string sql = @"WITH OrderedAssets AS
|
||||
(
|
||||
SELECT id, name, description, assetType, temporary, creatorid,
|
||||
RowNumber = ROW_NUMBER() OVER (ORDER BY id)
|
||||
FROM assets
|
||||
order by id
|
||||
limit :stop
|
||||
offset :start;";
|
||||
)
|
||||
SELECT *
|
||||
FROM OrderedAssets
|
||||
WHERE RowNumber BETWEEN @start AND @stop;";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("start", start));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -28,38 +28,32 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLAuthenticationData : IAuthenticationData
|
||||
public class MSSQLAuthenticationData : IAuthenticationData
|
||||
{
|
||||
private string m_Realm;
|
||||
private List<string> m_ColumnNames = null;
|
||||
private int m_LastExpire = 0;
|
||||
private string m_ConnectionString;
|
||||
private PGSQLManager m_database;
|
||||
private MSSQLManager m_database;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public PGSQLAuthenticationData(string connectionString, string realm)
|
||||
public MSSQLAuthenticationData(string connectionString, string realm)
|
||||
{
|
||||
m_Realm = realm;
|
||||
m_ConnectionString = connectionString;
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, "AuthStore");
|
||||
m_database = new PGSQLManager(m_ConnectionString);
|
||||
m_database = new MSSQLManager(m_ConnectionString);
|
||||
m.Update();
|
||||
}
|
||||
}
|
||||
|
@ -69,14 +63,14 @@ namespace OpenSim.Data.PGSQL
|
|||
AuthenticationData ret = new AuthenticationData();
|
||||
ret.Data = new Dictionary<string, object>();
|
||||
|
||||
string sql = string.Format("select * from {0} where uuid = :principalID", m_Realm);
|
||||
string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader result = cmd.ExecuteReader())
|
||||
using (SqlDataReader result = cmd.ExecuteReader())
|
||||
{
|
||||
if (result.Read())
|
||||
{
|
||||
|
@ -93,7 +87,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
foreach (string s in m_ColumnNames)
|
||||
{
|
||||
if (s == "UUID"||s == "uuid")
|
||||
if (s == "UUID")
|
||||
continue;
|
||||
|
||||
ret.Data[s] = result[s].ToString();
|
||||
|
@ -109,31 +103,12 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
if (data.Data.ContainsKey("UUID"))
|
||||
data.Data.Remove("UUID");
|
||||
if (data.Data.ContainsKey("uuid"))
|
||||
data.Data.Remove("uuid");
|
||||
|
||||
/*
|
||||
Dictionary<string, object> oAuth = new Dictionary<string, object>();
|
||||
|
||||
foreach (KeyValuePair<string, object> oDado in data.Data)
|
||||
{
|
||||
if (oDado.Key != oDado.Key.ToLower())
|
||||
{
|
||||
oAuth.Add(oDado.Key.ToLower(), oDado.Value);
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<string, object> oDado in data.Data)
|
||||
{
|
||||
if (!oAuth.ContainsKey(oDado.Key.ToLower())) {
|
||||
oAuth.Add(oDado.Key.ToLower(), oDado.Value);
|
||||
}
|
||||
}
|
||||
*/
|
||||
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||
StringBuilder updateBuilder = new StringBuilder();
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
updateBuilder.AppendFormat("update {0} set ", m_Realm);
|
||||
|
||||
|
@ -142,28 +117,27 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
if (!first)
|
||||
updateBuilder.Append(", ");
|
||||
updateBuilder.AppendFormat("\"{0}\" = :{0}",field);
|
||||
updateBuilder.AppendFormat("{0} = @{0}",field);
|
||||
|
||||
first = false;
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("" + field, data.Data[field]));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
|
||||
}
|
||||
|
||||
updateBuilder.Append(" where uuid = :principalID");
|
||||
updateBuilder.Append(" where UUID = @principalID");
|
||||
|
||||
cmd.CommandText = updateBuilder.ToString();
|
||||
cmd.Connection = conn;
|
||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", data.PrincipalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
|
||||
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() < 1)
|
||||
{
|
||||
StringBuilder insertBuilder = new StringBuilder();
|
||||
|
||||
insertBuilder.AppendFormat("insert into {0} (uuid, \"", m_Realm);
|
||||
insertBuilder.Append(String.Join("\", \"", fields));
|
||||
insertBuilder.Append("\") values (:principalID, :");
|
||||
insertBuilder.Append(String.Join(", :", fields));
|
||||
insertBuilder.AppendFormat("insert into {0} (UUID, ", m_Realm);
|
||||
insertBuilder.Append(String.Join(", ", fields));
|
||||
insertBuilder.Append(") values (@principalID, @");
|
||||
insertBuilder.Append(String.Join(", @", fields));
|
||||
insertBuilder.Append(")");
|
||||
|
||||
cmd.CommandText = insertBuilder.ToString();
|
||||
|
@ -179,11 +153,11 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public bool SetDataItem(UUID principalID, string item, string value)
|
||||
{
|
||||
string sql = string.Format("update {0} set {1} = :{1} where uuid = :UUID", m_Realm, item);
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("" + item, value));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
return true;
|
||||
|
@ -196,13 +170,13 @@ namespace OpenSim.Data.PGSQL
|
|||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||
DoExpire();
|
||||
|
||||
string sql = "insert into tokens (uuid, token, validity) values (:principalID, :token, :lifetime)";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "insert into tokens (UUID, token, validity) values (@principalID, @token, @lifetime)";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("token", token));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("lifetime", DateTime.Now.AddMinutes(lifetime)));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@token", token));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@lifetime", DateTime.Now.AddMinutes(lifetime)));
|
||||
conn.Open();
|
||||
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
|
@ -219,14 +193,13 @@ namespace OpenSim.Data.PGSQL
|
|||
DoExpire();
|
||||
|
||||
DateTime validDate = DateTime.Now.AddMinutes(lifetime);
|
||||
string sql = "update tokens set validity = :validDate where uuid = :principalID and token = :token and validity > (CURRENT_DATE + CURRENT_TIME)";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "update tokens set validity = @validDate where UUID = @principalID and token = @token and validity > GetDate()";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("token", token));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("validDate", validDate));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@token", token));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@validDate", validDate));
|
||||
conn.Open();
|
||||
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
|
@ -240,12 +213,12 @@ namespace OpenSim.Data.PGSQL
|
|||
private void DoExpire()
|
||||
{
|
||||
DateTime currentDateTime = DateTime.Now;
|
||||
string sql = "delete from tokens where validity < :currentDateTime";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "delete from tokens where validity < @currentDateTime";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Parameters.Add(m_database.CreateParameter("currentDateTime", currentDateTime));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@currentDateTime", currentDateTime));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
m_LastExpire = System.Environment.TickCount;
|
|
@ -27,39 +27,38 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A PGSQL Interface for Avatar Storage
|
||||
/// A MSSQL Interface for Avatar Storage
|
||||
/// </summary>
|
||||
public class PGSQLAvatarData : PGSQLGenericTableHandler<AvatarBaseData>,
|
||||
public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
|
||||
IAvatarData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public PGSQLAvatarData(string connectionString, string realm) :
|
||||
public MSSQLAvatarData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "Avatar")
|
||||
{
|
||||
}
|
||||
|
||||
public bool Delete(UUID principalID, string name)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format("DELETE FROM {0} where \"PrincipalID\" = :PrincipalID and \"Name\" = :Name", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Name", name));
|
||||
cmd.CommandText = String.Format("DELETE FROM {0} where [PrincipalID] = @PrincipalID and [Name] = @Name", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@Name", name));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
|
@ -27,44 +27,38 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using System.Data;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLEstateStore : IEstateDataStore
|
||||
public class MSSQLEstateStore : IEstateDataStore
|
||||
{
|
||||
private const string _migrationStore = "EstateStore";
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private PGSQLManager _Database;
|
||||
private MSSQLManager _Database;
|
||||
private string m_connectionString;
|
||||
private FieldInfo[] _Fields;
|
||||
private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
|
||||
|
||||
#region Public methods
|
||||
|
||||
public PGSQLEstateStore()
|
||||
public MSSQLEstateStore()
|
||||
{
|
||||
}
|
||||
|
||||
public PGSQLEstateStore(string connectionString)
|
||||
public MSSQLEstateStore(string connectionString)
|
||||
{
|
||||
Initialise(connectionString);
|
||||
}
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialises the estatedata class.
|
||||
/// </summary>
|
||||
|
@ -74,11 +68,11 @@ namespace OpenSim.Data.PGSQL
|
|||
if (!string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
_Database = new PGSQLManager(connectionString);
|
||||
_Database = new MSSQLManager(connectionString);
|
||||
}
|
||||
|
||||
//Migration settings
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
|
||||
|
@ -107,17 +101,15 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
EstateSettings es = new EstateSettings();
|
||||
|
||||
string sql = "select estate_settings.\"" + String.Join("\",estate_settings.\"", FieldList) +
|
||||
"\" from estate_map left join estate_settings on estate_map.\"EstateID\" = estate_settings.\"EstateID\" " +
|
||||
" where estate_settings.\"EstateID\" is not null and \"RegionID\" = :RegionID";
|
||||
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = @RegionID";
|
||||
|
||||
bool insertEstate = false;
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("RegionID", regionID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -127,15 +119,11 @@ namespace OpenSim.Data.PGSQL
|
|||
object v = reader[name];
|
||||
if (f.FieldType == typeof(bool))
|
||||
{
|
||||
f.SetValue(es, v);
|
||||
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||
}
|
||||
else if (f.FieldType == typeof(UUID))
|
||||
{
|
||||
UUID estUUID = UUID.Zero;
|
||||
|
||||
UUID.TryParse(v.ToString(), out estUUID);
|
||||
|
||||
f.SetValue(es, estUUID);
|
||||
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||
}
|
||||
else if (f.FieldType == typeof(string))
|
||||
{
|
||||
|
@ -199,37 +187,25 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
names.Remove("EstateID");
|
||||
|
||||
string sql = string.Format("insert into estate_settings (\"{0}\") values ( :{1} )", String.Join("\",\"", names.ToArray()), String.Join(", :", names.ToArray()));
|
||||
string sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand insertCommand = new NpgsqlCommand(sql, conn))
|
||||
//_Log.Debug("[DB ESTATE]: SQL: " + sql);
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand insertCommand = new SqlCommand(sql, conn))
|
||||
{
|
||||
insertCommand.CommandText = sql;
|
||||
insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
insertCommand.Parameters.Add(_Database.CreateParameter("" + name, _FieldMap[name].GetValue(es)));
|
||||
insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
||||
}
|
||||
//NpgsqlParameter idParameter = new NpgsqlParameter("ID", SqlDbType.Int);
|
||||
//idParameter.Direction = ParameterDirection.Output;
|
||||
//insertCommand.Parameters.Add(idParameter);
|
||||
SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
|
||||
idParameter.Direction = ParameterDirection.Output;
|
||||
insertCommand.Parameters.Add(idParameter);
|
||||
conn.Open();
|
||||
insertCommand.ExecuteNonQuery();
|
||||
|
||||
es.EstateID = 100;
|
||||
|
||||
if (insertCommand.ExecuteNonQuery() > 0)
|
||||
{
|
||||
insertCommand.CommandText = "Select cast(lastval() as int) as ID ;";
|
||||
|
||||
using (NpgsqlDataReader result = insertCommand.ExecuteReader())
|
||||
{
|
||||
if (result.Read())
|
||||
{
|
||||
es.EstateID = (uint)result.GetInt32(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
es.EstateID = Convert.ToUInt32(idParameter.Value);
|
||||
}
|
||||
|
||||
//TODO check if this is needed??
|
||||
|
@ -249,20 +225,20 @@ namespace OpenSim.Data.PGSQL
|
|||
string sql = string.Format("UPDATE estate_settings SET ");
|
||||
foreach (string name in names)
|
||||
{
|
||||
sql += "\"" + name + "\" = :" + name + ", ";
|
||||
sql += name + " = @" + name + ", ";
|
||||
}
|
||||
sql = sql.Remove(sql.LastIndexOf(","));
|
||||
sql += " WHERE \"EstateID\" = :EstateID";
|
||||
sql += " WHERE EstateID = @EstateID";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
foreach (string name in names)
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("" + name, _FieldMap[name].GetValue(es)));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
||||
}
|
||||
|
||||
cmd.Parameters.Add(_Database.CreateParameter("EstateID", es.EstateID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
@ -286,24 +262,22 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
es.ClearBans();
|
||||
|
||||
string sql = "select * from estateban where \"EstateID\" = :EstateID";
|
||||
string sql = "select bannedUUID from estateban where EstateID = @EstateID";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
NpgsqlParameter idParameter = new NpgsqlParameter("EstateID", DbType.Int32);
|
||||
SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
|
||||
idParameter.Value = es.EstateID;
|
||||
cmd.Parameters.Add(idParameter);
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
EstateBan eb = new EstateBan();
|
||||
|
||||
eb.BannedUserID = new UUID((Guid)reader["bannedUUID"]); //uuid;
|
||||
eb.BanningUserID = new UUID((Guid)reader["banningUUID"]); //uuid;
|
||||
eb.BanTime = Convert.ToInt32(reader["banTime"]);
|
||||
eb.BannedHostAddress = "0.0.0.0";
|
||||
eb.BannedHostIPMask = "0.0.0.0";
|
||||
es.AddBan(eb);
|
||||
|
@ -316,14 +290,14 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
|
||||
string sql = string.Format("select uuid from {0} where \"EstateID\" = :EstateID", table);
|
||||
string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("EstateID", estateID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -338,25 +312,21 @@ namespace OpenSim.Data.PGSQL
|
|||
private void SaveBanList(EstateSettings es)
|
||||
{
|
||||
//Delete first
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = conn.CreateCommand())
|
||||
using (SqlCommand cmd = conn.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from estateban where \"EstateID\" = :EstateID";
|
||||
cmd.Parameters.AddWithValue("EstateID", (int)es.EstateID);
|
||||
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
||||
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
//Insert after
|
||||
cmd.CommandText = "insert into estateban (\"EstateID\", \"bannedUUID\",\"bannedIp\", \"bannedIpHostMask\", \"bannedNameMask\", \"banningUUID\",\"banTime\" ) values ( :EstateID, :bannedUUID, '','','', :banningUUID, :banTime )";
|
||||
cmd.Parameters.AddWithValue("bannedUUID", Guid.Empty);
|
||||
cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
|
||||
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
|
||||
foreach (EstateBan b in es.EstateBans)
|
||||
{
|
||||
cmd.Parameters["EstateID"].Value = b.EstateID;
|
||||
cmd.Parameters["bannedUUID"].Value = b.BannedUserID.Guid;
|
||||
cmd.Parameters["banningUUID"].Value = b.BanningUserID.Guid;
|
||||
cmd.Parameters["banTime"].Value = b.BanTime;
|
||||
|
||||
cmd.Parameters["@bannedUUID"].Value = b.BannedUserID.Guid;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
@ -365,20 +335,20 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
private void SaveUUIDList(uint estateID, string table, UUID[] data)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = conn.CreateCommand())
|
||||
using (SqlCommand cmd = conn.CreateCommand())
|
||||
{
|
||||
cmd.Parameters.AddWithValue("EstateID", (int)estateID);
|
||||
cmd.CommandText = string.Format("delete from {0} where \"EstateID\" = :EstateID", table);
|
||||
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||
cmd.CommandText = string.Format("delete from {0} where EstateID = @EstateID", table);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = string.Format("insert into {0} (\"EstateID\", uuid) values ( :EstateID, :uuid )", table);
|
||||
cmd.Parameters.AddWithValue("uuid", Guid.Empty);
|
||||
cmd.CommandText = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table);
|
||||
cmd.Parameters.AddWithValue("@uuid", Guid.Empty);
|
||||
foreach (UUID uuid in data)
|
||||
{
|
||||
cmd.Parameters["uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
|
||||
cmd.Parameters["@uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
@ -388,14 +358,14 @@ namespace OpenSim.Data.PGSQL
|
|||
public EstateSettings LoadEstateSettings(int estateID)
|
||||
{
|
||||
EstateSettings es = new EstateSettings();
|
||||
string sql = "select estate_settings.\"" + String.Join("\",estate_settings.\"", FieldList) + "\" from estate_settings where \"EstateID\" = :EstateID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("EstateID", (int)estateID);
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -458,13 +428,13 @@ namespace OpenSim.Data.PGSQL
|
|||
public List<int> GetEstates(string search)
|
||||
{
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select \"EstateID\" from estate_settings where lower(\"EstateName\") = lower(:EstateName)";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string sql = "select estateID from estate_settings where EstateName = @EstateName";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("EstateName", search);
|
||||
cmd.Parameters.AddWithValue("@EstateName", search);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
|
@ -483,11 +453,11 @@ namespace OpenSim.Data.PGSQL
|
|||
public List<int> GetEstatesAll()
|
||||
{
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select \"EstateID\" from estate_settings";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string sql = "select estateID from estate_settings";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
|
@ -506,13 +476,13 @@ namespace OpenSim.Data.PGSQL
|
|||
public List<int> GetEstatesByOwner(UUID ownerID)
|
||||
{
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select \"EstateID\" from estate_settings where \"EstateOwner\" = :EstateOwner";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("EstateOwner", ownerID);
|
||||
cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
|
@ -530,29 +500,28 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public bool LinkRegion(UUID regionID, int estateID)
|
||||
{
|
||||
string deleteSQL = "delete from estate_map where \"RegionID\" = :RegionID";
|
||||
string insertSQL = "insert into estate_map values (:RegionID, :EstateID)";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string deleteSQL = "delete from estate_map where RegionID = @RegionID";
|
||||
string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
NpgsqlTransaction transaction = conn.BeginTransaction();
|
||||
SqlTransaction transaction = conn.BeginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(deleteSQL, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
|
||||
{
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Parameters.AddWithValue("RegionID", regionID.Guid);
|
||||
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(insertSQL, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
|
||||
{
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Parameters.AddWithValue("RegionID", regionID.Guid);
|
||||
cmd.Parameters.AddWithValue("EstateID", estateID);
|
||||
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||
|
||||
int ret = cmd.ExecuteNonQuery();
|
||||
|
||||
|
@ -576,13 +545,13 @@ namespace OpenSim.Data.PGSQL
|
|||
public List<UUID> GetRegions(int estateID)
|
||||
{
|
||||
List<UUID> result = new List<UUID>();
|
||||
string sql = "select \"RegionID\" from estate_map where \"EstateID\" = :EstateID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
string sql = "select RegionID from estate_map where EstateID = @EstateID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("EstateID", estateID);
|
||||
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -31,18 +31,18 @@ using System.Collections.Generic;
|
|||
using System.Data;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Npgsql;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLFriendsData : PGSQLGenericTableHandler<FriendsData>, IFriendsData
|
||||
public class MSSQLFriendsData : MSSQLGenericTableHandler<FriendsData>, IFriendsData
|
||||
{
|
||||
public PGSQLFriendsData(string connectionString, string realm)
|
||||
public MSSQLFriendsData(string connectionString, string realm)
|
||||
: base(connectionString, realm, "FriendsStore")
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, "FriendsStore");
|
||||
|
@ -50,27 +50,19 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool Delete(string principalID, string friend)
|
||||
{
|
||||
UUID princUUID = UUID.Zero;
|
||||
|
||||
bool ret = UUID.TryParse(principalID, out princUUID);
|
||||
|
||||
if (ret)
|
||||
return Delete(princUUID, friend);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where \"PrincipalID\" = :PrincipalID and \"Friend\" = :Friend", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Friend", friend));
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where PrincipalID = @PrincipalID and Friend = @Friend", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@Friend", friend));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
|
@ -79,28 +71,19 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
UUID princUUID = UUID.Zero;
|
||||
|
||||
bool ret = UUID.TryParse(principalID, out princUUID);
|
||||
|
||||
if (ret)
|
||||
return GetFriends(princUUID);
|
||||
else
|
||||
return new FriendsData[0];
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format("select a.*,case when b.\"Flags\" is null then '-1' else b.\"Flags\" end as \"TheirFlags\" from {0} as a " +
|
||||
" left join {0} as b on a.\"PrincipalID\" = b.\"Friend\" and a.\"Friend\" = b.\"PrincipalID\" " +
|
||||
" where a.\"PrincipalID\" = :PrincipalID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID.ToString()));
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = @PrincipalID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
|
@ -109,7 +92,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public FriendsData[] GetFriends(Guid principalID)
|
||||
{
|
||||
return GetFriends(principalID);
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
}
|
|
@ -30,38 +30,30 @@ using System.Collections.Generic;
|
|||
using System.Data;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using System.Data.SqlClient;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using System.Text;
|
||||
using Npgsql;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLGenericTableHandler<T> : PGSqlFramework where T : class, new()
|
||||
public class MSSQLGenericTableHandler<T> where T : class, new()
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected string m_ConnectionString;
|
||||
protected PGSQLManager m_database; //used for parameter type translation
|
||||
protected MSSQLManager m_database; //used for parameter type translation
|
||||
protected Dictionary<string, FieldInfo> m_Fields =
|
||||
new Dictionary<string, FieldInfo>();
|
||||
|
||||
protected Dictionary<string, string> m_FieldTypes = new Dictionary<string, string>();
|
||||
|
||||
protected List<string> m_ColumnNames = null;
|
||||
protected string m_Realm;
|
||||
protected FieldInfo m_DataField = null;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public PGSQLGenericTableHandler(string connectionString,
|
||||
public MSSQLGenericTableHandler(string connectionString,
|
||||
string realm, string storeName)
|
||||
: base(connectionString)
|
||||
{
|
||||
m_Realm = realm;
|
||||
|
||||
|
@ -69,7 +61,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
if (storeName != String.Empty)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, storeName);
|
||||
|
@ -77,15 +69,13 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
|
||||
}
|
||||
m_database = new PGSQLManager(m_ConnectionString);
|
||||
m_database = new MSSQLManager(m_ConnectionString);
|
||||
|
||||
Type t = typeof(T);
|
||||
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.DeclaredOnly);
|
||||
|
||||
LoadFieldTypes();
|
||||
|
||||
if (fields.Length == 0)
|
||||
return;
|
||||
|
||||
|
@ -99,31 +89,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
}
|
||||
|
||||
private void LoadFieldTypes()
|
||||
{
|
||||
m_FieldTypes = new Dictionary<string, string>();
|
||||
|
||||
string query = string.Format(@"select column_name,data_type
|
||||
from INFORMATION_SCHEMA.COLUMNS
|
||||
where table_name = lower('{0}');
|
||||
|
||||
", m_Realm);
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader rdr = cmd.ExecuteReader())
|
||||
{
|
||||
while (rdr.Read())
|
||||
{
|
||||
// query produces 0 to many rows of single column, so always add the first item in each row
|
||||
m_FieldTypes.Add((string)rdr[0], (string)rdr[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckColumnNames(NpgsqlDataReader reader)
|
||||
private void CheckColumnNames(SqlDataReader reader)
|
||||
{
|
||||
if (m_ColumnNames != null)
|
||||
return;
|
||||
|
@ -131,7 +97,6 @@ namespace OpenSim.Data.PGSQL
|
|||
m_ColumnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = reader.GetSchemaTable();
|
||||
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
{
|
||||
if (row["ColumnName"] != null &&
|
||||
|
@ -141,32 +106,21 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
// TODO GET CONSTRAINTS FROM POSTGRESQL
|
||||
private List<string> GetConstraints()
|
||||
{
|
||||
List<string> constraints = new List<string>();
|
||||
string query = string.Format(@"select
|
||||
a.attname as column_name
|
||||
from
|
||||
pg_class t,
|
||||
pg_class i,
|
||||
pg_index ix,
|
||||
pg_attribute a
|
||||
where
|
||||
t.oid = ix.indrelid
|
||||
and i.oid = ix.indexrelid
|
||||
and a.attrelid = t.oid
|
||||
and a.attnum = ANY(ix.indkey)
|
||||
and t.relkind = 'r'
|
||||
and ix.indisunique = true
|
||||
and t.relname = lower('{0}')
|
||||
;", m_Realm);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
|
||||
string query = string.Format(@"SELECT
|
||||
COL_NAME(ic.object_id,ic.column_id) AS column_name
|
||||
FROM sys.indexes AS i
|
||||
INNER JOIN sys.index_columns AS ic
|
||||
ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
||||
WHERE i.is_primary_key = 1
|
||||
AND i.object_id = OBJECT_ID('{0}');", m_Realm);
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(query, conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader rdr = cmd.ExecuteReader())
|
||||
using (SqlDataReader rdr = cmd.ExecuteReader())
|
||||
{
|
||||
while (rdr.Read())
|
||||
{
|
||||
|
@ -180,54 +134,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public virtual T[] Get(string field, string key)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
if ( m_FieldTypes.ContainsKey(field) )
|
||||
cmd.Parameters.Add(m_database.CreateParameter(field, key, m_FieldTypes[field]));
|
||||
else
|
||||
cmd.Parameters.Add(m_database.CreateParameter(field, key));
|
||||
|
||||
string query = String.Format("SELECT * FROM {0} WHERE \"{1}\" = :{1}", m_Realm, field, field);
|
||||
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T[] Get(string field, string[] keys)
|
||||
{
|
||||
|
||||
int flen = keys.Length;
|
||||
if(flen == 0)
|
||||
return new T[0];
|
||||
|
||||
int flast = flen - 1;
|
||||
StringBuilder sb = new StringBuilder(1024);
|
||||
sb.AppendFormat("select * from {0} where {1} IN ('", m_Realm, field);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
|
||||
for (int i = 0 ; i < flen ; i++)
|
||||
{
|
||||
sb.Append(keys[i]);
|
||||
if(i < flast)
|
||||
sb.Append("','");
|
||||
else
|
||||
sb.Append("')");
|
||||
}
|
||||
|
||||
string query = sb.ToString();
|
||||
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
return Get(new string[] { field }, new string[] { key });
|
||||
}
|
||||
|
||||
public virtual T[] Get(string[] fields, string[] keys)
|
||||
|
@ -237,18 +144,14 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
List<string> terms = new List<string>();
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
if ( m_FieldTypes.ContainsKey(fields[i]) )
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
|
||||
else
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
||||
|
||||
terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
|
||||
terms.Add("[" + fields[i] + "] = @" + fields[i]);
|
||||
}
|
||||
|
||||
string where = String.Join(" AND ", terms.ToArray());
|
||||
|
@ -263,18 +166,10 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
protected T[] DoQuery(NpgsqlCommand cmd)
|
||||
protected T[] DoQuery(SqlCommand cmd)
|
||||
{
|
||||
List<T> result = new List<T>();
|
||||
if (cmd.Connection == null)
|
||||
{
|
||||
cmd.Connection = new NpgsqlConnection(m_connectionString);
|
||||
}
|
||||
if (cmd.Connection.State == ConnectionState.Closed)
|
||||
{
|
||||
cmd.Connection.Open();
|
||||
}
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader == null)
|
||||
return new T[0];
|
||||
|
@ -318,7 +213,6 @@ namespace OpenSim.Data.PGSQL
|
|||
foreach (string col in m_ColumnNames)
|
||||
{
|
||||
data[col] = reader[col].ToString();
|
||||
|
||||
if (data[col] == null)
|
||||
data[col] = String.Empty;
|
||||
}
|
||||
|
@ -334,34 +228,16 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public virtual T[] Get(string where)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
string query = String.Format("SELECT * FROM {0} WHERE {1}",
|
||||
m_Realm, where);
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T[] Get(string where, NpgsqlParameter parameter)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
|
||||
string query = String.Format("SELECT * FROM {0} WHERE {1}",
|
||||
m_Realm, where);
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
cmd.Parameters.Add(parameter);
|
||||
//m_log.WarnFormat("[MSSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
|
@ -373,8 +249,8 @@ namespace OpenSim.Data.PGSQL
|
|||
List<string> constraintFields = GetConstraints();
|
||||
List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
StringBuilder query = new StringBuilder();
|
||||
|
@ -384,24 +260,21 @@ namespace OpenSim.Data.PGSQL
|
|||
foreach (FieldInfo fi in m_Fields.Values)
|
||||
{
|
||||
names.Add(fi.Name);
|
||||
values.Add(":" + fi.Name);
|
||||
values.Add("@" + fi.Name);
|
||||
// Temporarily return more information about what field is unexpectedly null for
|
||||
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
|
||||
// InventoryTransferModule or we may be required to substitute a DBNull here.
|
||||
if (fi.GetValue(row) == null)
|
||||
throw new NullReferenceException(
|
||||
string.Format(
|
||||
"[PGSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||
"[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||
fi.Name, row));
|
||||
|
||||
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
||||
{
|
||||
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
|
||||
}
|
||||
if (m_FieldTypes.ContainsKey(fi.Name))
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row), m_FieldTypes[fi.Name]));
|
||||
else
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row)));
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row).ToString()));
|
||||
}
|
||||
|
||||
if (m_DataField != null)
|
||||
|
@ -416,12 +289,8 @@ namespace OpenSim.Data.PGSQL
|
|||
constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
|
||||
}
|
||||
names.Add(kvp.Key);
|
||||
values.Add(":" + kvp.Key);
|
||||
|
||||
if (m_FieldTypes.ContainsKey(kvp.Key))
|
||||
cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value, m_FieldTypes[kvp.Key]));
|
||||
else
|
||||
cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value));
|
||||
values.Add("@" + kvp.Key);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@" + kvp.Key, kvp.Value));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -430,15 +299,15 @@ namespace OpenSim.Data.PGSQL
|
|||
int i = 0;
|
||||
for (i = 0; i < names.Count - 1; i++)
|
||||
{
|
||||
query.AppendFormat("\"{0}\" = {1}, ", names[i], values[i]);
|
||||
query.AppendFormat("[{0}] = {1}, ", names[i], values[i]);
|
||||
}
|
||||
query.AppendFormat("\"{0}\" = {1} ", names[i], values[i]);
|
||||
query.AppendFormat("[{0}] = {1} ", names[i], values[i]);
|
||||
if (constraints.Count > 0)
|
||||
{
|
||||
List<string> terms = new List<string>();
|
||||
for (int j = 0; j < constraints.Count; j++)
|
||||
{
|
||||
terms.Add(String.Format(" \"{0}\" = :{0}", constraints[j].Key));
|
||||
terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key);
|
||||
}
|
||||
string where = String.Join(" AND ", terms.ToArray());
|
||||
query.AppendFormat(" WHERE {0} ", where);
|
||||
|
@ -450,7 +319,7 @@ namespace OpenSim.Data.PGSQL
|
|||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
{
|
||||
//m_log.WarnFormat("[PGSQLGenericTable]: Updating {0}", m_Realm);
|
||||
//m_log.WarnFormat("[MSSQLGenericTable]: Updating {0}", m_Realm);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -458,14 +327,12 @@ namespace OpenSim.Data.PGSQL
|
|||
// assume record has not yet been inserted
|
||||
|
||||
query = new StringBuilder();
|
||||
query.AppendFormat("INSERT INTO {0} (\"", m_Realm);
|
||||
query.Append(String.Join("\",\"", names.ToArray()));
|
||||
query.Append("\") values (" + String.Join(",", values.ToArray()) + ")");
|
||||
query.AppendFormat("INSERT INTO {0} ([", m_Realm);
|
||||
query.Append(String.Join("],[", names.ToArray()));
|
||||
query.Append("]) values (" + String.Join(",", values.ToArray()) + ")");
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query.ToString();
|
||||
|
||||
// m_log.WarnFormat("[PGSQLGenericTable]: Inserting into {0} sql {1}", m_Realm, cmd.CommandText);
|
||||
|
||||
//m_log.WarnFormat("[MSSQLGenericTable]: Inserting into {0}", m_Realm);
|
||||
if (conn.State != ConnectionState.Open)
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
|
@ -488,17 +355,13 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
List<string> terms = new List<string>();
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
if (m_FieldTypes.ContainsKey(fields[i]))
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
|
||||
else
|
||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
||||
|
||||
terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
|
||||
terms.Add("[" + fields[i] + "] = @" + fields[i]);
|
||||
}
|
||||
|
||||
string where = String.Join(" AND ", terms.ToArray());
|
||||
|
@ -511,69 +374,11 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
{
|
||||
//m_log.Warn("[PGSQLGenericTable]: " + deleteCommand);
|
||||
//m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public long GetCount(string field, string key)
|
||||
{
|
||||
return GetCount(new string[] { field }, new string[] { key });
|
||||
}
|
||||
|
||||
public long GetCount(string[] fields, string[] keys)
|
||||
{
|
||||
if (fields.Length != keys.Length)
|
||||
return 0;
|
||||
|
||||
List<string> terms = new List<string>();
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
||||
terms.Add("\"" + fields[i] + "\" = :" + fields[i]);
|
||||
}
|
||||
|
||||
string where = String.Join(" and ", terms.ToArray());
|
||||
|
||||
string query = String.Format("select count(*) from {0} where {1}",
|
||||
m_Realm, where);
|
||||
|
||||
cmd.CommandText = query;
|
||||
|
||||
Object result = DoQueryScalar(cmd);
|
||||
|
||||
return Convert.ToInt64(result);
|
||||
}
|
||||
}
|
||||
|
||||
public long GetCount(string where)
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
string query = String.Format("select count(*) from {0} where {1}",
|
||||
m_Realm, where);
|
||||
|
||||
cmd.CommandText = query;
|
||||
|
||||
object result = DoQueryScalar(cmd);
|
||||
|
||||
return Convert.ToInt64(result);
|
||||
}
|
||||
}
|
||||
|
||||
public object DoQueryScalar(NpgsqlCommand cmd)
|
||||
{
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_ConnectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
return cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,18 +33,19 @@ using System.Threading;
|
|||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A PGSQL Interface for Avatar Storage
|
||||
/// A MSSQL Interface for Avatar Storage
|
||||
/// </summary>
|
||||
public class PGSQLGridUserData : PGSQLGenericTableHandler<GridUserData>,
|
||||
public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
|
||||
IGridUserData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public PGSQLGridUserData(string connectionString, string realm) :
|
||||
public MSSQLGridUserData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "GridUserStore")
|
||||
{
|
||||
}
|
||||
|
@ -61,7 +62,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("\"UserID\" LIKE '{0}%'", userID));
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
|
||||
}
|
|
@ -28,18 +28,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using Npgsql;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A PGSQL interface for the inventory server
|
||||
/// A MSSQL interface for the inventory server
|
||||
/// </summary>
|
||||
public class PGSQLInventoryData : IInventoryDataPlugin
|
||||
public class MSSQLInventoryData : IInventoryDataPlugin
|
||||
{
|
||||
private const string _migrationStore = "InventoryStore";
|
||||
|
||||
|
@ -48,7 +48,7 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <summary>
|
||||
/// The database manager
|
||||
/// </summary>
|
||||
private PGSQLManager database;
|
||||
private MSSQLManager database;
|
||||
private string m_connectionString;
|
||||
|
||||
#region IPlugin members
|
||||
|
@ -56,19 +56,19 @@ namespace OpenSim.Data.PGSQL
|
|||
[Obsolete("Cannot be default-initialized!")]
|
||||
public void Initialise()
|
||||
{
|
||||
m_log.Info("[PGSQLInventoryData]: " + Name + " cannot be default-initialized!");
|
||||
m_log.Info("[MSSQLInventoryData]: " + Name + " cannot be default-initialized!");
|
||||
throw new PluginNotInitialisedException(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads and initialises the PGSQL inventory storage interface
|
||||
/// Loads and initialises the MSSQL inventory storage interface
|
||||
/// </summary>
|
||||
/// <param name="connectionString">connect string</param>
|
||||
/// <remarks>use PGSQL_connection.ini</remarks>
|
||||
/// <remarks>use mssql_connection.ini</remarks>
|
||||
public void Initialise(string connectionString)
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
database = new PGSQLManager(connectionString);
|
||||
database = new MSSQLManager(connectionString);
|
||||
|
||||
//New migrations check of store
|
||||
database.CheckMigration(_migrationStore);
|
||||
|
@ -80,7 +80,7 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns>A string containing the name of the DB provider</returns>
|
||||
public string Name
|
||||
{
|
||||
get { return "PGSQL Inventory Data Interface"; }
|
||||
get { return "MSSQL Inventory Data Interface"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -158,13 +158,13 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns>A folder class</returns>
|
||||
public InventoryFolderBase getInventoryFolder(UUID folderID)
|
||||
{
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE \"folderID\" = :folderID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE folderID = @folderID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -200,11 +200,11 @@ namespace OpenSim.Data.PGSQL
|
|||
if (parentID == UUID.Zero)
|
||||
return folders;
|
||||
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE \"parentFolderID\" = :parentID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("parentID", parentID));
|
||||
cmd.Parameters.Add(database.CreateParameter("@parentID", parentID));
|
||||
conn.Open();
|
||||
folders.AddRange(getInventoryFolders(cmd));
|
||||
|
||||
|
@ -228,8 +228,8 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="folder">Folder to create</param>
|
||||
public void addInventoryFolder(InventoryFolderBase folder)
|
||||
{
|
||||
string sql = "INSERT INTO inventoryfolders (\"folderID\", \"agentID\", \"parentFolderID\", \"folderName\", type, version) " +
|
||||
" VALUES (:folderID, :agentID, :parentFolderID, :folderName, :type, :version);";
|
||||
string sql = @"INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version])
|
||||
VALUES (@folderID, @agentID, @parentFolderID, @folderName, @type, @version);";
|
||||
|
||||
string folderName = folder.Name;
|
||||
if (folderName.Length > 64)
|
||||
|
@ -237,8 +237,8 @@ namespace OpenSim.Data.PGSQL
|
|||
folderName = folderName.Substring(0, 64);
|
||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add");
|
||||
}
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
||||
|
@ -264,12 +264,12 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="folder">Folder to update</param>
|
||||
public void updateInventoryFolder(InventoryFolderBase folder)
|
||||
{
|
||||
string sql = @"UPDATE inventoryfolders SET ""agentID"" = :agentID,
|
||||
""parentFolderID"" = :parentFolderID,
|
||||
""folderName"" = :folderName,
|
||||
type = :type,
|
||||
version = :version
|
||||
WHERE folderID = :folderID";
|
||||
string sql = @"UPDATE inventoryfolders SET agentID = @agentID,
|
||||
parentFolderID = @parentFolderID,
|
||||
folderName = @folderName,
|
||||
type = @type,
|
||||
version = @version
|
||||
WHERE folderID = @folderID";
|
||||
|
||||
string folderName = folder.Name;
|
||||
if (folderName.Length > 64)
|
||||
|
@ -277,8 +277,8 @@ namespace OpenSim.Data.PGSQL
|
|||
folderName = folderName.Substring(0, 64);
|
||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update");
|
||||
}
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
||||
|
@ -304,9 +304,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="folder">Folder to update</param>
|
||||
public void moveInventoryFolder(InventoryFolderBase folder)
|
||||
{
|
||||
string sql = @"UPDATE inventoryfolders SET ""parentFolderID"" = :parentFolderID WHERE ""folderID"" = :folderID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = @"UPDATE inventoryfolders SET parentFolderID = @parentFolderID WHERE folderID = @folderID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
|
||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||
|
@ -328,13 +328,13 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="folderID">Id of folder to delete</param>
|
||||
public void deleteInventoryFolder(UUID folderID)
|
||||
{
|
||||
string sql = @"SELECT * FROM inventoryfolders WHERE ""parentFolderID"" = :parentID";
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
List<InventoryFolderBase> subFolders;
|
||||
cmd.Parameters.Add(database.CreateParameter("parentID", UUID.Zero));
|
||||
cmd.Parameters.Add(database.CreateParameter("@parentID", UUID.Zero));
|
||||
conn.Open();
|
||||
subFolders = getFolderHierarchy(folderID, cmd);
|
||||
|
||||
|
@ -363,15 +363,15 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns>A list containing inventory items</returns>
|
||||
public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
|
||||
{
|
||||
string sql = @"SELECT * FROM inventoryitems WHERE ""parentFolderID"" = :parentFolderID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
|
||||
conn.Open();
|
||||
List<InventoryItemBase> items = new List<InventoryItemBase>();
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -389,13 +389,13 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns>An inventory item</returns>
|
||||
public InventoryItemBase getInventoryItem(UUID itemID)
|
||||
{
|
||||
string sql = @"SELECT * FROM inventoryitems WHERE ""inventoryID"" = :inventoryID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -421,15 +421,15 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
|
||||
string sql = @"INSERT INTO inventoryitems
|
||||
(""inventoryID"", ""assetID"", ""assetType"", ""parentFolderID"", ""avatarID"", ""inventoryName"",
|
||||
""inventoryDescription"", ""inventoryNextPermissions"", ""inventoryCurrentPermissions"",
|
||||
""invType"", ""creatorID"", ""inventoryBasePermissions"", ""inventoryEveryOnePermissions"", ""inventoryGroupPermissions"",
|
||||
""salePrice"", ""SaleType"", ""creationDate"", ""groupID"", ""groupOwned"", flags)
|
||||
([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName],
|
||||
[inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions],
|
||||
[invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions], [inventoryGroupPermissions],
|
||||
[salePrice], [saleType], [creationDate], [groupID], [groupOwned], [flags])
|
||||
VALUES
|
||||
(:inventoryID, :assetID, :assetType, :parentFolderID, :avatarID, :inventoryName, :inventoryDescription,
|
||||
:inventoryNextPermissions, :inventoryCurrentPermissions, :invType, :creatorID,
|
||||
:inventoryBasePermissions, :inventoryEveryOnePermissions, :inventoryGroupPermissions, :SalePrice, :SaleType,
|
||||
:creationDate, :groupID, :groupOwned, :flags)";
|
||||
(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription,
|
||||
@inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID,
|
||||
@inventoryBasePermissions, @inventoryEveryOnePermissions, @inventoryGroupPermissions, @salePrice, @saleType,
|
||||
@creationDate, @groupID, @groupOwned, @flags)";
|
||||
|
||||
string itemName = item.Name;
|
||||
if (item.Name.Length > 64)
|
||||
|
@ -445,8 +445,8 @@ namespace OpenSim.Data.PGSQL
|
|||
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters");
|
||||
}
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
||||
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
||||
|
@ -462,8 +462,8 @@ namespace OpenSim.Data.PGSQL
|
|||
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
||||
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
||||
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
||||
command.Parameters.Add(database.CreateParameter("SalePrice", item.SalePrice));
|
||||
command.Parameters.Add(database.CreateParameter("SaleType", item.SaleType));
|
||||
command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
|
||||
command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
|
||||
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
||||
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
||||
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
||||
|
@ -479,9 +479,9 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
sql = @"UPDATE inventoryfolders SET version = version + 1 WHERE ""folderID"" = @folderID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
||||
sql = "UPDATE inventoryfolders SET version = version + 1 WHERE folderID = @folderID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString()));
|
||||
conn.Open();
|
||||
|
@ -502,26 +502,26 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="item">Inventory item to update</param>
|
||||
public void updateInventoryItem(InventoryItemBase item)
|
||||
{
|
||||
string sql = @"UPDATE inventoryitems SET ""assetID"" = :assetID,
|
||||
""assetType"" = :assetType,
|
||||
""parentFolderID"" = :parentFolderID,
|
||||
""avatarID"" = :avatarID,
|
||||
""inventoryName"" = :inventoryName,
|
||||
""inventoryDescription"" = :inventoryDescription,
|
||||
""inventoryNextPermissions"" = :inventoryNextPermissions,
|
||||
""inventoryCurrentPermissions"" = :inventoryCurrentPermissions,
|
||||
""invType"" = :invType,
|
||||
""creatorID"" = :creatorID,
|
||||
""inventoryBasePermissions"" = :inventoryBasePermissions,
|
||||
""inventoryEveryOnePermissions"" = :inventoryEveryOnePermissions,
|
||||
""inventoryGroupPermissions"" = :inventoryGroupPermissions,
|
||||
""salePrice"" = :SalePrice,
|
||||
""saleType"" = :SaleType,
|
||||
""creationDate"" = :creationDate,
|
||||
""groupID"" = :groupID,
|
||||
""groupOwned"" = :groupOwned,
|
||||
flags = :flags
|
||||
WHERE ""inventoryID"" = :inventoryID";
|
||||
string sql = @"UPDATE inventoryitems SET assetID = @assetID,
|
||||
assetType = @assetType,
|
||||
parentFolderID = @parentFolderID,
|
||||
avatarID = @avatarID,
|
||||
inventoryName = @inventoryName,
|
||||
inventoryDescription = @inventoryDescription,
|
||||
inventoryNextPermissions = @inventoryNextPermissions,
|
||||
inventoryCurrentPermissions = @inventoryCurrentPermissions,
|
||||
invType = @invType,
|
||||
creatorID = @creatorID,
|
||||
inventoryBasePermissions = @inventoryBasePermissions,
|
||||
inventoryEveryOnePermissions = @inventoryEveryOnePermissions,
|
||||
inventoryGroupPermissions = @inventoryGroupPermissions,
|
||||
salePrice = @salePrice,
|
||||
saleType = @saleType,
|
||||
creationDate = @creationDate,
|
||||
groupID = @groupID,
|
||||
groupOwned = @groupOwned,
|
||||
flags = @flags
|
||||
WHERE inventoryID = @inventoryID";
|
||||
|
||||
string itemName = item.Name;
|
||||
if (item.Name.Length > 64)
|
||||
|
@ -537,8 +537,8 @@ namespace OpenSim.Data.PGSQL
|
|||
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update");
|
||||
}
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
||||
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
||||
|
@ -554,8 +554,8 @@ namespace OpenSim.Data.PGSQL
|
|||
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
||||
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
||||
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
||||
command.Parameters.Add(database.CreateParameter("SalePrice", item.SalePrice));
|
||||
command.Parameters.Add(database.CreateParameter("SaleType", item.SaleType));
|
||||
command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
|
||||
command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
|
||||
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
||||
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
||||
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
||||
|
@ -580,9 +580,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="itemID">the item UUID</param>
|
||||
public void deleteInventoryItem(UUID itemID)
|
||||
{
|
||||
string sql = @"DELETE FROM inventoryitems WHERE ""inventoryID""=:inventoryID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "DELETE FROM inventoryitems WHERE inventoryID=@inventoryID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
||||
try
|
||||
|
@ -616,14 +616,14 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </returns>
|
||||
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
|
||||
{
|
||||
string sql = @"SELECT * FROM inventoryitems WHERE ""avatarID"" = :uuid AND ""assetType"" = :assetType and flags = 1";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(database.CreateParameter("uuid", avatarID));
|
||||
cmd.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
|
||||
while (reader.Read())
|
||||
|
@ -644,9 +644,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </summary>
|
||||
/// <param name="folderID">the item ID</param>
|
||||
/// <param name="connection">connection to the database</param>
|
||||
private void DeleteItemsInFolder(UUID folderID, NpgsqlConnection connection)
|
||||
private void DeleteItemsInFolder(UUID folderID, SqlConnection connection)
|
||||
{
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(@"DELETE FROM inventoryitems WHERE ""folderID""=:folderID", connection))
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryitems WHERE folderID=@folderID", connection))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||
|
||||
|
@ -667,9 +667,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="parentID">parent ID.</param>
|
||||
/// <param name="command">SQL command/connection to database</param>
|
||||
/// <returns></returns>
|
||||
private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, NpgsqlCommand command)
|
||||
private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, SqlCommand command)
|
||||
{
|
||||
command.Parameters["parentID"].Value = parentID.Guid; //.ToString();
|
||||
command.Parameters["@parentID"].Value = parentID.Guid; //.ToString();
|
||||
|
||||
List<InventoryFolderBase> folders = getInventoryFolders(command);
|
||||
|
||||
|
@ -698,9 +698,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <returns></returns>
|
||||
private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
|
||||
{
|
||||
string sql = @"SELECT * FROM inventoryfolders WHERE ""parentFolderID"" = :parentID AND ""agentID"" = :uuid";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
||||
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (user == UUID.Zero)
|
||||
{
|
||||
|
@ -721,9 +721,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </summary>
|
||||
/// <param name="command">SQLcommand.</param>
|
||||
/// <returns></returns>
|
||||
private static List<InventoryFolderBase> getInventoryFolders(NpgsqlCommand command)
|
||||
private static List<InventoryFolderBase> getInventoryFolders(SqlCommand command)
|
||||
{
|
||||
using (NpgsqlDataReader reader = command.ExecuteReader())
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
|
||||
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
|
||||
|
@ -738,9 +738,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <summary>
|
||||
/// Reads a list of inventory folders returned by a query.
|
||||
/// </summary>
|
||||
/// <param name="reader">A PGSQL Data Reader</param>
|
||||
/// <param name="reader">A MSSQL Data Reader</param>
|
||||
/// <returns>A List containing inventory folders</returns>
|
||||
protected static InventoryFolderBase readInventoryFolder(NpgsqlDataReader reader)
|
||||
protected static InventoryFolderBase readInventoryFolder(SqlDataReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -796,7 +796,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
return item;
|
||||
}
|
||||
catch (NpgsqlException e)
|
||||
catch (SqlException e)
|
||||
{
|
||||
m_log.Error("[INVENTORY DB]: Error reading inventory item :" + e.Message);
|
||||
}
|
||||
|
@ -809,18 +809,18 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </summary>
|
||||
/// <param name="folderID">the folder UUID</param>
|
||||
/// <param name="connection">connection to database</param>
|
||||
private void DeleteOneFolder(UUID folderID, NpgsqlConnection connection)
|
||||
private void DeleteOneFolder(UUID folderID, SqlConnection connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (NpgsqlCommand command = new NpgsqlCommand(@"DELETE FROM inventoryfolders WHERE ""folderID""=:folderID and type=-1", connection))
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (NpgsqlException e)
|
||||
catch (SqlException e)
|
||||
{
|
||||
m_log.Error("[INVENTORY DB]: Error deleting folder :" + e.Message);
|
||||
}
|
|
@ -28,20 +28,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using OpenSim.Framework;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A management class for the MS SQL Storage Engine
|
||||
/// </summary>
|
||||
public class PGSQLManager
|
||||
public class MSSQLManager
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
|
@ -54,37 +52,9 @@ namespace OpenSim.Data.PGSQL
|
|||
/// Initialize the manager and set the connectionstring
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
public PGSQLManager(string connection)
|
||||
public MSSQLManager(string connection)
|
||||
{
|
||||
connectionString = connection;
|
||||
InitializeMonoSecurity();
|
||||
}
|
||||
|
||||
public void InitializeMonoSecurity()
|
||||
{
|
||||
if (!Util.IsPlatformMono)
|
||||
{
|
||||
if (AppDomain.CurrentDomain.GetData("MonoSecurityPostgresAdded") == null)
|
||||
{
|
||||
AppDomain.CurrentDomain.SetData("MonoSecurityPostgresAdded", "true");
|
||||
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandlerMonoSec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private System.Reflection.Assembly ResolveEventHandlerMonoSec(object sender, ResolveEventArgs args)
|
||||
{
|
||||
Assembly MyAssembly = null;
|
||||
|
||||
if (args.Name.Substring(0, args.Name.IndexOf(",")) == "Mono.Security")
|
||||
{
|
||||
MyAssembly = Assembly.LoadFrom("lib/NET/Mono.Security.dll");
|
||||
}
|
||||
|
||||
//Return the loaded assembly.
|
||||
return MyAssembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -92,97 +62,54 @@ namespace OpenSim.Data.PGSQL
|
|||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
internal NpgsqlDbType DbtypeFromType(Type type)
|
||||
internal SqlDbType DbtypeFromType(Type type)
|
||||
{
|
||||
if (type == typeof(string))
|
||||
{
|
||||
return NpgsqlDbType.Varchar;
|
||||
return SqlDbType.VarChar;
|
||||
}
|
||||
if (type == typeof(double))
|
||||
{
|
||||
return NpgsqlDbType.Double;
|
||||
return SqlDbType.Float;
|
||||
}
|
||||
if (type == typeof(Single))
|
||||
{
|
||||
return NpgsqlDbType.Double;
|
||||
return SqlDbType.Float;
|
||||
}
|
||||
if (type == typeof(int))
|
||||
{
|
||||
return NpgsqlDbType.Integer;
|
||||
return SqlDbType.Int;
|
||||
}
|
||||
if (type == typeof(bool))
|
||||
{
|
||||
return NpgsqlDbType.Boolean;
|
||||
return SqlDbType.Bit;
|
||||
}
|
||||
if (type == typeof(UUID))
|
||||
{
|
||||
return NpgsqlDbType.Uuid;
|
||||
}
|
||||
if (type == typeof(byte))
|
||||
{
|
||||
return NpgsqlDbType.Smallint;
|
||||
return SqlDbType.UniqueIdentifier;
|
||||
}
|
||||
if (type == typeof(sbyte))
|
||||
{
|
||||
return NpgsqlDbType.Integer;
|
||||
return SqlDbType.Int;
|
||||
}
|
||||
if (type == typeof(Byte[]))
|
||||
{
|
||||
return NpgsqlDbType.Bytea;
|
||||
return SqlDbType.Image;
|
||||
}
|
||||
if (type == typeof(uint) || type == typeof(ushort))
|
||||
{
|
||||
return NpgsqlDbType.Integer;
|
||||
return SqlDbType.Int;
|
||||
}
|
||||
if (type == typeof(ulong))
|
||||
{
|
||||
return NpgsqlDbType.Bigint;
|
||||
return SqlDbType.BigInt;
|
||||
}
|
||||
if (type == typeof(DateTime))
|
||||
{
|
||||
return NpgsqlDbType.Timestamp;
|
||||
return SqlDbType.DateTime;
|
||||
}
|
||||
|
||||
return NpgsqlDbType.Varchar;
|
||||
}
|
||||
|
||||
internal NpgsqlDbType DbtypeFromString(Type type, string PGFieldType)
|
||||
{
|
||||
if (PGFieldType == "")
|
||||
{
|
||||
return DbtypeFromType(type);
|
||||
}
|
||||
|
||||
if (PGFieldType == "character varying")
|
||||
{
|
||||
return NpgsqlDbType.Varchar;
|
||||
}
|
||||
if (PGFieldType == "double precision")
|
||||
{
|
||||
return NpgsqlDbType.Double;
|
||||
}
|
||||
if (PGFieldType == "integer")
|
||||
{
|
||||
return NpgsqlDbType.Integer;
|
||||
}
|
||||
if (PGFieldType == "smallint")
|
||||
{
|
||||
return NpgsqlDbType.Smallint;
|
||||
}
|
||||
if (PGFieldType == "boolean")
|
||||
{
|
||||
return NpgsqlDbType.Boolean;
|
||||
}
|
||||
if (PGFieldType == "uuid")
|
||||
{
|
||||
return NpgsqlDbType.Uuid;
|
||||
}
|
||||
if (PGFieldType == "bytea")
|
||||
{
|
||||
return NpgsqlDbType.Bytea;
|
||||
}
|
||||
|
||||
return DbtypeFromType(type);
|
||||
return SqlDbType.VarChar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -204,7 +131,7 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
if (valueType == typeof(bool))
|
||||
{
|
||||
return (bool)value;
|
||||
return (bool)value ? 1 : 0;
|
||||
}
|
||||
if (valueType == typeof(Byte[]))
|
||||
{
|
||||
|
@ -217,52 +144,13 @@ namespace OpenSim.Data.PGSQL
|
|||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create value for parameter based on PGSQL Schema
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="PGFieldType"></param>
|
||||
/// <returns></returns>
|
||||
internal static object CreateParameterValue(object value, string PGFieldType)
|
||||
{
|
||||
if (PGFieldType == "uuid")
|
||||
{
|
||||
UUID uidout;
|
||||
UUID.TryParse(value.ToString(), out uidout);
|
||||
return uidout;
|
||||
}
|
||||
if (PGFieldType == "integer")
|
||||
{
|
||||
int intout;
|
||||
int.TryParse(value.ToString(), out intout);
|
||||
return intout;
|
||||
}
|
||||
if (PGFieldType == "boolean")
|
||||
{
|
||||
return (value.ToString() == "true");
|
||||
}
|
||||
if (PGFieldType == "timestamp with time zone")
|
||||
{
|
||||
return (DateTime)value;
|
||||
}
|
||||
if (PGFieldType == "timestamp without time zone")
|
||||
{
|
||||
return (DateTime)value;
|
||||
}
|
||||
if (PGFieldType == "double precision")
|
||||
{
|
||||
return Convert.ToDouble(value);
|
||||
}
|
||||
return CreateParameterValue(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a parameter for a command
|
||||
/// </summary>
|
||||
/// <param name="parameterName">Name of the parameter.</param>
|
||||
/// <param name="parameterObject">parameter object.</param>
|
||||
/// <returns></returns>
|
||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject)
|
||||
internal SqlParameter CreateParameter(string parameterName, object parameterObject)
|
||||
{
|
||||
return CreateParameter(parameterName, parameterObject, false);
|
||||
}
|
||||
|
@ -274,15 +162,15 @@ namespace OpenSim.Data.PGSQL
|
|||
/// <param name="parameterObject">parameter object.</param>
|
||||
/// <param name="parameterOut">if set to <c>true</c> parameter is a output parameter</param>
|
||||
/// <returns></returns>
|
||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut)
|
||||
internal SqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut)
|
||||
{
|
||||
//Tweak so we dont always have to add : sign
|
||||
if (parameterName.StartsWith(":")) parameterName = parameterName.Replace(":","");
|
||||
//Tweak so we dont always have to add @ sign
|
||||
if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName;
|
||||
|
||||
//HACK if object is null, it is turned into a string, there are no nullable type till now
|
||||
if (parameterObject == null) parameterObject = "";
|
||||
|
||||
NpgsqlParameter parameter = new NpgsqlParameter(parameterName, DbtypeFromType(parameterObject.GetType()));
|
||||
SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType()));
|
||||
|
||||
if (parameterOut)
|
||||
{
|
||||
|
@ -297,40 +185,17 @@ namespace OpenSim.Data.PGSQL
|
|||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a parameter with PGSQL schema type
|
||||
/// </summary>
|
||||
/// <param name="parameterName"></param>
|
||||
/// <param name="parameterObject"></param>
|
||||
/// <param name="PGFieldType"></param>
|
||||
/// <returns></returns>
|
||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject, string PGFieldType)
|
||||
{
|
||||
//Tweak so we dont always have to add : sign
|
||||
if (parameterName.StartsWith(":")) parameterName = parameterName.Replace(":", "");
|
||||
|
||||
//HACK if object is null, it is turned into a string, there are no nullable type till now
|
||||
if (parameterObject == null) parameterObject = "";
|
||||
|
||||
NpgsqlParameter parameter = new NpgsqlParameter(parameterName, DbtypeFromString(parameterObject.GetType(), PGFieldType));
|
||||
|
||||
parameter.Direction = ParameterDirection.Input;
|
||||
parameter.Value = CreateParameterValue(parameterObject, PGFieldType);
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if we need to do some migrations to the database
|
||||
/// </summary>
|
||||
/// <param name="migrationStore">migrationStore.</param>
|
||||
public void CheckMigration(string migrationStore)
|
||||
{
|
||||
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
|
||||
using (SqlConnection connection = new SqlConnection(connectionString))
|
||||
{
|
||||
connection.Open();
|
||||
Assembly assem = GetType().Assembly;
|
||||
PGSQLMigration migration = new PGSQLMigration(connection, assem, migrationStore);
|
||||
MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore);
|
||||
|
||||
migration.Update();
|
||||
}
|
|
@ -25,22 +25,22 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using Npgsql;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Reflection;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLMigration : Migration
|
||||
public class MSSQLMigration : Migration
|
||||
{
|
||||
public PGSQLMigration(NpgsqlConnection conn, Assembly assem, string type)
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string type)
|
||||
: base(conn, assem, type)
|
||||
{
|
||||
}
|
||||
|
||||
public PGSQLMigration(NpgsqlConnection conn, Assembly assem, string subtype, string type)
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
|
||||
: base(conn, assem, subtype, type)
|
||||
{
|
||||
}
|
||||
|
@ -48,15 +48,12 @@ namespace OpenSim.Data.PGSQL
|
|||
protected override int FindVersion(DbConnection conn, string type)
|
||||
{
|
||||
int version = 0;
|
||||
NpgsqlConnection lcConn = (NpgsqlConnection)conn;
|
||||
|
||||
using (NpgsqlCommand cmd = lcConn.CreateCommand())
|
||||
using (DbCommand cmd = conn.CreateCommand())
|
||||
{
|
||||
try
|
||||
{
|
||||
cmd.CommandText = "select version from migrations where name = '" + type + "' " +
|
||||
" order by version desc limit 1"; //Must be
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
cmd.CommandText = "select top 1 version from migrations where name = '" + type + "' order by version desc"; //Must be
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
|
@ -76,7 +73,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
protected override void ExecuteScript(DbConnection conn, string[] script)
|
||||
{
|
||||
if (!(conn is NpgsqlConnection))
|
||||
if (!(conn is SqlConnection))
|
||||
{
|
||||
base.ExecuteScript(conn, script);
|
||||
return;
|
||||
|
@ -86,7 +83,7 @@ namespace OpenSim.Data.PGSQL
|
|||
{
|
||||
try
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, (NpgsqlConnection)conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
39
OpenSim/Data/PGSQL/PGSQLPresenceData.cs → OpenSim/Data/MSSQL/MSSQLPresenceData.cs
Executable file → Normal file
39
OpenSim/Data/PGSQL/PGSQLPresenceData.cs → OpenSim/Data/MSSQL/MSSQLPresenceData.cs
Executable file → Normal file
|
@ -33,26 +33,27 @@ using System.Threading;
|
|||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using Npgsql;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A PGSQL Interface for the Presence Server
|
||||
/// A MySQL Interface for the Presence Server
|
||||
/// </summary>
|
||||
public class PGSQLPresenceData : PGSQLGenericTableHandler<PresenceData>,
|
||||
public class MSSQLPresenceData : MSSQLGenericTableHandler<PresenceData>,
|
||||
IPresenceData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public PGSQLPresenceData(string connectionString, string realm) :
|
||||
public MSSQLPresenceData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "Presence")
|
||||
{
|
||||
}
|
||||
|
||||
public PresenceData Get(UUID sessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SessionID", sessionID.ToString());
|
||||
PresenceData[] ret = Get("SessionID",
|
||||
sessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return null;
|
||||
|
@ -62,13 +63,13 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public void LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format("DELETE FROM {0} WHERE \"RegionID\" = :regionID", m_Realm);
|
||||
cmd.CommandText = String.Format("DELETE FROM {0} WHERE [RegionID]=@RegionID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("RegionID", regionID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
|
@ -81,17 +82,16 @@ namespace OpenSim.Data.PGSQL
|
|||
if (pd.Length == 0)
|
||||
return false;
|
||||
|
||||
if (regionID == UUID.Zero)
|
||||
return false;
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format("UPDATE {0} SET \"RegionID\" = :regionID, \"LastSeen\" = now() WHERE \"SessionID\" = :sessionID", m_Realm);
|
||||
cmd.CommandText = String.Format(@"UPDATE {0} SET
|
||||
[RegionID] = @RegionID
|
||||
WHERE [SessionID] = @SessionID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SessionID", sessionID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("RegionID", regionID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@SessionID", sessionID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() == 0)
|
||||
|
@ -102,7 +102,8 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public bool VerifyAgent(UUID agentId, UUID secureSessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SecureSessionID", secureSessionID.ToString());
|
||||
PresenceData[] ret = Get("SecureSessionID",
|
||||
secureSessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return false;
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using RegionFlags = OpenSim.Framework.RegionFlags;
|
||||
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A MSSQL Interface for the Region Server.
|
||||
/// </summary>
|
||||
public class MSSQLRegionData : IRegionData
|
||||
{
|
||||
private string m_Realm;
|
||||
private List<string> m_ColumnNames = null;
|
||||
private string m_ConnectionString;
|
||||
private MSSQLManager m_database;
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MSSQLRegionData(string connectionString, string realm)
|
||||
{
|
||||
m_Realm = realm;
|
||||
m_ConnectionString = connectionString;
|
||||
m_database = new MSSQLManager(connectionString);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, "GridStore");
|
||||
m.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public List<RegionData> Get(string regionName, UUID scopeID)
|
||||
{
|
||||
string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
sql += " order by regionName";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@regionName", regionName));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
conn.Open();
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public RegionData Get(int posX, int posY, UUID scopeID)
|
||||
{
|
||||
string sql = "select * from ["+m_Realm+"] where locX = @posX and locY = @posY";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@posX", posX.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@posY", posY.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
conn.Open();
|
||||
List<RegionData> ret = RunCommand(cmd);
|
||||
if (ret.Count == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
}
|
||||
|
||||
public RegionData Get(UUID regionID, UUID scopeID)
|
||||
{
|
||||
string sql = "select * from ["+m_Realm+"] where uuid = @regionID";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@regionID", regionID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
conn.Open();
|
||||
List<RegionData> ret = RunCommand(cmd);
|
||||
if (ret.Count == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
}
|
||||
|
||||
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
|
||||
{
|
||||
string sql = "select * from ["+m_Realm+"] where locX between @startX and @endX and locY between @startY and @endY";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@startX", startX));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@startY", startY));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@endX", endX));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@endY", endY));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
conn.Open();
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public List<RegionData> RunCommand(SqlCommand cmd)
|
||||
{
|
||||
List<RegionData> retList = new List<RegionData>();
|
||||
|
||||
SqlDataReader result = cmd.ExecuteReader();
|
||||
|
||||
while (result.Read())
|
||||
{
|
||||
RegionData ret = new RegionData();
|
||||
ret.Data = new Dictionary<string, object>();
|
||||
|
||||
UUID regionID;
|
||||
UUID.TryParse(result["uuid"].ToString(), out regionID);
|
||||
ret.RegionID = regionID;
|
||||
UUID scope;
|
||||
UUID.TryParse(result["ScopeID"].ToString(), out scope);
|
||||
ret.ScopeID = scope;
|
||||
ret.RegionName = result["regionName"].ToString();
|
||||
ret.posX = Convert.ToInt32(result["locX"]);
|
||||
ret.posY = Convert.ToInt32(result["locY"]);
|
||||
ret.sizeX = Convert.ToInt32(result["sizeX"]);
|
||||
ret.sizeY = Convert.ToInt32(result["sizeY"]);
|
||||
|
||||
if (m_ColumnNames == null)
|
||||
{
|
||||
m_ColumnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = result.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
||||
}
|
||||
|
||||
foreach (string s in m_ColumnNames)
|
||||
{
|
||||
if (s == "uuid")
|
||||
continue;
|
||||
if (s == "ScopeID")
|
||||
continue;
|
||||
if (s == "regionName")
|
||||
continue;
|
||||
if (s == "locX")
|
||||
continue;
|
||||
if (s == "locY")
|
||||
continue;
|
||||
|
||||
ret.Data[s] = result[s].ToString();
|
||||
}
|
||||
|
||||
retList.Add(ret);
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
|
||||
public bool Store(RegionData data)
|
||||
{
|
||||
if (data.Data.ContainsKey("uuid"))
|
||||
data.Data.Remove("uuid");
|
||||
if (data.Data.ContainsKey("ScopeID"))
|
||||
data.Data.Remove("ScopeID");
|
||||
if (data.Data.ContainsKey("regionName"))
|
||||
data.Data.Remove("regionName");
|
||||
if (data.Data.ContainsKey("posX"))
|
||||
data.Data.Remove("posX");
|
||||
if (data.Data.ContainsKey("posY"))
|
||||
data.Data.Remove("posY");
|
||||
if (data.Data.ContainsKey("sizeX"))
|
||||
data.Data.Remove("sizeX");
|
||||
if (data.Data.ContainsKey("sizeY"))
|
||||
data.Data.Remove("sizeY");
|
||||
if (data.Data.ContainsKey("locX"))
|
||||
data.Data.Remove("locX");
|
||||
if (data.Data.ContainsKey("locY"))
|
||||
data.Data.Remove("locY");
|
||||
|
||||
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
string update = "update [" + m_Realm + "] set locX=@posX, locY=@posY, sizeX=@sizeX, sizeY=@sizeY ";
|
||||
|
||||
foreach (string field in fields)
|
||||
{
|
||||
|
||||
update += ", ";
|
||||
update += "[" + field + "] = @" + field;
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
|
||||
}
|
||||
|
||||
update += " where uuid = @regionID";
|
||||
|
||||
if (data.ScopeID != UUID.Zero)
|
||||
update += " and ScopeID = @scopeID";
|
||||
|
||||
cmd.CommandText = update;
|
||||
cmd.Connection = conn;
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@regionID", data.RegionID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@regionName", data.RegionName));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@posX", data.posX));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@posY", data.posY));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@sizeX", data.sizeX));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@sizeY", data.sizeY));
|
||||
conn.Open();
|
||||
try
|
||||
{
|
||||
if (cmd.ExecuteNonQuery() < 1)
|
||||
{
|
||||
string insert = "insert into [" + m_Realm + "] ([uuid], [ScopeID], [locX], [locY], [sizeX], [sizeY], [regionName], [" +
|
||||
String.Join("], [", fields) +
|
||||
"]) values (@regionID, @scopeID, @posX, @posY, @sizeX, @sizeY, @regionName, @" + String.Join(", @", fields) + ")";
|
||||
|
||||
cmd.CommandText = insert;
|
||||
|
||||
try
|
||||
{
|
||||
if (cmd.ExecuteNonQuery() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Warn("[MSSQL Grid]: Error inserting into Regions table: " + ex.Message + ", INSERT sql: " + insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Warn("[MSSQL Grid]: Error updating Regions table: " + ex.Message + ", UPDATE sql: " + update);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetDataItem(UUID regionID, string item, string value)
|
||||
{
|
||||
string sql = "update [" + m_Realm +
|
||||
"] set [" + item + "] = @" + item + " where uuid = @UUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID));
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Delete(UUID regionID)
|
||||
{
|
||||
string sql = "delete from [" + m_Realm +
|
||||
"] where uuid = @UUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID));
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<RegionData> GetDefaultRegions(UUID scopeID)
|
||||
{
|
||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||
}
|
||||
|
||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||
{
|
||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||
RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y);
|
||||
regions.Sort(distanceComparer);
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
||||
public List<RegionData> GetHyperlinks(UUID scopeID)
|
||||
{
|
||||
return Get((int)RegionFlags.Hyperlink, scopeID);
|
||||
}
|
||||
|
||||
private List<RegionData> Get(int regionFlags, UUID scopeID)
|
||||
{
|
||||
string sql = "SELECT * FROM [" + m_Realm + "] WHERE (flags & " + regionFlags.ToString() + ") <> 0";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " AND ScopeID = @scopeID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
conn.Open();
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1302
OpenSim/Data/PGSQL/PGSQLSimulationData.cs → OpenSim/Data/MSSQL/MSSQLSimulationData.cs
Executable file → Normal file
1302
OpenSim/Data/PGSQL/PGSQLSimulationData.cs → OpenSim/Data/MSSQL/MSSQLSimulationData.cs
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class MSSQLUserAccountData : MSSQLGenericTableHandler<UserAccountData>,IUserAccountData
|
||||
{
|
||||
public MSSQLUserAccountData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "UserAccount")
|
||||
{
|
||||
}
|
||||
//private string m_Realm;
|
||||
//private List<string> m_ColumnNames = null;
|
||||
//private MSSQLManager m_database;
|
||||
|
||||
//public MSSQLUserAccountData(string connectionString, string realm)
|
||||
//{
|
||||
// m_Realm = realm;
|
||||
// m_ConnectionString = connectionString;
|
||||
// m_database = new MSSQLManager(connectionString);
|
||||
|
||||
// using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
// {
|
||||
// conn.Open();
|
||||
// Migration m = new Migration(conn, GetType().Assembly, "UserStore");
|
||||
// m.Update();
|
||||
// }
|
||||
//}
|
||||
|
||||
//public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query)
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//public UserAccountData Get(UUID principalID, UUID scopeID)
|
||||
//{
|
||||
// UserAccountData ret = new UserAccountData();
|
||||
// ret.Data = new Dictionary<string, string>();
|
||||
|
||||
// string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
|
||||
// if (scopeID != UUID.Zero)
|
||||
// sql += " and ScopeID = @scopeID";
|
||||
|
||||
// using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
// using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
// {
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
|
||||
// conn.Open();
|
||||
// using (SqlDataReader result = cmd.ExecuteReader())
|
||||
// {
|
||||
// if (result.Read())
|
||||
// {
|
||||
// ret.PrincipalID = principalID;
|
||||
// UUID scope;
|
||||
// UUID.TryParse(result["ScopeID"].ToString(), out scope);
|
||||
// ret.ScopeID = scope;
|
||||
|
||||
// if (m_ColumnNames == null)
|
||||
// {
|
||||
// m_ColumnNames = new List<string>();
|
||||
|
||||
// DataTable schemaTable = result.GetSchemaTable();
|
||||
// foreach (DataRow row in schemaTable.Rows)
|
||||
// m_ColumnNames.Add(row["ColumnName"].ToString());
|
||||
// }
|
||||
|
||||
// foreach (string s in m_ColumnNames)
|
||||
// {
|
||||
// if (s == "UUID")
|
||||
// continue;
|
||||
// if (s == "ScopeID")
|
||||
// continue;
|
||||
|
||||
// ret.Data[s] = result[s].ToString();
|
||||
// }
|
||||
// return ret;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//public bool Store(UserAccountData data)
|
||||
//{
|
||||
// if (data.Data.ContainsKey("UUID"))
|
||||
// data.Data.Remove("UUID");
|
||||
// if (data.Data.ContainsKey("ScopeID"))
|
||||
// data.Data.Remove("ScopeID");
|
||||
|
||||
// string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||
|
||||
// using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
// using (SqlCommand cmd = new SqlCommand())
|
||||
// {
|
||||
// StringBuilder updateBuilder = new StringBuilder();
|
||||
// updateBuilder.AppendFormat("update {0} set ", m_Realm);
|
||||
// bool first = true;
|
||||
// foreach (string field in fields)
|
||||
// {
|
||||
// if (!first)
|
||||
// updateBuilder.Append(", ");
|
||||
// updateBuilder.AppendFormat("{0} = @{0}", field);
|
||||
|
||||
// first = false;
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
|
||||
// }
|
||||
|
||||
// updateBuilder.Append(" where UUID = @principalID");
|
||||
|
||||
// if (data.ScopeID != UUID.Zero)
|
||||
// updateBuilder.Append(" and ScopeID = @scopeID");
|
||||
|
||||
// cmd.CommandText = updateBuilder.ToString();
|
||||
// cmd.Connection = conn;
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
|
||||
// conn.Open();
|
||||
|
||||
// if (cmd.ExecuteNonQuery() < 1)
|
||||
// {
|
||||
// StringBuilder insertBuilder = new StringBuilder();
|
||||
// insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm);
|
||||
// insertBuilder.Append(String.Join(", ", fields));
|
||||
// insertBuilder.Append(") values (@principalID, @scopeID, @");
|
||||
// insertBuilder.Append(String.Join(", @", fields));
|
||||
// insertBuilder.Append(")");
|
||||
|
||||
// cmd.CommandText = insertBuilder.ToString();
|
||||
|
||||
// if (cmd.ExecuteNonQuery() < 1)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//public bool Store(UserAccountData data, UUID principalID, string token)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//public bool SetDataItem(UUID principalID, string item, string value)
|
||||
//{
|
||||
// string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
|
||||
// using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
// using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
// {
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
|
||||
// cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID));
|
||||
|
||||
// conn.Open();
|
||||
|
||||
// if (cmd.ExecuteNonQuery() > 0)
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//public UserAccountData[] Get(string[] keys, string[] vals)
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
|
||||
public UserAccountData[] GetUsers(UUID scopeID, string query)
|
||||
{
|
||||
string[] words = query.Split(new char[] { ' ' });
|
||||
|
||||
for (int i = 0; i < words.Length; i++)
|
||||
{
|
||||
if (words[i].Length < 3)
|
||||
{
|
||||
if (i != words.Length - 1)
|
||||
Array.Copy(words, i + 1, words, i, words.Length - i - 1);
|
||||
Array.Resize(ref words, words.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (words.Length == 0)
|
||||
return new UserAccountData[0];
|
||||
|
||||
if (words.Length > 2)
|
||||
return new UserAccountData[0];
|
||||
|
||||
string sql = "";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
if (words.Length == 1)
|
||||
{
|
||||
sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
|
||||
}
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = sql;
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -31,39 +31,29 @@ using System.Collections.Generic;
|
|||
using System.Data;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace OpenSim.Data.PGSQL
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class PGSQLXInventoryData : IXInventoryData
|
||||
public class MSSQLXInventoryData : IXInventoryData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private PGSQLFolderHandler m_Folders;
|
||||
private PGSQLItemHandler m_Items;
|
||||
private MSSQLFolderHandler m_Folders;
|
||||
private MSSQLItemHandler m_Items;
|
||||
|
||||
public PGSQLXInventoryData(string conn, string realm)
|
||||
public MSSQLXInventoryData(string conn, string realm)
|
||||
{
|
||||
m_Folders = new PGSQLFolderHandler(
|
||||
m_Folders = new MSSQLFolderHandler(
|
||||
conn, "inventoryfolders", "InventoryStore");
|
||||
m_Items = new PGSQLItemHandler(
|
||||
m_Items = new MSSQLItemHandler(
|
||||
conn, "inventoryitems", String.Empty);
|
||||
}
|
||||
|
||||
public static UUID str2UUID(string strUUID)
|
||||
{
|
||||
UUID newUUID = UUID.Zero;
|
||||
|
||||
UUID.TryParse(strUUID, out newUUID);
|
||||
|
||||
return newUUID;
|
||||
}
|
||||
|
||||
public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Folders.Get(fields, vals);
|
||||
|
@ -123,7 +113,7 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||
{
|
||||
return m_Items.GetActiveGestures(principalID.ToString());
|
||||
return m_Items.GetActiveGestures(principalID);
|
||||
}
|
||||
|
||||
public int GetAssetPermissions(UUID principalID, UUID assetID)
|
||||
|
@ -132,9 +122,9 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
public class PGSQLItemHandler : PGSQLInventoryHandler<XInventoryItem>
|
||||
public class MSSQLItemHandler : MSSQLInventoryHandler<XInventoryItem>
|
||||
{
|
||||
public PGSQLItemHandler(string c, string t, string m) :
|
||||
public MSSQLItemHandler(string c, string t, string m) :
|
||||
base(c, t, m)
|
||||
{
|
||||
}
|
||||
|
@ -147,13 +137,14 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
UUID oldParent = retrievedItems[0].parentFolderID;
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format(@"update {0} set ""parentFolderID"" = :ParentFolderID where ""inventoryID"" = :InventoryID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParentFolderID", newParent));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("InventoryID", id ));
|
||||
|
||||
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
|
||||
|
@ -168,21 +159,16 @@ namespace OpenSim.Data.PGSQL
|
|||
return true;
|
||||
}
|
||||
|
||||
public XInventoryItem[] GetActiveGestures(string principalID)
|
||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
// cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1", m_Realm);
|
||||
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
|
||||
|
||||
cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1");
|
||||
|
||||
UUID princID = UUID.Zero;
|
||||
UUID.TryParse(principalID, out princID);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("uuid", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("type", (int)AssetType.Gesture));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
|
@ -192,28 +178,16 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
public int GetAssetPermissions(UUID principalID, UUID assetID)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
/*
|
||||
cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions""
|
||||
from inventoryitems
|
||||
where ""avatarID"" = :PrincipalID
|
||||
and ""assetID"" = :AssetID
|
||||
group by ""assetID"" ", m_Realm);
|
||||
*/
|
||||
cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions""
|
||||
from inventoryitems
|
||||
where ""avatarID""::uuid = :PrincipalID
|
||||
and ""assetID""::uuid = :AssetID
|
||||
group by ""assetID"" ");
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("AssetID", assetID));
|
||||
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString()));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
|
||||
int perms = 0;
|
||||
|
@ -241,9 +215,9 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
public class PGSQLFolderHandler : PGSQLInventoryHandler<XInventoryFolder>
|
||||
public class MSSQLFolderHandler : MSSQLInventoryHandler<XInventoryFolder>
|
||||
{
|
||||
public PGSQLFolderHandler(string c, string t, string m) :
|
||||
public MSSQLFolderHandler(string c, string t, string m) :
|
||||
base(c, t, m)
|
||||
{
|
||||
}
|
||||
|
@ -257,19 +231,14 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
UUID oldParentFolderUUID = folders[0].parentFolderID;
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
UUID foldID = UUID.Zero;
|
||||
UUID.TryParse(id, out foldID);
|
||||
|
||||
UUID newPar = UUID.Zero;
|
||||
UUID.TryParse(newParentFolderID, out newPar);
|
||||
|
||||
cmd.CommandText = String.Format(@"update {0} set ""parentFolderID"" = :ParentFolderID where ""folderID"" = :folderID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParentFolderID", newPar));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("folderID", foldID));
|
||||
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
|
||||
|
@ -295,9 +264,9 @@ namespace OpenSim.Data.PGSQL
|
|||
}
|
||||
}
|
||||
|
||||
public class PGSQLInventoryHandler<T> : PGSQLGenericTableHandler<T> where T: class, new()
|
||||
public class MSSQLInventoryHandler<T> : MSSQLGenericTableHandler<T> where T: class, new()
|
||||
{
|
||||
public PGSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {}
|
||||
public MSSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {}
|
||||
|
||||
protected bool IncrementFolderVersion(UUID folderID)
|
||||
{
|
||||
|
@ -306,21 +275,18 @@ namespace OpenSim.Data.PGSQL
|
|||
|
||||
protected bool IncrementFolderVersion(string folderID)
|
||||
{
|
||||
// m_log.DebugFormat("[PGSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
|
||||
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
|
||||
// Util.PrintCallStack();
|
||||
|
||||
string sql = @"update inventoryfolders set version=version+1 where ""folderID"" = :folderID";
|
||||
string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
UUID foldID = UUID.Zero;
|
||||
UUID.TryParse(folderID, out foldID);
|
||||
|
||||
conn.Open();
|
||||
|
||||
cmd.Parameters.Add( m_database.CreateParameter("folderID", foldID) );
|
||||
cmd.Parameters.AddWithValue("@folderID", folderID);
|
||||
|
||||
try
|
||||
{
|
|
@ -32,11 +32,11 @@ using System.Runtime.InteropServices;
|
|||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly : AssemblyTitle("OpenSim.Data.PGSQL")]
|
||||
[assembly : AssemblyTitle("OpenSim.Data.MSSQL")]
|
||||
[assembly : AssemblyDescription("")]
|
||||
[assembly : AssemblyConfiguration("")]
|
||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly : AssemblyProduct("OpenSim.Data.PGSQL")]
|
||||
[assembly : AssemblyProduct("OpenSim.Data.MSSQL")]
|
||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||
[assembly : AssemblyTrademark("")]
|
||||
[assembly : AssemblyCulture("")]
|
||||
|
@ -61,5 +61,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
||||
[assembly : AssemblyVersion("0.7.6.*")]
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
:VERSION 1
|
||||
|
||||
CREATE TABLE [assets] (
|
||||
[id] [varchar](36) NOT NULL,
|
||||
[name] [varchar](64) NOT NULL,
|
||||
[description] [varchar](64) NOT NULL,
|
||||
[assetType] [tinyint] NOT NULL,
|
||||
[local] [tinyint] NOT NULL,
|
||||
[temporary] [tinyint] NOT NULL,
|
||||
[data] [image] NOT NULL,
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[id] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
|
||||
:VERSION 2
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE Tmp_assets
|
||||
(
|
||||
id varchar(36) NOT NULL,
|
||||
name varchar(64) NOT NULL,
|
||||
description varchar(64) NOT NULL,
|
||||
assetType tinyint NOT NULL,
|
||||
local bit NOT NULL,
|
||||
temporary bit NOT NULL,
|
||||
data image NOT NULL
|
||||
) ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
|
||||
IF EXISTS(SELECT * FROM assets)
|
||||
EXEC('INSERT INTO Tmp_assets (id, name, description, assetType, local, temporary, data)
|
||||
SELECT id, name, description, assetType, CONVERT(bit, local), CONVERT(bit, temporary), data FROM assets WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE assets
|
||||
|
||||
EXECUTE sp_rename N'Tmp_assets', N'assets', 'OBJECT'
|
||||
|
||||
ALTER TABLE dbo.assets ADD CONSTRAINT
|
||||
PK__assets__id PRIMARY KEY CLUSTERED
|
||||
(
|
||||
id
|
||||
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE assets add create_time integer default 0
|
||||
ALTER TABLE assets add access_time integer default 0
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
:VERSION 4
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE dbo.Tmp_assets
|
||||
(
|
||||
id uniqueidentifier NOT NULL,
|
||||
name varchar(64) NOT NULL,
|
||||
description varchar(64) NOT NULL,
|
||||
assetType tinyint NOT NULL,
|
||||
local bit NOT NULL,
|
||||
temporary bit NOT NULL,
|
||||
data image NOT NULL,
|
||||
create_time int NULL,
|
||||
access_time int NULL
|
||||
) ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
|
||||
IF EXISTS(SELECT * FROM dbo.assets)
|
||||
EXEC('INSERT INTO dbo.Tmp_assets (id, name, description, assetType, local, temporary, data, create_time, access_time)
|
||||
SELECT CONVERT(uniqueidentifier, id), name, description, assetType, local, temporary, data, create_time, access_time FROM dbo.assets WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE assets
|
||||
|
||||
EXECUTE sp_rename N'Tmp_assets', N'assets', 'OBJECT'
|
||||
|
||||
ALTER TABLE dbo.assets ADD CONSTRAINT
|
||||
PK__assets__id PRIMARY KEY CLUSTERED
|
||||
(
|
||||
id
|
||||
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
:VERSION 5
|
||||
|
||||
DELETE FROM assets WHERE id = 'dc4b9f0b-d008-45c6-96a4-01dd947ac621';
|
||||
|
||||
:VERSION 6
|
||||
|
||||
ALTER TABLE assets ADD asset_flags INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
:VERSION 7
|
||||
|
||||
alter table assets add creatorid varchar(36) not null default '';
|
|
@ -0,0 +1,32 @@
|
|||
:VERSION 1
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [auth] (
|
||||
[uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
|
||||
[passwordHash] [varchar](32) NOT NULL,
|
||||
[passwordSalt] [varchar](32) NOT NULL,
|
||||
[webLoginKey] [varchar](255) NOT NULL,
|
||||
[accountType] VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
|
||||
) ON [PRIMARY]
|
||||
|
||||
CREATE TABLE [tokens] (
|
||||
[uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
|
||||
[token] [varchar](255) NOT NULL,
|
||||
[validity] [datetime] NOT NULL )
|
||||
ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 2
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
|
||||
INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
:VERSION 1
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [Avatars] (
|
||||
[PrincipalID] uniqueidentifier NOT NULL,
|
||||
[Name] varchar(32) NOT NULL,
|
||||
[Value] varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[PrincipalID] ASC, [Name] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 2
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE dbo.Tmp_Avatars
|
||||
(
|
||||
PrincipalID uniqueidentifier NOT NULL,
|
||||
[Name] varchar(32) NOT NULL,
|
||||
Value text NOT NULL DEFAULT '',
|
||||
) ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
|
||||
IF EXISTS(SELECT * FROM dbo.Avatars)
|
||||
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
|
||||
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE dbo.Avatars
|
||||
|
||||
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE dbo.Tmp_Avatars
|
||||
(
|
||||
PrincipalID uniqueidentifier NOT NULL,
|
||||
[Name] varchar(32) NOT NULL,
|
||||
Value text NOT NULL DEFAULT '',
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[PrincipalID] ASC, [Name] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
|
||||
IF EXISTS(SELECT * FROM dbo.Avatars)
|
||||
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
|
||||
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE dbo.Avatars
|
||||
|
||||
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||
COMMIT
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue