Compare commits

..

38 Commits

Author SHA1 Message Date
Diva Canto eb988d72bc New config var: DisableObjectTransfer. If set to True, objects never cross; instead they stay in the region, possibly placed outside its borders. 2016-07-03 12:17:19 -07:00
Diva Canto 00efc288d1 Don't copy assets to foreign asset servers when the objects are being deleted 2016-06-05 16:43:28 -07:00
Kevin Cozens 48b6d7ad27 Correct case in the names of the Avatar and Friends tables 2016-05-15 10:05:57 -07:00
Diva Canto 28e35420ea MySQL migrations: fix one last migration that had been left behind
Conflicts:
	OpenSim/Data/MySQL/Resources/UserAccount.migrations
2016-04-12 11:12:36 -07:00
Melanie Thielker ea7b316c4b Correct the case of the Presence table 2016-04-12 10:59:34 -07:00
Melanie Thielker 0bae05ff46 Change casing on UserAccounts 2016-04-12 10:59:22 -07:00
Diva Canto cbf5dfc16f The old sqlite inventory data interface was still around and causing problems: the only part of the code using it was the data (sqlite) tests. Given that this old interface has been obsolete for several years, it has now been removed, including the tests. TODO: Writing tests for the new (ah!) inventory data interface. 2016-02-21 10:43:40 -08:00
Diva Canto 928706b207 SQLite: Removed obsolete migration file 2016-02-21 09:11:06 -08:00
Diva Canto e726fa11f3 Flatten migrations for sqlite 2016-02-21 09:00:59 -08:00
Diva Canto 736343bee9 Flatten migrations for MySQL. 2016-02-20 19:08:02 -08:00
Diva Canto 363d7054ea The configger tool hadn't been updated since the introduction of OpenSimDefaults! :0
It is updated now.
2015-12-24 10:10:15 -08:00
Diva Canto 997cafb556 Flipped flavour to Post_Fixes 2015-12-24 10:09:56 -08:00
Diva Canto 497f575b9b Flipped flavour to Release 2015-12-09 11:14:28 -08:00
UbitUmarov 0a122c9b40 try to suport physics wearable type, sending it only if outgoing protocol version >= 0.5 2015-12-01 19:12:16 +00:00
UbitUmarov 46cd2da82c clamp maximum wearables types to Max suported by region (physics type still not supported) 2015-12-01 16:34:38 +00:00
Melanie Thielker dc46089054 Change versions 2015-12-01 15:59:21 +01:00
Melanie Thielker 22cf03ea0b Revert "downgrade protocol max to 0.3 since variable wearable types is still not supported"
This reverts commit 8c75625e85.
2015-12-01 15:55:42 +01:00
Diva Canto 13bdd25cfd Replaced ICSharpCode.SharpZipLib.dll for the same reason 2015-11-30 20:20:02 -08:00
Diva Canto a2ae17ad33 Replaced the mono addins dlls with freshly compiled ones, because the existing ones may somehow been mutually inconsistent. 2015-11-30 20:19:48 -08:00
UbitUmarov 8c75625e85 downgrade protocol max to 0.3 since variable wearable types is still not supported 2015-11-30 01:50:56 +00:00
Diva Canto f3829c10e0 Sometimes the viewer sends a null string as mapName; this made the client thread throw an exception with unexpected behavior for users (nothing happens). This commit gives it a sane default: it assumes we're looking for a position in the current region. 2015-11-27 08:29:19 -08:00
Diva Canto 4251fdf120 Commented out annoying debug messages. They are already commented in the master branch. 2015-11-27 08:28:30 -08:00
Diva Canto 9074c3d6f6 ok, now let's really flip it
Revert "Not yet"

This reverts commit de7f31abd1.
2015-11-24 14:02:17 -08:00
Diva Canto de7f31abd1 Not yet
Revert "Flip flavour to post-fixes"

This reverts commit 2e7c2ee998.
2015-11-24 13:51:55 -08:00
Diva Canto 2e7c2ee998 Flip flavour to post-fixes 2015-11-24 13:40:57 -08:00
Shy Robbiani e4e31d9acf row format fixed removed to allow creation of regions table
row_format=fixed is not supported by innodb and has broken the creation
of the regions table during the first startup of ROBUST. It must be a
relict from MyISAM. Also removed the probably inappropriate table
comment.

Signed-off-by: Kevin Cozens <kevin@ve3syb.ca>
2015-11-21 20:08:20 -05:00
Diva Canto 7c1f6ba913 Flip flavour to release. 2015-11-15 19:37:24 -08:00
Diva Canto f980355da4 Merge branch 'master' into 0.8.2-post-fixes 2015-11-12 18:52:56 -08:00
Diva Canto be744b68b4 Flipped flavour to RC2 2015-11-10 20:38:41 -08:00
Diva Canto 465abf01c0 Merge branch 'master' into 0.8.2-post-fixes
Conflicts:
	OpenSim/Framework/VersionInfo.cs
	OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
	OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
2015-11-10 20:34:18 -08:00
Diva Canto 8a96d42e97 Don't crash the sim if the map image is null. 2015-11-01 11:36:11 -08:00
UbitUmarov 84c8a7ae53 set SOG.IsAttachment when doing a full check, so future gets see the right value 2015-10-25 20:43:35 -07:00
Diva Canto 36af6a3baa Removed invalid dependencies from prebuild (those dlls no longer exist) 2015-10-22 21:44:54 -07:00
Diva Canto 2c729a1a63 Mark XAssetService obsolete and warn users. 2015-10-21 19:23:26 -07:00
Diva Canto 426bbb63dd Fix an issue introduced in 70a46fe090. I accidentally deleted the entire [EntityTransfer] section instead of just a few variables in it. 2015-10-21 16:52:08 -07:00
Melanie Thielker 4fd48ae8b3 Let the initiator of a teleport or crossing know that we handle extra
wearables
2015-10-20 01:00:18 +02:00
Diva Canto a7f42ea8f1 Added warning in RegionCombinerModule about it being considered obsolete and encouraging people to switch to varregions. 2015-10-18 17:01:28 -07:00
Diva Canto 36573b4568 Flipped flavour to RC1. 2015-10-18 16:30:33 -07:00
1516 changed files with 178585 additions and 242262 deletions

5
.gitignore vendored
View File

@ -1,6 +1,5 @@
.project
.settings
.gitignore
*.csproj
*.csproj.user
*.build
@ -11,7 +10,6 @@
*.pidb
*.dll.build
*.dll
*.log
# Ignore .user and .suo files as these are user preference specific
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
@ -31,8 +29,6 @@
*/*/*/*/*/bin
*/*/*/*/*/*/bin
*/*/*/*/*/*/*/bin
.vs/
addon-modules/
bin/Debug/*.dll
bin/*.dll.mdb
bin/*.db
@ -94,6 +90,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/

View File

@ -113,12 +113,10 @@
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
<!--
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.optionalmodules.tests">
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
-->
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.framework.tests">
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
@ -145,12 +143,7 @@
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.permissions">
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
<delete dir="%temp%"/>
<delete dir="%temp%"/>
</target>
<target name="test-stress" depends="build, find-nunit">
@ -233,12 +226,10 @@
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
</exec>
<!--
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.optionalmodules.tests">
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Region.OptionalModules.Tests.dll-Results.xml" />
</exec>
-->
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
@ -265,23 +256,17 @@
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.tests.permissions">
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
<arg value="-xml=test-results/OpenSim.Tests.Permissions.dll-Results.xml" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" /> -->
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
</target>
<target name="doxygen">

View File

@ -1,35 +1,38 @@
# Building on Windows
Steps:
* runprebuild.bat
* Load OpenSim.sln into Visual Studio .NET and build the solution.
* chdir bin
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
* run OpenSim.exe
# Building on Linux / Mac
# Building on Linux
Prereqs:
* Mono > 5.0
* On some Linux distributions you may need to install additional packages.
* msbuild or xbuild if still supported by the mono version
* See http://opensimulator.org/wiki/Dependencies for more information.
* Mono >= 2.4.3
* Nant >= 0.85
* On some Linux distributions you may need to install additional packages.
See http://opensimulator.org/wiki/Dependencies for more information.
* May also use xbuild (included in mono distributions)
* May use Monodevelop, a cross-platform IDE
From the distribution type:
* ./runprebuild.sh
* type msbuild or xbuild
* nant (or !* xbuild)
* cd bin
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
* review and change those ini files according to your needs
* windows: execute opensim.exe or opensim32.exe for small regions
* linux: run ./opensim.sh
* msbuild (xbuild) option switches
* clean: msbuild /target:clean
* debug: (default) msbuild /property:Configuration=Debug
* release: msbuild /property:Configuration=Release
* run mono OpenSim.exe
!* xbuild option switches
!* clean: xbuild /target:clean
!* debug: (default) xbuild /property:Configuration=Debug
!* release: xbuild /property:Configuration=Release
# Using Monodevelop
From the distribution type:
* ./runprebuild.sh
* type monodevelop OpenSim.sln
# References

View File

@ -4,9 +4,14 @@ The following people have contributed to OpenSim (Thank you for your effort!)
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)
* Melanie Thielker
* Diva (Crista Lopes, University of California, Irvine)
* BlueWall (James Hughes)
* Nebadon Izumi (Michael Cerquoni, OSgrid)
* Snoopy Pfeffer
* Robert Adams (MisterBlue)
* Oren Hurvitz (Kitely)
* Kevin Cozens
* Leal Duarte (Ubit Umarov)
@ -15,8 +20,11 @@ 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
* Teravus (w3z)
* Arthur Rodrigo S Valadares (IBM)
* Dan Lake
* Marck
* Mic Bowman
= Past Open Sim Developers =
These folks are alumns of the OpenSim core group, but are now
@ -49,15 +57,7 @@ where we are today.
* 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
@ -69,9 +69,9 @@ what it is today.
* alex_carnell
* Alan Webb (IBM)
* Aleric
* Alicia Raven
* Allen Kerensky
* BigFootAg
* Bill Blight
* BlueWall Slade
* bobshaffer2
* brianw/Sir_Ahzz
@ -89,7 +89,6 @@ what it is today.
* dmiles (Daxtron Labs)
* Dong Jun Lan (IBM)
* DoranZemlja
* Drake Arconis
* dr0b3rts
* dslake
* eeyore
@ -108,7 +107,6 @@ what it is today.
* Flyte Xevious
* Freaky Tech
* Garmin Kawaguichi
* Geir Noklebye
* Glenn Martin (MOSES)
* Gryc Ueusp
* H-H-H (ginge264)
@ -117,7 +115,6 @@ what it is today.
* Imaze Rhiano
* Intimidated
* Jak Daniels
* Jeff Kelly
* Jeremy Bongio (IBM)
* jhurliman
* John R Sohn (XenReborn)
@ -131,7 +128,6 @@ what it is today.
* KittyLiu
* Kurt Taylor (IBM)
* Lani Global
* lickx
* lillith_xue
* lkalif
* LuciusSirnah
@ -140,10 +136,8 @@ what it is today.
* Magnuz Binder
* maimedleech
* Mana Janus
* Mandarinka Tasty
* MarcelEdward
* Matt Lehmann
* mewtwo0641
* Mic Bowman
* Michelle Argus
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
@ -151,7 +145,6 @@ what it is today.
* Micheil Merlin
* Mike Osias (IBM)
* Mike Pitman (IBM)
* Mike Rieker (Dreamnation)
* mikemig
* mikkopa/_someone - RealXtend
* Misterblue
@ -165,7 +158,6 @@ what it is today.
* openlifegrid.com
* otakup0pe
* Pixel Tomsen
* Quill Littlefeather
* ralphos
* RemedyTomm
* Revolution
@ -185,20 +177,14 @@ what it is today.
* 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)

7241
OpenSim.FxCop Normal file

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@ namespace OpenSim.Groups
public string AccessToken;
}
public class ExtendedGroupMembersData
public class ExtendedGroupMembersData
{
// This is the only difference: this is a string
public string AgentID;
@ -65,7 +65,7 @@ namespace OpenSim.Groups
public UUID RoleID;
// This is the only difference: this is a string
public string MemberID;
}
public struct ExtendedGroupNoticeData

103
OpenSim/Addons/Groups/GroupsMessagingModule.cs Executable file → Normal file
View File

@ -131,7 +131,7 @@ namespace OpenSim.Groups
{
if (!m_groupMessagingEnabled)
return;
scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
m_sceneList.Add(scene);
@ -163,7 +163,7 @@ namespace OpenSim.Groups
if (m_groupData == null)
{
m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
RemoveRegion(scene);
RemoveRegion(scene);
return;
}
@ -218,7 +218,7 @@ namespace OpenSim.Groups
m_msgTransferModule = null;
}
public Type ReplaceableInterface
public Type ReplaceableInterface
{
get { return null; }
}
@ -252,7 +252,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);
}
/// <summary>
@ -262,7 +262,7 @@ namespace OpenSim.Groups
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
if (groupInfo != null)
@ -279,7 +279,7 @@ namespace OpenSim.Groups
{
SendMessageToGroup(im, groupID, UUID.Zero, null);
}
public void SendMessageToGroup(
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
{
@ -355,9 +355,9 @@ namespace OpenSim.Groups
{
if (!sendCondition(member))
{
if (m_debugEnabled)
if (m_debugEnabled)
m_log.DebugFormat(
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
member.AgentID);
continue;
@ -366,7 +366,7 @@ namespace OpenSim.Groups
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
{
// Don't deliver messages to people who have dropped this session
if (m_debugEnabled)
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
continue;
@ -414,7 +414,7 @@ namespace OpenSim.Groups
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
}
#region SimGridEventHandlers
void OnClientLogin(IClientAPI client)
@ -445,13 +445,13 @@ namespace OpenSim.Groups
// The instant message module will only deliver messages of dialog types:
// MessageFromAgent, StartTyping, StopTyping, MessageFromObject
//
// Any other message type will not be delivered to a client by the
// Any other message type will not be delivered to a client by the
// Instant Message Module
UUID regionID = new UUID(msg.RegionID);
if (m_debugEnabled)
{
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
DebugGridInstantMessage(msg);
@ -508,7 +508,7 @@ namespace OpenSim.Groups
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
return;
}
else
else
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
@ -531,7 +531,7 @@ namespace OpenSim.Groups
}
}
});
}
}
}
@ -555,7 +555,7 @@ namespace OpenSim.Groups
break;
case (byte)InstantMessageDialog.SessionSend:
// User hasn't dropped, so they're in the session,
// User hasn't dropped, so they're in the session,
// maybe we should deliver it.
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
if (client != null)
@ -599,34 +599,35 @@ namespace OpenSim.Groups
{
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
UUID fromAgent = new UUID(msg.fromAgentID);
// Force? open the group session dialog???
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
if (eq != null)
{
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, fromAgent
, msg.message
, AgentID
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, new UUID(msg.fromAgentID)
, msg.message
, AgentID
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
var update = new GroupChatListAgentUpdateData(AgentID);
var updates = new List<GroupChatListAgentUpdateData> { update };
eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
}
eq.ChatterBoxSessionAgentListUpdates(
new UUID(GroupID)
, AgentID
, new UUID(msg.toAgentID)
, false //canVoiceChat
, false //isModerator
, false //text mute
);
}
}
}
@ -653,7 +654,7 @@ namespace OpenSim.Groups
UUID AgentID = new UUID(im.fromAgentID);
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
if (groupInfo != null)
{
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
@ -661,12 +662,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
);
}
}
@ -676,7 +679,7 @@ namespace OpenSim.Groups
UUID GroupID = new UUID(im.imSessionID);
UUID AgentID = new UUID(im.fromAgentID);
if (m_debugEnabled)
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
//If this agent is sending a message, then they want to be in the session
@ -708,7 +711,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)

686
OpenSim/Addons/Groups/GroupsModule.cs Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -103,7 +103,7 @@ namespace OpenSim.Groups
if (!m_Enabled)
return;
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
m_Scenes.Add(scene);
@ -135,7 +135,7 @@ namespace OpenSim.Groups
{
m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
// Also, if local, create the endpoint for the HGGroupsService
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
scene.RequestModuleInterface<IOfflineIMService>(), scene.RequestModuleInterface<IUserAccountService>());
}
@ -170,7 +170,7 @@ namespace OpenSim.Groups
if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
{
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
m_OfflineIM != null && m_Messaging != null)
{
List<GridInstantMessage> ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
@ -184,12 +184,12 @@ namespace OpenSim.Groups
#region IGroupsServicesConnector
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
{
reason = string.Empty;
if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
else
{
@ -198,14 +198,14 @@ namespace OpenSim.Groups
}
}
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
{
reason = string.Empty;
string url = string.Empty;
string name = string.Empty;
if (IsLocal(groupID, out url, out name))
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
openEnrollment, allowPublish, maturePublish, out reason);
else
{
@ -246,9 +246,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)
@ -374,7 +374,7 @@ namespace OpenSim.Groups
}
}
return new List<GroupRoleMembersData>();
}
@ -605,8 +605,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();
@ -620,7 +626,7 @@ namespace OpenSim.Groups
}
if (agent != null)
return Util.ProduceUserUniversalIdentifier(agent);
// we don't know anything about this foreign user
// try asking the user management module, which may know more
return m_UserManagement.GetUserUUI(AgentID);
@ -630,8 +636,14 @@ namespace OpenSim.Groups
private string AgentUUIForOutside(string AgentIDStr)
{
UUID AgentID = UUID.Zero;
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
return UUID.Zero.ToString();
try
{
AgentID = new UUID(AgentIDStr);
}
catch (FormatException)
{
return AgentID.ToString();
}
AgentCircuitData agent = null;
foreach (Scene scene in m_Scenes)
@ -652,7 +664,7 @@ namespace OpenSim.Groups
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp))
m_UserManagement.AddUser(userID, first, last, url);
return userID;
}

View File

@ -64,8 +64,8 @@ namespace OpenSim.Groups
m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
if (homeURI == string.Empty)
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
@ -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);

View File

@ -34,12 +34,12 @@ namespace OpenSim.Groups
{
public interface IGroupsServicesConnector
{
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason);
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
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);
@ -75,7 +75,7 @@ namespace OpenSim.Groups
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
/// </returns>
ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
/// <summary>
/// Get information about the groups to which a user belongs.
/// </summary>
@ -87,7 +87,7 @@ namespace OpenSim.Groups
/// </returns>
List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);

View File

@ -108,7 +108,7 @@ namespace OpenSim.Groups
if (!m_Enabled)
return;
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
m_Scenes.Add(scene);
}
@ -146,16 +146,16 @@ namespace OpenSim.Groups
#region IGroupsServicesConnector
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
{
m_log.DebugFormat("[Groups]: Creating group {0}", name);
reason = string.Empty;
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
}
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
{
reason = string.Empty;
@ -173,9 +173,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)
@ -296,7 +296,7 @@ namespace OpenSim.Groups
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
{
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
hasAttachment, attType, attName, attItemID, attOwnerID);
}

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mono.Addins;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
@ -15,8 +15,8 @@ using Mono.Addins;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -26,11 +26,11 @@ using Mono.Addins;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
[assembly: AssemblyVersion("0.8.3.*")]
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]

View File

@ -41,7 +41,7 @@ using Nini.Config;
namespace OpenSim.Groups
{
public class GroupsServiceRemoteConnector
public class GroupsServiceRemoteConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -71,7 +71,7 @@ namespace OpenSim.Groups
}
///
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
}
@ -153,7 +153,7 @@ namespace OpenSim.Groups
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 +161,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);

View File

@ -113,7 +113,7 @@ namespace OpenSim.Groups
if (!m_Enabled)
return;
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
m_Scenes.Add(scene);
}
@ -151,7 +151,7 @@ namespace OpenSim.Groups
#region IGroupsServicesConnector
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
{
m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
@ -167,7 +167,7 @@ namespace OpenSim.Groups
return groupID;
}
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
{
string r = string.Empty;
@ -186,16 +186,16 @@ namespace OpenSim.Groups
if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
return null;
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
{
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
{
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
});
}
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)
@ -362,7 +362,7 @@ namespace OpenSim.Groups
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
}
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
{
GroupNoticeInfo notice = new GroupNoticeInfo();

View File

@ -91,10 +91,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);
@ -287,7 +286,7 @@ namespace OpenSim.Groups
string requestingAgentID = request["RequestingAgentID"].ToString();
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
NullResult(result, string.Format("Insufficient permissions. {0}", agentID));
NullResult(result, string.Format("Insufficient permissions.", agentID));
else
result["RESULT"] = "true";
}
@ -394,7 +393,7 @@ namespace OpenSim.Groups
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
!request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
NullResult(result, "Bad network data");
else
@ -520,11 +519,11 @@ namespace OpenSim.Groups
bool success = false;
if (op == "ADD")
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
else if (op == "DELETE")
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
result["RESULT"] = success.ToString();
@ -648,8 +647,8 @@ namespace OpenSim.Groups
string op = request["OP"].ToString();
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
{
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
{
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
@ -665,7 +664,7 @@ namespace OpenSim.Groups
}
else if (op == "GET")
{
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
new UUID(request["InviteID"].ToString()));
if (invite != null)

View File

@ -43,63 +43,60 @@ namespace OpenSim.Groups
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public const GroupPowers DefaultEveryonePowers =
GroupPowers.AllowSetHome |
GroupPowers.Accountable |
GroupPowers.JoinChat |
GroupPowers.AllowVoiceChat |
GroupPowers.ReceiveNotices |
GroupPowers.StartProposal |
GroupPowers.VoteOnProposal;
public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
GroupPowers.Accountable |
GroupPowers.JoinChat |
GroupPowers.AllowVoiceChat |
GroupPowers.ReceiveNotices |
GroupPowers.StartProposal |
GroupPowers.VoteOnProposal;
public const GroupPowers OfficersPowers = DefaultEveryonePowers |
GroupPowers.AllowFly |
GroupPowers.AllowLandmark |
GroupPowers.AllowRez |
GroupPowers.AssignMemberLimited |
GroupPowers.ChangeIdentity |
GroupPowers.ChangeMedia |
GroupPowers.ChangeOptions |
GroupPowers.DeedObject |
GroupPowers.Eject |
GroupPowers.FindPlaces |
GroupPowers.Invite |
GroupPowers.LandChangeIdentity |
GroupPowers.LandDeed |
GroupPowers.LandDivideJoin |
GroupPowers.LandEdit |
GroupPowers.AllowEnvironment |
GroupPowers.LandEjectAndFreeze |
GroupPowers.LandGardening |
GroupPowers.LandManageAllowed |
GroupPowers.LandManageBanned |
GroupPowers.LandManagePasses |
GroupPowers.LandOptions |
GroupPowers.LandRelease |
GroupPowers.LandSetSale |
GroupPowers.MemberVisible |
GroupPowers.ModerateChat |
GroupPowers.ObjectManipulate |
GroupPowers.ObjectSetForSale |
GroupPowers.ReturnGroupOwned |
GroupPowers.ReturnGroupSet |
GroupPowers.ReturnNonGroup |
GroupPowers.RoleProperties |
GroupPowers.SendNotices |
GroupPowers.SetLandingPoint;
public const GroupPowers OwnerPowers = OfficersPowers |
GroupPowers.Accountable |
GroupPowers.AllowEditLand |
GroupPowers.AssignMember |
GroupPowers.ChangeActions |
GroupPowers.CreateRole |
GroupPowers.DeleteRole |
GroupPowers.ExperienceAdmin |
GroupPowers.ExperienceCreator |
GroupPowers.GroupBanAccess |
GroupPowers.HostEvent |
GroupPowers.RemoveMember;
public const GroupPowers OwnerPowers = GroupPowers.Accountable |
GroupPowers.AllowEditLand |
GroupPowers.AllowFly |
GroupPowers.AllowLandmark |
GroupPowers.AllowRez |
GroupPowers.AllowSetHome |
GroupPowers.AllowVoiceChat |
GroupPowers.AssignMember |
GroupPowers.AssignMemberLimited |
GroupPowers.ChangeActions |
GroupPowers.ChangeIdentity |
GroupPowers.ChangeMedia |
GroupPowers.ChangeOptions |
GroupPowers.CreateRole |
GroupPowers.DeedObject |
GroupPowers.DeleteRole |
GroupPowers.Eject |
GroupPowers.FindPlaces |
GroupPowers.HostEvent |
GroupPowers.Invite |
GroupPowers.JoinChat |
GroupPowers.LandChangeIdentity |
GroupPowers.LandDeed |
GroupPowers.LandDivideJoin |
GroupPowers.LandEdit |
GroupPowers.LandEjectAndFreeze |
GroupPowers.LandGardening |
GroupPowers.LandManageAllowed |
GroupPowers.LandManageBanned |
GroupPowers.LandManagePasses |
GroupPowers.LandOptions |
GroupPowers.LandRelease |
GroupPowers.LandSetSale |
GroupPowers.ModerateChat |
GroupPowers.ObjectManipulate |
GroupPowers.ObjectSetForSale |
GroupPowers.ReceiveNotices |
GroupPowers.RemoveMember |
GroupPowers.ReturnGroupOwned |
GroupPowers.ReturnGroupSet |
GroupPowers.ReturnNonGroup |
GroupPowers.RoleProperties |
GroupPowers.SendNotices |
GroupPowers.SetLandingPoint |
GroupPowers.StartProposal |
GroupPowers.VoteOnProposal;
#region Daily Cleanup
@ -129,7 +126,7 @@ namespace OpenSim.Groups
#endregion
public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
{
reason = string.Empty;
@ -154,25 +151,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();
UUID roleID = UUID.Random();
data.Data["OwnerRoleID"] = roleID.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);
_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 +223,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);
}
@ -279,7 +264,7 @@ namespace OpenSim.Groups
if (ownerRole != null)
ownerRoleID = ownerRole.RoleID;
// Check visibility?
// Check visibility?
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
@ -322,20 +307,20 @@ namespace OpenSim.Groups
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");
}
}
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;
@ -500,8 +485,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 +496,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 +516,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)
@ -568,8 +540,8 @@ namespace OpenSim.Groups
{
newRoleID = r.RoleID;
break;
}
}
}
}
MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
if (member != null)
@ -727,7 +699,7 @@ namespace OpenSim.Groups
m_Database.StoreMember(membership);
}
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
{
// Check perms
@ -840,7 +812,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 +830,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;

View File

@ -35,67 +35,67 @@ using OpenSim.Services.Base;
namespace OpenSim.Groups
{
public class GroupsServiceBase : ServiceBase
{
protected IGroupsData m_Database = null;
protected IGridUserData m_GridUserService = null;
public class GroupsServiceBase : ServiceBase
{
protected IGroupsData m_Database = null;
protected IGridUserData m_GridUserService = null;
public GroupsServiceBase(IConfigSource config, string cName)
: base(config)
{
string dllName = String.Empty;
string connString = String.Empty;
string realm = "os_groups";
string usersRealm = "GridUser";
string configName = (cName == string.Empty) ? "Groups" : cName;
public GroupsServiceBase(IConfigSource config, string cName)
: base(config)
{
string dllName = String.Empty;
string connString = String.Empty;
string realm = "os_groups";
string usersRealm = "GridUser";
string configName = (cName == string.Empty) ? "Groups" : cName;
//
// Try reading the [DatabaseService] section, if it exists
//
IConfig dbConfig = config.Configs["DatabaseService"];
if (dbConfig != null)
{
if (dllName == String.Empty)
dllName = dbConfig.GetString("StorageProvider", String.Empty);
if (connString == String.Empty)
connString = dbConfig.GetString("ConnectionString", String.Empty);
}
//
// Try reading the [DatabaseService] section, if it exists
//
IConfig dbConfig = config.Configs["DatabaseService"];
if (dbConfig != null)
{
if (dllName == String.Empty)
dllName = dbConfig.GetString("StorageProvider", String.Empty);
if (connString == String.Empty)
connString = dbConfig.GetString("ConnectionString", String.Empty);
}
//
// [Groups] section overrides [DatabaseService], if it exists
//
IConfig groupsConfig = config.Configs[configName];
if (groupsConfig != null)
{
dllName = groupsConfig.GetString("StorageProvider", dllName);
connString = groupsConfig.GetString("ConnectionString", connString);
realm = groupsConfig.GetString("Realm", realm);
}
//
// [Groups] section overrides [DatabaseService], if it exists
//
IConfig groupsConfig = config.Configs[configName];
if (groupsConfig != null)
{
dllName = groupsConfig.GetString("StorageProvider", dllName);
connString = groupsConfig.GetString("ConnectionString", connString);
realm = groupsConfig.GetString("Realm", realm);
}
//
// We tried, but this doesn't exist. We can't proceed.
//
if (dllName.Equals(String.Empty))
throw new Exception("No StorageProvider configured");
//
// We tried, but this doesn't exist. We can't proceed.
//
if (dllName.Equals(String.Empty))
throw new Exception("No StorageProvider configured");
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
if (m_Database == null)
throw new Exception("Could not find a storage interface in the given module " + dllName);
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);
//
// [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);
}
}
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);
}
}
}

View File

@ -76,7 +76,7 @@ namespace OpenSim.Groups
// Check if it already exists
GroupData grec = m_Database.RetrieveGroup(groupID);
if (grec == null ||
if (grec == null ||
(grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower()))
{
// Create the group

View File

@ -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 &&

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mono.Addins;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
@ -15,8 +15,8 @@ using Mono.Addins;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -26,11 +26,11 @@ using Mono.Addins;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
[assembly: AssemblyVersion("0.8.3.*")]
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]

View File

@ -77,7 +77,7 @@ namespace OpenSim.OfflineIM
break;
}
///
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
}
@ -140,7 +140,7 @@ namespace OpenSim.OfflineIM
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["UserID"] = userID;
MakeRequest("DELETE", sendData);
}

View File

@ -90,7 +90,7 @@ namespace OpenSim.OfflineIM
public bool StoreMessage(GridInstantMessage im, out string reason)
{
reason = string.Empty;
// Check limits
UUID principalID = new UUID(im.toAgentID);
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
@ -110,8 +110,9 @@ namespace OpenSim.OfflineIM
{
m_serializer.Serialize(writer, im);
writer.Flush();
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
}
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
}
OfflineIMData data = new OfflineIMData();

View File

@ -124,7 +124,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
Thread.CurrentThread.ManagedThreadId.ToString() +
")");
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);

View File

@ -61,8 +61,9 @@ 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 : AssemblyVersion("0.8.2.*")]
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]

View File

@ -38,7 +38,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
public class RegionLoaderFileSystem : IRegionLoader
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IConfigSource m_configSource;
public void SetIniConfigSource(IConfigSource configSource)
@ -72,11 +72,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
// Create an empty Regions.ini if there are no existing config files.
if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0)
{
{
new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
}
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config files from {0}", regionConfigPath);
List<RegionInfo> regionInfos = new List<RegionInfo>();
@ -85,16 +85,16 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
foreach (string file in iniFiles)
{
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
IConfigSource source = new IniConfigSource(file);
foreach (IConfig config in source.Configs)
{
{
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource, config.Name);
regionInfos.Add(regionInfo);
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
i++;
}
}
@ -102,12 +102,12 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
foreach (string file in configFiles)
{
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource);
regionInfos.Add(regionInfo);
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
i++;
}

View File

@ -49,9 +49,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
public RegionInfo[] LoadRegions()
{
int tries = 3;
int wait = 2000;
if (m_configSource == null)
{
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
@ -59,7 +56,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
}
else
{
IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"];
string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim();
bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
@ -70,74 +67,82 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
}
else
{
while (tries > 0)
RegionInfo[] regionInfos = new RegionInfo[] {};
int regionCount = 0;
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
try
{
RegionInfo[] regionInfos = new RegionInfo[] { };
int regionCount = 0;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
string xmlSource = String.Empty;
try
using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())
{
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string xmlSource = String.Empty;
string tempStr = reader.ReadLine();
while (tempStr != null)
{
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Nini")
{
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
if (regionCount > 0)
using (Stream s = webResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(s))
{
regionInfos = new RegionInfo[regionCount];
int i;
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
string tempStr = reader.ReadLine();
while (tempStr != null)
{
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
regionInfos[i] =
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i], false, m_configSource);
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
}
}
}
catch (WebException ex)
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Nini")
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
if (regionCount > 0)
{
regionInfos = new RegionInfo[regionCount];
int i;
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
{
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
regionInfos[i] =
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
}
}
}
}
catch (WebException ex)
{
using (HttpWebResponse response = (HttpWebResponse)ex.Response)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
if (!allowRegionless)
throw ex;
}
else
{
throw ex;
}
if (regionCount > 0 || allowRegionless)
return regionInfos;
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
tries--;
if (tries > 0)
{
m_log.Debug("[WEBLOADER]: Retrying");
System.Threading.Thread.Sleep(wait);
}
}
}
m_log.Error("[WEBLOADER]: No region configs were available.");
return null;
if (regionCount > 0 | allowRegionless)
{
return regionInfos;
}
else
{
m_log.Error("[WEBLOADER]: No region configs were available.");
return null;
}
}
}
}
}
}
}

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mono.Addins;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")]
@ -15,8 +15,8 @@ using Mono.Addins;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -26,11 +26,11 @@ using Mono.Addins;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
[assembly: AssemblyVersion("0.8.3.*")]
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]

View File

@ -75,7 +75,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
}
#region IApplicationPlugin implementation
public void Initialise (OpenSimBase openSim)
{
m_openSim = openSim;
@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
{
m_log.InfoFormat(
"[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown",
loadedModuleData.Key.Id,
loadedModuleData.Key.Id,
loadedModuleData.Key.Version,
loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2],
loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]);
@ -261,7 +261,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
}
#region Region Module interfacesController implementation
/// <summary>
/// Check that the given module is no disabled in the [Modules] section of the config files.
/// </summary>
@ -293,10 +293,10 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
if (className != String.Empty &&
node.Type.ToString() != className)
return false;
}
}
return true;
}
}
// The root of all evil.
// This is where we handle adding the modules to scenes when they

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mono.Addins;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")]
@ -15,8 +15,8 @@ using Mono.Addins;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -26,11 +26,11 @@ using Mono.Addins;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
[assembly: AssemblyVersion("0.8.3.*")]
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]

View File

@ -74,7 +74,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 +93,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
public void Initialise(OpenSimBase openSim)
{
m_openSimVersion = openSim.GetVersionText();
m_configSource = openSim.ConfigSource.Source;
try
{
@ -138,13 +135,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
// Agent management
availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
@ -169,11 +163,8 @@ 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);
// Land management
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
// Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -274,148 +265,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
try
{
m_log.Info("[RADMIN]: Request to restart Region.");
CheckRegionParams(requestData, responseData);
Scene rebootedScene = null;
bool restartAll = false;
IConfig startupConfig = m_configSource.Configs["Startup"];
if (startupConfig != null)
{
if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
{
rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
restartAll = true;
}
}
if (rebootedScene == null)
{
CheckRegionParams(requestData, responseData);
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
}
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
responseData["success"] = false;
responseData["accepted"] = true;
responseData["rebooting"] = true;
string message;
List<int> times = new List<int>();
if (requestData.ContainsKey("alerts"))
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
if (restartModule != null)
{
string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
{
m_log.Info("[RADMIN]: Request to cancel restart.");
List<int> times = new List<int> { 30, 15 };
if (restartModule != null)
{
message = "Restart has been cancelled";
if (requestData.ContainsKey("message"))
message = requestData["message"].ToString();
restartModule.AbortRestart(message);
responseData["success"] = true;
responseData["rebooting"] = false;
return;
}
}
foreach (string a in alertTimes)
times.Add(Convert.ToInt32(a));
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
responseData["success"] = true;
}
else
{
int timeout = 30;
if (requestData.ContainsKey("milliseconds"))
timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
while (timeout > 0)
{
times.Add(timeout);
if (timeout > 300)
timeout -= 120;
else if (timeout > 30)
timeout -= 30;
else
timeout -= 15;
}
}
m_log.Info("[RADMIN]: Request to restart Region.");
message = "Region is restarting in {0}. Please save what you are doing and log out.";
if (requestData.ContainsKey("message"))
message = requestData["message"].ToString();
bool notice = true;
if (requestData.ContainsKey("noticetype")
&& ((string)requestData["noticetype"] == "dialog"))
{
notice = false;
}
if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false))
{
m_log.Info("[RADMIN]: Counting affected avatars");
int agents = 0;
if (restartAll)
{
foreach (Scene s in m_application.SceneManager.Scenes)
{
foreach (ScenePresence sp in s.GetScenePresences())
{
if (!sp.IsChildAgent && !sp.IsNPC)
agents++;
}
}
}
else
{
foreach (ScenePresence sp in rebootedScene.GetScenePresences())
{
if (!sp.IsChildAgent && !sp.IsNPC)
agents++;
}
}
m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents);
if (agents == 0)
{
m_log.Info("[RADMIN]: No avatars detected, shutting down without delay");
times.Clear();
times.Add(0);
}
}
List<Scene> restartList;
if (restartAll)
restartList = m_application.SceneManager.Scenes;
else
restartList = new List<Scene>() { rebootedScene };
foreach (Scene s in m_application.SceneManager.Scenes)
{
restartModule = s.RequestModuleInterface<IRestartModule>();
if (restartModule != null)
restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
}
responseData["success"] = true;
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
responseData["rebooting"] = false;
throw;
throw e;
}
m_log.Info("[RADMIN]: Restart Region request complete");
@ -445,32 +320,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
m_log.Info("[RADMIN]: Alert request complete");
}
public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
Hashtable responseData = (Hashtable)response.Value;
m_log.Info("[RADMIN]: Dialog request started");
Hashtable requestData = (Hashtable)request.Params[0];
string message = (string)requestData["message"];
string fromuuid = (string)requestData["from"];
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
responseData["accepted"] = true;
responseData["success"] = true;
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
});
m_log.Info("[RADMIN]: Dialog request complete");
}
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Load height maps request started");
@ -574,32 +423,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController
message = "Region is going down now.";
}
if (requestData.ContainsKey("noticetype")
&& ((string) requestData["noticetype"] == "dialog"))
{
m_application.SceneManager.ForEachScene(
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
});
}
else
{
if (!requestData.ContainsKey("noticetype")
|| ((string)requestData["noticetype"] != "none"))
{
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendGeneralAlert(message);
});
}
}
// Perform shutdown
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
@ -611,7 +441,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
responseData["success"] = true;
m_log.Info("[RADMIN]: Shutdown Administrator Request complete");
}
@ -783,9 +613,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
// No INI setting recorded.
}
string regionIniPath;
if (requestData.Contains("region_file"))
{
// Make sure that the file to be created is in a subdirectory of the region storage directory.
@ -809,7 +639,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
region.RegionName.Replace(" ", "_").Replace(":", "_").
Replace("/", "_")));
}
m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}",
region.RegionID, regionIniPath);
region.SaveRegionToFile("dynamic region", regionIniPath);
@ -818,9 +648,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
region.Persistent = false;
}
// Set the estate
// Check for an existing estate
List<int> estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]);
if (estateIDs.Count < 1)
@ -831,12 +661,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// ok, client wants us to use an explicit UUID
// regardless of what the avatar name provided
userID = new UUID((string) requestData["estate_owner_uuid"]);
// Check that the specified user exists
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
IUserAccountService accountService = currentOrFirst.UserAccountService;
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
if (user == null)
throw new Exception("Specified user was not found.");
}
@ -845,23 +675,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// We need to look up the UUID for the avatar with the provided name.
string ownerFirst = (string) requestData["estate_owner_first"];
string ownerLast = (string) requestData["estate_owner_last"];
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
IUserAccountService accountService = currentOrFirst.UserAccountService;
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
ownerFirst, ownerLast);
// Check that the specified user exists
if (user == null)
throw new Exception("Specified user was not found.");
userID = user.PrincipalID;
}
else
{
throw new Exception("Estate owner details not provided.");
}
// Create a new estate with the name provided
region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
@ -888,7 +718,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
throw new Exception("Failed to join estate.");
}
}
// Create the region and perform any initial initialization
IScene newScene;
@ -1195,7 +1025,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// Set home position
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
if (null == home)
{
@ -1425,7 +1255,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
if ((null != regionXLocation) && (null != regionYLocation))
{
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
if (null == home) {
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
@ -1452,7 +1282,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
throw e;
}
m_log.Info("[RADMIN]: UpdateUserAccount: request complete");
}
}
@ -1644,7 +1474,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
GetSceneFromRegionParams(requestData, responseData, out scene);
string filename = (string) requestData["filename"];
bool mergeOar = false;
bool skipAssets = false;
@ -1658,7 +1488,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
Dictionary<string, object> archiveOptions = new Dictionary<string,object>();
if (mergeOar) archiveOptions.Add("merge", null);
if (skipAssets) archiveOptions.Add("skipAssets", null);
if (archiver != null)
@ -1771,7 +1601,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
m_log.InfoFormat(
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
scene.Name, filename, requestId);
archiver.ArchiveRegion(filename, requestId, options);
@ -1918,31 +1748,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
int flags = 0;
string text = String.Empty;
int health = 0;
responseData["success"] = true;
CheckRegionParams(requestData, responseData);
Scene scene = null;
try
{
GetSceneFromRegionParams(requestData, responseData, out scene);
health = scene.GetHealth(out flags, out text);
}
catch
{
responseData["error"] = null;
}
GetSceneFromRegionParams(requestData, responseData, out scene);
int health = scene.GetHealth();
responseData["health"] = health;
responseData["success"] = true;
responseData["health"] = health;
responseData["flags"] = flags;
responseData["message"] = text;
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
}
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
@ -2118,8 +1938,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
Hashtable responseData = (Hashtable)response.Value;
// Hashtable requestData = (Hashtable)request.Params[0];
m_application.SceneManager.ForEachScene(s =>
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
m_application.SceneManager.ForEachScene(s =>
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
);
responseData["success"] = true;
@ -2251,6 +2071,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
Hashtable requestData = (Hashtable)request.Params[0];
Hashtable responseData = (Hashtable)response.Value;
string musicURL = string.Empty;
UUID groupID = UUID.Zero;
uint flags = 0;
@ -2260,129 +2081,41 @@ namespace OpenSim.ApplicationPlugins.RemoteController
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"),
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)
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.
@ -2851,7 +2584,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
if (destinationFolder.Type != (short)FolderType.Clothing)
{
destinationFolder = new InventoryFolderBase();
destinationFolder.ID = UUID.Random();
destinationFolder.Name = "Clothing";
destinationFolder.Owner = destination;
@ -2872,7 +2605,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 +2659,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)
{
@ -2987,11 +2722,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
sourceFolder = new InventoryFolderBase();
sourceFolder.ID = UUID.Random();
if (assetType == FolderType.Clothing)
if (assetType == FolderType.Clothing)
{
sourceFolder.Name = "Clothing";
}
else
}
else
{
sourceFolder.Name = "Body Parts";
}
@ -3204,7 +2939,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// Set home position
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
if (null == home) {
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);

View File

@ -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,9 @@ 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 +63,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 +117,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 +134,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,32 +149,20 @@ 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}",
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
{
m_log.ErrorFormat(
"[CAPS]: Handler with name {0} already registered (ulr {1}, agent {2}, region {3}",
capName, pollServiceHandler.Url, m_agentID, m_regionName);
return;
}
m_pollServiceHandlers.Add(capName, pollServiceHandler);
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler);
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
// string protocol = "http";
// string hostName = m_httpListenerHostName;
//
//
// if (MainServer.Instance.UseSSL)
// {
// hostName = MainServer.Instance.SSLCommonName;
@ -254,9 +197,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)
@ -288,13 +230,16 @@ namespace OpenSim.Framework.Capabilities
string hostName = m_httpListenerHostName;
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
string protocol = "http";
if (MainServer.Instance.UseSSL)
{
hostName = MainServer.Instance.SSLCommonName;
port = MainServer.Instance.SSLPort;
protocol = "https";
}
//
// caps.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 +253,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);
}
}
}

View File

@ -27,7 +27,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
@ -41,7 +40,6 @@ namespace OpenSim.Framework.Capabilities
public class CapsHandlers
{
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
private ConcurrentDictionary<string, ISimpleStreamHandler> m_capsSimpleHandlers = new ConcurrentDictionary<string, ISimpleStreamHandler>();
private IHttpServer m_httpListener;
private string m_httpListenerHostName;
private uint m_httpListenerPort;
@ -55,15 +53,31 @@ namespace OpenSim.Framework.Capabilities
/// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP server</param>
/// <param name="httpListenerPort">HTTP port</param>
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
{
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
: this(httpListener,httpListenerHostname,httpListenerPort, false)
{
}
/// <summary></summary>
/// CapsHandlers is a cap handler container but also takes
/// care of adding and removing cap handlers to and from the
/// supplied BaseHttpServer.
/// </summary>
/// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP
/// server</param>
/// <param name="httpListenerPort">HTTP port</param>
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https)
{
m_httpListener = httpListener;
m_httpListenerHostName = httpListenerHostname;
m_httpListenerPort = httpListenerPort;
if (httpListener != null && httpListener.UseSSL)
m_useSSL = true;
else
m_useSSL = false;
m_useSSL = https;
if (httpListener != null && m_useSSL)
{
m_httpListenerHostName = httpListener.SSLCommonName;
m_httpListenerPort = httpListener.SSLPort;
}
}
/// <summary>
@ -75,35 +89,16 @@ namespace OpenSim.Framework.Capabilities
{
lock (m_capsHandlers)
{
if(m_capsHandlers.ContainsKey(capsName))
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}
if(m_capsSimpleHandlers.TryRemove(capsName, out ISimpleStreamHandler hdr))
{
m_httpListener.RemoveSimpleStreamHandler(hdr.Path);
}
}
public void AddSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
{
if(ContainsCap(capName))
Remove(capName);
if(m_capsSimpleHandlers.TryAdd(capName, handler) && addToListener)
m_httpListener.AddSimpleStreamHandler(handler);
}
public bool ContainsCap(string cap)
{
lock (m_capsHandlers)
if (m_capsHandlers.ContainsKey(cap))
return true;
return m_capsSimpleHandlers.ContainsKey(cap);
return m_capsHandlers.ContainsKey(cap);
}
/// <summary>
@ -130,14 +125,11 @@ 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);
}
if (null == value) return;
m_capsHandlers[idx] = value;
m_httpListener.AddStreamHandler(value);
}
@ -154,9 +146,8 @@ namespace OpenSim.Framework.Capabilities
{
lock (m_capsHandlers)
{
string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
string[] __keys = new string[m_capsHandlers.Keys.Count];
m_capsHandlers.Keys.CopyTo(__keys, 0);
m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
return __keys;
}
}
@ -170,39 +161,24 @@ namespace OpenSim.Framework.Capabilities
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
{
Hashtable caps = new Hashtable();
string protocol = "http://";
if (m_useSSL)
protocol = "https://";
string protocol = m_useSSL ? "https://" : "http://";
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
if (requestedCaps == null)
{
lock (m_capsHandlers)
{
foreach (KeyValuePair<string, ISimpleStreamHandler> kvp in m_capsSimpleHandlers)
caps[kvp.Key] = baseUrl + kvp.Value.Path;
foreach (KeyValuePair<string, IRequestHandler> kvp in m_capsHandlers)
caps[kvp.Key] = baseUrl + kvp.Value.Path;
}
return caps;
}
lock (m_capsHandlers)
{
for(int i = 0; i < requestedCaps.Count; ++i)
foreach (string capsName in m_capsHandlers.Keys)
{
string capsName = requestedCaps[i];
if (excludeSeed && "SEED" == capsName)
continue;
if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
{
caps[capsName] = baseUrl + shdr.Path;
if (requestedCaps != null && !requestedCaps.Contains(capsName))
continue;
}
if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
{
caps[capsName] = baseUrl + chdr.Path;
}
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
}
}

View File

@ -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);
}
}
}

View File

@ -29,12 +29,9 @@ 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
{
@ -70,16 +67,16 @@ namespace OpenSim.Capabilities.Handlers
m_LibraryService =
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
ISimpleStreamHandler reqHandler
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
});
server.AddSimpleStreamHandler(reqHandler);
IRequestHandler reqHandler
= new RestStreamHandler(
"POST",
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
webFetchHandler.FetchInventoryDescendentsRequest,
"FetchInvDescendents",
null);
server.AddStreamHandler(reqHandler);
}
}
}

View File

@ -25,12 +25,11 @@
* 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.Capabilities;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
@ -60,107 +59,83 @@ namespace OpenSim.Capabilities.Handlers
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
OSDArray itemsRequested = (OSDArray)requestmap["items"];
string reply;
LLSDFetchInventory llsdReply = new LLSDFetchInventory();
UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0;
foreach (OSDMap osdItemId in itemsRequested)
{
itemIDs[i++] = osdItemId["item_id"].AsUUID();
}
InventoryItemBase[] items = null;
InventoryItemBase[] items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
if (m_agentID != UUID.Zero)
{
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
}
else
if (items == null)
{
// OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
m_log.WarnFormat("[FETCH INVENTORY HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
items = new InventoryItemBase[itemsRequested.Count];
i = 0;
InventoryItemBase item = new InventoryItemBase();
item.Owner = m_agentID;
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);
item.ID = id;
items[i++] = m_inventoryService.GetItem(item);
}
LLSDxmlEncode.AddEndArray(lsl);
}
}
LLSDxmlEncode.AddEndMap(lsl);
return LLSDxmlEncode.End(lsl);
foreach (InventoryItemBase item in items)
{
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;
}
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
/// <summary>
/// Convert an internal inventory item object into an LLSD object.
/// </summary>
/// <param name="invItem"></param>
/// <returns></returns>
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
{
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
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;
if(BadRequests == null)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
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;
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;
return llsdItem;
}
}
}
}

View File

@ -120,7 +120,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
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");

View File

@ -28,7 +28,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using log4net;
using log4net.Config;
@ -46,7 +46,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
[TestFixture]
public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase
{
private UUID m_userID = new UUID("00000000-0000-0000-0000-000000000001");
private UUID m_userID = UUID.Zero;
private Scene m_scene;
private UUID m_rootFolderID;
private int m_rootDescendents;
@ -103,7 +103,6 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
// 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
@ -127,19 +126,6 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
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()
{
@ -148,18 +134,18 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
Init();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
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);
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 = handler.FetchInventoryDescendentsRequest(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("00000000-0000-0000-0000-000000000000"), 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");
@ -172,17 +158,19 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
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 += "</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-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
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);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
@ -200,12 +188,14 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
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>";
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);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string descendents = "descendents</key><integer>2</integer>";
@ -213,7 +203,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
// 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");
@ -225,11 +215,10 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
// 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");
@ -242,6 +231,8 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
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>";
@ -258,7 +249,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
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);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
@ -275,26 +266,27 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
[Test]
public void Test_005_FolderZero()
{
TestHelpers.InMethod();
Init();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
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);
string llsdresponse = handler.FetchInventoryDescendentsRequest(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");
// 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");
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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.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;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
namespace OpenSim.Capabilities.Handlers
{
public class GetDisplayNamesHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IUserManagement m_UserManagement;
public GetDisplayNamesHandler(string path, IUserManagement umService, string name, string description)
: base("GET", path, name, description)
{
m_UserManagement = umService;
}
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query);
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string[] ids = query.GetValues("ids");
if (m_UserManagement == null)
{
m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
return new byte[0];
}
OSDMap osdReply = new OSDMap();
OSDArray agents = new OSDArray();
osdReply["agents"] = agents;
foreach (string id in ids)
{
UUID uuid = UUID.Zero;
if (UUID.TryParse(id, out uuid))
{
string name = m_UserManagement.GetUserName(uuid);
if (!string.IsNullOrEmpty(name))
{
string[] parts = name.Split(new char[] {' '});
OSDMap osdname = new OSDMap();
osdname["display_name_next_update"] = OSD.FromDate(DateTime.MinValue);
osdname["display_name_expires"] = OSD.FromDate(DateTime.Now.AddMonths(1));
osdname["display_name"] = OSD.FromString(name);
osdname["legacy_first_name"] = parts[0];
osdname["legacy_last_name"] = parts[1];
osdname["username"] = OSD.FromString(name);
osdname["id"] = OSD.FromUUID(uuid);
osdname["is_display_name_default"] = OSD.FromBoolean(true);
agents.Add(osdname);
}
}
}
// Full content request
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
//httpResponse.ContentLength = ??;
httpResponse.ContentType = "application/llsd+xml";
string reply = OSDParser.SerializeLLSDXmlString(osdReply);
return System.Text.Encoding.UTF8.GetBytes(reply);
}
}
}

View File

@ -35,13 +35,13 @@ using OpenMetaverse;
namespace OpenSim.Capabilities.Handlers
{
public class FetchInventory2ServerConnector : ServiceConnector
public class GetDisplayNamesServerConnector : ServiceConnector
{
private IInventoryService m_InventoryService;
private IUserManagement m_UserManagement;
private string m_ConfigName = "CapsService";
public FetchInventory2ServerConnector(IConfigSource config, IHttpServer server, string configName)
: base(config, server, configName)
public GetDisplayNamesServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
if (configName != String.Empty)
m_ConfigName = configName;
@ -50,22 +50,22 @@ namespace OpenSim.Capabilities.Handlers
if (serverConfig == null)
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
string invService = serverConfig.GetString("InventoryService", String.Empty);
string umService = serverConfig.GetString("AssetService", String.Empty);
if (invService == String.Empty)
throw new Exception("No InventoryService in config file");
if (umService == String.Empty)
throw new Exception("No AssetService in config file");
Object[] args = new Object[] { config };
m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
m_UserManagement =
ServerUtils.LoadPlugin<IUserManagement>(umService, args);
if (m_InventoryService == null)
throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
if (m_UserManagement == null)
throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName));
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero);
IRequestHandler reqHandler
= new RestStreamHandler(
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
server.AddStreamHandler(reqHandler);
string rurl = serverConfig.GetString("GetTextureRedirectURL");
server.AddStreamHandler(
new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null));
}
}
}
}

View File

@ -25,131 +25,229 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using System;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Web;
namespace OpenSim.Capabilities.Handlers
{
public class GetMeshHandler
public class GetMeshHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_assetService;
public const string DefaultFormat = "vnd.ll.mesh";
// TODO: Change this to a config option
private string m_RedirectURL = null;
public GetMeshHandler(IAssetService assService)
public GetMeshHandler(string path, IAssetService assService, string name, string description, string redirectURL)
: base("GET", path, name, description)
{
m_assetService = assService;
}
public Hashtable Handle(Hashtable request)
{
return ProcessGetMesh(request, UUID.Zero, null); ;
m_RedirectURL = redirectURL;
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
m_RedirectURL += "/";
}
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
Hashtable responsedata = new Hashtable();
// Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string textureStr = query.GetOne("mesh_id");
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;
m_log.Error("[GETMESH]: Cannot fetch mesh " + textureStr + " without an asset service");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
}
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
responsedata["content_type"] = "text/plain";
responsedata["int_bytes"] = 0;
string meshStr = string.Empty;
if (request.ContainsKey("mesh_id"))
meshStr = request["mesh_id"].ToString();
if (String.IsNullOrEmpty(meshStr))
return responsedata;
UUID meshID = UUID.Zero;
if(!UUID.TryParse(meshStr, out meshID))
return responsedata;
AssetBase mesh = m_assetService.Get(meshID.ToString());
if(mesh == null)
UUID meshID;
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out meshID))
{
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
responsedata["str_response_string"] = "Mesh not found.";
return responsedata;
}
// OK, we have an array with preferred formats, possibly with only one entry
if (mesh.Type != (SByte)AssetType.Mesh)
{
responsedata["str_response_string"] = "Asset isn't a mesh.";
return responsedata;
}
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
AssetBase mesh;
string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
responsedata["content_type"] = "application/vnd.ll.mesh";
if (String.IsNullOrEmpty(range))
{
// full mesh
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
return responsedata;
}
// range request
int start, end;
if (Util.TryParseHttpRange(range, out start, out end))
{
// Before clamping start make sure we can satisfy it in order to avoid
// sending back the last byte instead of an error status
if (start >= mesh.Data.Length)
if (!String.IsNullOrEmpty(m_RedirectURL))
{
responsedata["str_response_string"] = "This range doesnt exist.";
return responsedata;
// Only try to fetch locally cached meshes. Misses are redirected
mesh = m_assetService.GetCached(meshID.ToString());
if (mesh != null)
{
if (mesh.Type != (sbyte)AssetType.Mesh)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
}
WriteMeshData(httpRequest, httpResponse, mesh);
}
else
{
string textureUrl = m_RedirectURL + "?mesh_id="+ meshID.ToString();
m_log.Debug("[GETMESH]: Redirecting mesh request to " + textureUrl);
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
httpResponse.RedirectLocation = textureUrl;
return null;
}
}
else // no redirect
{
// try the cache
mesh = m_assetService.GetCached(meshID.ToString());
if (mesh == null)
{
// Fetch locally or remotely. Misses return a 404
mesh = m_assetService.Get(meshID.ToString());
if (mesh != null)
{
if (mesh.Type != (sbyte)AssetType.Mesh)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return null;
}
WriteMeshData(httpRequest, httpResponse, mesh);
return null;
}
}
else // it was on the cache
{
if (mesh.Type != (sbyte)AssetType.Mesh)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return null;
}
WriteMeshData(httpRequest, httpResponse, mesh);
return null;
}
}
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;
// not found
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return null;
}
else
{
m_log.Warn("[GETTEXTURE]: Failed to parse a mesh_id from GetMesh request: " + httpRequest.Url);
}
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
return responsedata;
return null;
}
private void WriteMeshData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture)
{
string range = request.Headers.GetOne("Range");
if (!String.IsNullOrEmpty(range))
{
// 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)
{
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;
if (0 == start && len == texture.Data.Length)
{
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
}
else
{
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
}
response.ContentLength = len;
response.ContentType = "application/vnd.ll.mesh";
response.Body.Write(texture.Data, start, len);
}
}
else
{
m_log.Warn("[GETMESH]: Malformed Range header: " + range);
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
}
}
else
{
// Full content request
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.ContentLength = texture.Data.Length;
response.ContentType = "application/vnd.ll.mesh";
response.Body.Write(texture.Data, 0, 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;
}
}
}

View File

@ -64,15 +64,13 @@ namespace OpenSim.Capabilities.Handlers
string rurl = serverConfig.GetString("GetMeshRedirectURL");
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
IRequestHandler reqHandler
= new RestHTTPHandler(
"GET",
"/" + UUID.Random(),
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
"GetMesh",
null);
server.AddStreamHandler(reqHandler); ;
server.AddStreamHandler(
new GetTextureHandler("/CAPS/GetMesh/" /*+ UUID.Random() */, m_AssetService, "GetMesh", null, rurl));
rurl = serverConfig.GetString("GetMesh2RedirectURL");
server.AddStreamHandler(
new GetTextureHandler("/CAPS/GetMesh2/" /*+ UUID.Random() */, m_AssetService, "GetMesh2", null, rurl));
}
}
}

View File

@ -47,41 +47,46 @@ 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
private string m_RedirectURL = null;
public GetTextureHandler(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 += "/";
}
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;
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))
{
@ -89,50 +94,41 @@ namespace OpenSim.Capabilities.Handlers
}
else
{
formats = new string[1] { DefaultFormat }; // default
if (((Hashtable)request["headers"])["Accept"] != null)
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
if (formats.Length == 0)
formats = new string[1] { DefaultFormat }; // default
}
// OK, we have an array with preferred formats, possibly with only one entry
bool foundtexture = false;
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
foreach (string f in formats)
{
foundtexture = FetchTexture(request, ret, textureID, f);
if (foundtexture)
if (FetchTexture(httpRequest, httpResponse, textureID, f))
break;
}
if (!foundtexture)
{
ret["int_response_code"] = 404;
ret["error_status_text"] = "not found";
ret["str_response_string"] = "not found";
ret["content_type"] = "text/plain";
ret["int_bytes"] = 0;
}
}
else
{
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
}
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
return ret;
return null;
}
/// <summary>
///
///
/// </summary>
/// <param name="httpRequest"></param>
/// <param name="httpResponse"></param>
/// <param name="textureID"></param>
/// <param name="format"></param>
/// <returns>False for "caller try another codec"; true otherwise</returns>
private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
{
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
AssetBase texture;
@ -141,76 +137,92 @@ namespace OpenSim.Capabilities.Handlers
if (format != DefaultFormat)
fullID = fullID + "-" + format;
// try the cache
texture = m_assetService.GetCached(fullID);
if (texture == null)
if (!String.IsNullOrEmpty(m_RedirectURL))
{
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
// Only try to fetch locally cached textures. Misses are redirected
texture = m_assetService.GetCached(fullID);
if (texture != null)
{
if (texture.Type != (sbyte)AssetType.Texture)
return true;
if (format == DefaultFormat)
{
WriteTextureData(request, response, texture, format);
return true;
}
else
{
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
newTexture.Data = ConvertTextureData(texture, format);
if (newTexture.Data.Length == 0)
return false; // !!! Caller try another codec, please!
newTexture.Flags = AssetFlags.Collectable;
newTexture.Temporary = true;
newTexture.Local = true;
m_assetService.Store(newTexture);
WriteTextureData(request, response, newTexture, format);
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
}
WriteTextureData(httpRequest, httpResponse, texture, format);
}
}
else // it was on the cache
{
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(request, response, texture, format);
return true;
}
else
{
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
httpResponse.RedirectLocation = textureUrl;
return true;
}
}
else // no redirect
{
// try the cache
texture = m_assetService.GetCached(fullID);
//response = new Hashtable();
if (texture == null)
{
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
if (texture != null)
{
if (texture.Type != (sbyte)AssetType.Texture)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
}
if (format == DefaultFormat)
{
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
else
{
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
newTexture.Data = ConvertTextureData(texture, format);
if (newTexture.Data.Length == 0)
return false; // !!! Caller try another codec, please!
newTexture.Flags = AssetFlags.Collectable;
newTexture.Temporary = true;
newTexture.Local = true;
m_assetService.Store(newTexture);
WriteTextureData(httpRequest, httpResponse, newTexture, format);
return true;
}
}
}
else // it was on the cache
{
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
}
//WriteTextureData(request,response,null,format);
// not found
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
return false;
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
}
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
{
Hashtable headers = new Hashtable();
response["headers"] = headers;
string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
string range = request.Headers.GetOne("Range");
if (!String.IsNullOrEmpty(range)) // JP2's only
{
// Range request
int start, end;
if (Util.TryParseHttpRange(range, out start, out end))
if (TryParseRange(range, out start, out end))
{
// Before clamping start make sure we can satisfy it in order to avoid
// sending back the last byte instead of an error status
@ -232,8 +244,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 +262,41 @@ namespace OpenSim.Capabilities.Handlers
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
response["content-type"] = texture.Metadata.ContentType;
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
// Always return PartialContent, even if the range covered the entire data length
// We were accidentally sending back 404 before in this situation
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
//
// We also do not want to send back OK even if the whole range was satisfiable since this causes
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
// if (end > maxEnd)
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
// else
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
byte[] d = new byte[len];
Array.Copy(texture.Data, start, d, 0, len);
response["bin_response_data"] = d;
response["int_bytes"] = len;
response.ContentLength = len;
response.ContentType = texture.Metadata.ContentType;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
response.Body.Write(texture.Data, start, len);
}
}
else
{
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
}
}
else // JP2's or other formats
{
// Full content request
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.ContentLength = texture.Data.Length;
if (format == DefaultFormat)
response["content_type"] = texture.Metadata.ContentType;
response.ContentType = texture.Metadata.ContentType;
else
response["content_type"] = "image/" + format;
response["bin_response_data"] = texture.Data;
response["int_bytes"] = texture.Data.Length;
// response.Body.Write(texture.Data, 0, texture.Data.Length);
response.ContentType = "image/" + format;
response.Body.Write(texture.Data, 0, texture.Data.Length);
}
// if (response.StatusCode < 200 || response.StatusCode > 299)
@ -289,41 +309,86 @@ namespace OpenSim.Capabilities.Handlers
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
}
/// <summary>
/// Parse a range header.
/// </summary>
/// <remarks>
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
/// Where there is no value, -1 is returned.
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
/// for start.</remarks>
/// <returns></returns>
/// <param name='header'></param>
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
private bool TryParseRange(string header, out int start, out int end)
{
start = end = 0;
if (header.StartsWith("bytes="))
{
string[] rangeValues = header.Substring(6).Split('-');
if (rangeValues.Length == 2)
{
if (!Int32.TryParse(rangeValues[0], out start))
return false;
string rawEnd = rangeValues[1];
if (rawEnd == "")
{
end = -1;
return true;
}
else if (Int32.TryParse(rawEnd, out end))
{
return true;
}
}
}
start = end = 0;
return false;
}
private byte[] ConvertTextureData(AssetBase texture, string format)
{
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
byte[] data = new byte[0];
MemoryStream imgstream = new MemoryStream();
Bitmap mTexture = null;
ManagedImage managedImage = null;
Image image = null;
Bitmap mTexture = new Bitmap(1, 1);
ManagedImage managedImage;
Image image = (Image)mTexture;
try
{
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
imgstream = new MemoryStream();
// Decode image to System.Drawing.Image
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
{
// Save to bitmap
mTexture = new Bitmap(image);
using(EncoderParameters myEncoderParameters = new EncoderParameters())
{
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
EncoderParameters myEncoderParameters = new EncoderParameters();
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
// Save bitmap to stream
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
if (codec != null)
{
mTexture.Save(imgstream, codec, myEncoderParameters);
// Save bitmap to stream
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
if (codec != null)
{
mTexture.Save(imgstream, codec, myEncoderParameters);
// Write the stream to a byte array for output
data = imgstream.ToArray();
}
else
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
data = imgstream.ToArray();
}
else
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
}
}
catch (Exception e)
@ -340,10 +405,11 @@ namespace OpenSim.Capabilities.Handlers
if (image != null)
image.Dispose();
if(managedImage != null)
managedImage.Clear();
if (imgstream != null)
{
imgstream.Close();
imgstream.Dispose();
}
}
return data;
@ -362,4 +428,4 @@ namespace OpenSim.Capabilities.Handlers
return null;
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -33,7 +33,6 @@ using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using OpenMetaverse;
namespace OpenSim.Capabilities.Handlers
{
public class GetTextureServerConnector : ServiceConnector
@ -66,8 +65,7 @@ namespace OpenSim.Capabilities.Handlers
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, rurl));
}
}
}
}

View File

@ -38,7 +38,6 @@ using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
/*
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
{
[TestFixture]
@ -60,5 +59,4 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
}
}
}
*/
}

View File

@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -25,9 +25,9 @@ using System.Runtime.InteropServices;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
[assembly: AssemblyVersion("0.8.3.*")]

View File

@ -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;
}
}
}

View File

@ -29,35 +29,48 @@ 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.GridUser
namespace OpenSim.Capabilities.Handlers
{
public class MuteListServiceConnector : ServiceConnector
public class UploadBakedTextureServerConnector : ServiceConnector
{
private IMuteListService m_MuteListService;
private string m_ConfigName = "MuteListService";
private IAssetService m_AssetService;
private string m_ConfigName = "CapsService";
public MuteListServiceConnector(IConfigSource config, IHttpServer server, string configName) :
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
if (configName != String.Empty)
m_ConfigName = configName;
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
string service = serverConfig.GetString("LocalServiceModule", String.Empty);
string assetService = serverConfig.GetString("AssetService", String.Empty);
if (service == String.Empty)
throw new Exception("LocalServiceModule not present in MuteListService config file MuteListService section");
if (assetService == String.Empty)
throw new Exception("No AssetService in config file");
Object[] args = new Object[] { config };
m_MuteListService = ServerUtils.LoadPlugin<IMuteListService>(service, args);
m_AssetService =
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
if (m_AssetService == null)
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
server.AddStreamHandler(new MuteListServerPostHandler(m_MuteListService, auth));
}
// NEED TO FIX THIS
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
server.AddStreamHandler(new RestStreamHandler(
"POST",
"/CAPS/UploadBakedTexture/",
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
"UploadBakedTexture",
"Upload Baked Texture Capability"));
}
}
}
}

View File

@ -107,17 +107,17 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns>
public static byte[] LLSDSerialize(object obj)
{
using(StringWriter sw = new StringWriter())
using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None;
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
LLSDWriteOne(writer, obj);
writer.WriteEndElement();
writer.Flush();
return Util.UTF8.GetBytes(sw.ToString());
}
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
LLSDWriteOne(writer, obj);
writer.WriteEndElement();
writer.Close();
return Util.UTF8.GetBytes(sw.ToString());
}
/// <summary>
@ -566,7 +566,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");

View File

@ -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()
{

View File

@ -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()
{
}

View File

@ -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
{
@ -78,7 +47,7 @@ namespace OpenSim.Framework.Capabilities
public string state;
public int upload_price;
public string rsvp;
public LLSDNewFileAngentInventoryVariablePriceReplyResponse()
{
state = "confirm_upload";

View File

@ -42,7 +42,7 @@ namespace OpenSim.Framework.Capabilities
{
public string username;
public string display_name;
//'display_name_next_update':d"1970-01-01T00:00:00Z"
//'display_name_next_update':d"1970-01-01T00:00:00Z"
public string legacy_first_name;
public string legacy_last_name;
public UUID id;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -25,56 +25,44 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
namespace OpenSim.Framework
namespace OpenSim.Framework.Capabilities
{
public enum ObjectChangeType : uint
[OSDMap]
public class LLSDEnvironmentRequest
{
// bits definitions
Position = 0x01,
Rotation = 0x02,
Scale = 0x04,
Group = 0x08,
UniformScale = 0x10,
// macros from above
// single prim
primP = 0x01,
primR = 0x02,
primPR = 0x03,
primS = 0x04,
primPS = 0x05,
primRS = 0x06,
primPSR = 0x07,
primUS = 0x14,
primPUS = 0x15,
primRUS = 0x16,
primPUSR = 0x17,
// group
groupP = 0x09,
groupR = 0x0A,
groupPR = 0x0B,
groupS = 0x0C,
groupPS = 0x0D,
groupRS = 0x0E,
groupPSR = 0x0F,
groupUS = 0x1C,
groupPUS = 0x1D,
groupRUS = 0x1E,
groupPUSR = 0x1F,
PRSmask = 0x07
public UUID messageID;
public UUID regionID;
}
public struct ObjectChangeData
[OSDMap]
public class LLSDEnvironmentSetResponse
{
public Quaternion rotation;
public Vector3 position;
public Vector3 scale;
public ObjectChangeType change;
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);
}
}
}

View File

@ -30,7 +30,6 @@ using System.Collections;
using System.IO;
using System.Reflection;
using System.Xml;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
@ -41,32 +40,17 @@ namespace OpenSim.Framework.Capabilities
public static string SerialiseLLSDReply(object obj)
{
using(StringWriter sw = new StringWriter())
using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
SerializeOSDType(writer, obj);
writer.WriteEndElement();
writer.Flush();
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
SerializeOSDType(writer, obj);
writer.WriteEndElement();
writer.Close();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString();
}
}
public static string SerialiseLLSDReplyNoHeader(object obj)
{
using(StringWriter sw = new StringWriter())
using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None;
SerializeOSDType(writer, obj);
writer.Flush();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString();
}
return sw.ToString();
}
private static void SerializeOSDType(XmlTextWriter writer, object obj)
@ -173,22 +157,6 @@ namespace OpenSim.Framework.Capabilities
// the LLSD map/array types in the array need to be deserialised
// but first we need to know the right class to deserialise them into.
}
else if(enumerator.Value is Boolean && field.FieldType == typeof(int) )
{
int i = (bool)enumerator.Value ? 1 : 0;
field.SetValue(obj, i);
}
else if(field.FieldType == typeof(bool) && enumerator.Value is int)
{
bool b = (int)enumerator.Value != 0;
field.SetValue(obj, b);
}
else if(field.FieldType == typeof(UUID) && enumerator.Value is string)
{
UUID u;
UUID.TryParse((string)enumerator.Value, out u);
field.SetValue(obj, u);
}
else
{
field.SetValue(obj, enumerator.Value);

View File

@ -37,6 +37,5 @@ namespace OpenSim.Framework.Capabilities
public string name;
public int type;
public int preferred_type;
public int version;
}
}

View File

@ -87,12 +87,12 @@ namespace OpenSim.Framework.Capabilities
[OSDMap]
public class LLSDInventoryFolderContents
{
public UUID agent_id;
public UUID agent_id;
public int descendents;
public UUID folder_id;
public UUID folder_id;
public OSDArray categories = new OSDArray();
public OSDArray items = new OSDArray();
public UUID owner_id;
public UUID owner_id;
public int version;
}

View File

@ -25,11 +25,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
public interface IUserAccountCacheModule
namespace OpenSim.Framework.Capabilities
{
void Remove(string name);
void Remove(UUID id);
[OSDMap]
public class LLSDItemUpdate
{
public UUID item_id;
public LLSDItemUpdate()
{
}
}
}

View File

@ -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;
}
}
}

View File

@ -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()
{
}
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Capabilities")]
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//

View File

@ -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)
@ -178,7 +178,7 @@ namespace OpenSim.ConsoleClient
Requester.MakeRequest(requestUrl, requestData, ReadResponses);
return;
}
List<string> lines = new List<string>();
foreach (XmlNode part in rootNodeL[0].ChildNodes)
@ -202,7 +202,7 @@ namespace OpenSim.ConsoleClient
string[] parts = l.Split(new char[] {':'}, 3);
if (parts.Length != 3)
continue;
if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++"))
prompt = parts[2];
else

View File

@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.ConsoleClient")]
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//

View File

@ -37,7 +37,7 @@ namespace OpenSim.Data
public abstract class AssetDataBase : IAssetDataPlugin
{
public abstract AssetBase GetAsset(UUID uuid);
public abstract bool StoreAsset(AssetBase asset);
public abstract void StoreAsset(AssetBase asset);
public abstract bool[] AssetsExist(UUID[] uuids);
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);

View File

@ -38,7 +38,7 @@ namespace OpenSim.Data
/// <summary>This function converts a value returned from the database in one of the
/// supported formats into a UUID. This function is not actually DBMS-specific right
/// now
///
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
@ -47,25 +47,24 @@ namespace OpenSim.Data
if ((id == null) || (id == DBNull.Value))
return UUID.Zero;
Type idtype = id.GetType();
if (idtype == typeof(Guid))
if (id.GetType() == typeof(Guid))
return new UUID((Guid)id);
if (id.GetType() == typeof(string))
if (id.GetType() == typeof(byte[]))
{
Guid gg;
if (Guid.TryParse((string)id, out gg))
return new UUID(gg);
return UUID.Zero;
if (((byte[])id).Length == 0)
return UUID.Zero;
else if (((byte[])id).Length == 16)
return new UUID((byte[])id, 0);
}
else if (id.GetType() == typeof(string))
{
if (((string)id).Length == 0)
return UUID.Zero;
else if (((string)id).Length == 36)
return new UUID((string)id);
}
if (idtype == typeof(byte[]))
{
if (((byte[])id).Length < 16)
return UUID.Zero;
return new UUID((byte[])id, 0);
}
throw new Exception("Failed to convert db value to UUID: " + id.ToString());
}
}

View File

@ -34,7 +34,7 @@ namespace OpenSim.Data
public interface IAssetDataPlugin : IPlugin
{
AssetBase GetAsset(UUID uuid);
bool StoreAsset(AssetBase asset);
void StoreAsset(AssetBase asset);
bool[] AssetsExist(UUID[] uuids);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect);

View File

@ -39,7 +39,7 @@ namespace OpenSim.Data
public Dictionary<string, string> Data;
}
public interface IAvatarData
public interface IAvatarData
{
AvatarBaseData[] Get(string field, string val);
bool Store(AvatarBaseData data);

View File

@ -46,14 +46,14 @@ namespace OpenSim.Data
/// <param name="create">If true, then an estate is created if one is not found.</param>
/// <returns></returns>
EstateSettings LoadEstateSettings(UUID regionID, bool create);
/// <summary>
/// Load estate settings for an estate ID.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Create a new estate.
/// </summary>
@ -67,7 +67,7 @@ namespace OpenSim.Data
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<EstateSettings> LoadEstateSettingsAll();
/// <summary>
/// Store estate settings.
/// </summary>
@ -75,7 +75,7 @@ namespace OpenSim.Data
/// This is also called by EstateSettings.Save()</remarks>
/// <param name="es"></param>
void StoreEstateSettings(EstateSettings es);
/// <summary>
/// Get estate IDs.
/// </summary>
@ -88,13 +88,13 @@ namespace OpenSim.Data
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<int> GetEstatesByOwner(UUID ownerID);
/// <summary>
/// Get the IDs of all estates.
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<int> GetEstatesAll();
/// <summary>
/// Link a region to an estate.
/// </summary>
@ -102,14 +102,14 @@ namespace OpenSim.Data
/// <param name="estateID"></param>
/// <returns>true if the link succeeded, false otherwise</returns>
bool LinkRegion(UUID regionID, int estateID);
/// <summary>
/// Get the UUIDs of all the regions in an estate.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
List<UUID> GetRegions(int estateID);
/// <summary>
/// Delete an estate
/// </summary>

View File

@ -47,7 +47,7 @@ namespace OpenSim.Data
/// <summary>
/// An interface for connecting to the user grid datastore
/// </summary>
public interface IGridUserData
public interface IGridUserData
{
GridUserData Get(string userID);
GridUserData[] GetAll(string query);

View File

@ -81,7 +81,7 @@ namespace OpenSim.Data
}
public interface IGroupsData
public interface IGroupsData
{
// groups table
bool StoreGroup(GroupData data);

View File

@ -48,7 +48,7 @@ namespace OpenSim.Data
/// <summary>
/// An interface for connecting to the user grid datastore
/// </summary>
public interface IHGTravelingData
public interface IHGTravelingData
{
HGTravelingData Get(UUID sessionID);
HGTravelingData[] GetSessions(UUID userID);

View File

@ -39,7 +39,7 @@ namespace OpenSim.Data
}
public interface IOfflineIMData
public interface IOfflineIMData
{
OfflineIMData[] Get(string field, string val);
long GetCount(string field, string key);

View File

@ -44,7 +44,7 @@ namespace OpenSim.Data
/// <summary>
/// An interface for connecting to the presence datastore
/// </summary>
public interface IPresenceData
public interface IPresenceData
{
bool Store(PresenceData data);

View File

@ -48,7 +48,7 @@ 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 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);

View File

@ -67,12 +67,10 @@ namespace OpenSim.Data
/// <summary>
/// An interface for connecting to the authentication datastore
/// </summary>
public interface IRegionData
public interface IRegionData
{
RegionData Get(UUID regionID, UUID ScopeID);
List<RegionData> Get(string regionName, UUID ScopeID);
RegionData GetSpecific(string regionName, UUID ScopeID);
RegionData Get(int x, int y, UUID ScopeID);
List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);

View File

@ -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);
}
}

View File

@ -38,12 +38,12 @@ namespace OpenSim.Data
public UUID ownerRoleID;
public string name;
public string charter;
public bool showInList;
public UUID insigniaID;
public bool showInList;
public UUID insigniaID;
public int membershipFee;
public bool openEnrollment;
public bool allowPublish;
public bool maturePublish;
public bool maturePublish;
public UUID founderID;
public ulong everyonePowers;
public ulong ownersPowers;

View File

@ -80,10 +80,10 @@ namespace OpenSim.Data
/// <summary>Have the parameterless constructor just so we can specify it as a generic parameter with the new() constraint.
/// Currently this is only used in the tests. A Migration instance created this way must be then
/// initialized with Initialize(). Regular creation should be through the parameterized constructors.
/// initialized with Initialize(). Regular creation should be through the parameterized constructors.
/// </summary>
public Migration()
{
{
}
public Migration(DbConnection conn, Assembly assem, string subtype, string type)
@ -91,7 +91,7 @@ namespace OpenSim.Data
Initialize(conn, assem, type, subtype);
}
public Migration(DbConnection conn, Assembly assem, string type)
public Migration(DbConnection conn, Assembly assem, string type)
{
Initialize(conn, assem, type, "");
}
@ -191,7 +191,7 @@ namespace OpenSim.Data
int newversion = kvp.Key;
// we need to up the command timeout to infinite as we might be doing long migrations.
/* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like
/* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like
* stored proc definitions might have to be sent to the server each in a separate batch.
* This is certainly so for MS SQL; not sure how the MySQL connector sorts out the mess
* with 'delimiter @@'/'delimiter ;' around procs. So each "script" this code executes now is not
@ -276,7 +276,7 @@ namespace OpenSim.Data
private delegate void FlushProc();
/// <summary>Scans for migration resources in either old-style "scattered" (one file per version)
/// or new-style "integrated" format (single file with ":VERSION nnn" sections).
/// or new-style "integrated" format (single file with ":VERSION nnn" sections).
/// In the new-style migrations it also recognizes ':GO' separators for parts of the SQL script
/// that must be sent to the server separately. The old-style migrations are loaded each in one piece
/// and don't support the ':GO' feature.
@ -301,12 +301,12 @@ namespace OpenSim.Data
{
/* The filename should be '<StoreName>.migrations[.NNN]' where NNN
* is the last version number defined in the file. If the '.NNN' part is recognized, the code can skip
* the file without looking inside if we have a higher version already. Without the suffix we read
* the file without looking inside if we have a higher version already. Without the suffix we read
* the file anyway and use the version numbers inside. Any unrecognized suffix (such as '.sql')
* is valid but ignored.
*
* NOTE that we expect only one 'merged' migration file. If there are several, we take the last one.
* If you are numbering them, leave only the latest one in the project or at least make sure they numbered
*
* NOTE that we expect only one 'merged' migration file. If there are several, we take the last one.
* If you are numbering them, leave only the latest one in the project or at least make sure they numbered
* to come up in the correct order (e.g. 'SomeStore.migrations.001' rather than 'SomeStore.migrations.1')
*/
@ -351,7 +351,7 @@ namespace OpenSim.Data
if (sLine.Trim().Equals(":GO", StringComparison.InvariantCultureIgnoreCase))
{
if (sb.Length == 0) continue;
if (nVersion > after)
if (nVersion > after)
script.Add(sb.ToString());
sb.Length = 0;
continue;
@ -405,10 +405,10 @@ scan_old_style:
}
}
}
if (migrations.Count < 1)
if (migrations.Count < 1)
m_log.DebugFormat("[MIGRATIONS]: {0} data tables already up to date at revision {1}", _type, after);
return migrations;
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*

View File

@ -75,7 +75,6 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "AssetStore");
m.Update();
dbcon.Close();
}
}
@ -145,7 +144,6 @@ namespace OpenSim.Data.MySQL
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
}
}
dbcon.Close();
}
return asset;
@ -156,62 +154,65 @@ namespace OpenSim.Data.MySQL
/// </summary>
/// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public bool StoreAsset(AssetBase asset)
override public void StoreAsset(AssetBase asset)
{
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
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)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
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 (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
dbcon))
{
string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
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)
{
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
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);
}
try
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
dbcon.Close();
return true;
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
dbcon.Close();
return false;
m_log.Error(
string.Format(
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
asset.FullID, asset.Name)
, e);
}
}
}
}
}
@ -226,22 +227,24 @@ namespace OpenSim.Data.MySQL
{
try
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
asset.FullID, asset.Name),
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
asset.FullID, asset.Name),
e);
}
}
dbcon.Close();
}
}
@ -274,7 +277,6 @@ namespace OpenSim.Data.MySQL
}
}
}
dbcon.Close();
}
bool[] results = new bool[uuids.Length];
@ -334,12 +336,11 @@ namespace OpenSim.Data.MySQL
{
m_log.Error(
string.Format(
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
start, count),
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
start, count),
e);
}
}
dbcon.Close();
}
return retList;
@ -356,7 +357,6 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
dbcon.Close();
}
return true;
@ -364,4 +364,4 @@ namespace OpenSim.Data.MySQL
#endregion
}
}
}

View File

@ -59,7 +59,6 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "AuthStore");
m.Update();
dbcon.Close();
}
}
@ -77,30 +76,27 @@ namespace OpenSim.Data.MySQL
{
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
using(IDataReader result = cmd.ExecuteReader())
IDataReader result = cmd.ExecuteReader();
if (result.Read())
{
if(result.Read())
ret.PrincipalID = principalID;
CheckColumnNames(result);
foreach (string s in m_ColumnNames)
{
ret.PrincipalID = principalID;
CheckColumnNames(result);
foreach(string s in m_ColumnNames)
{
if(s == "UUID")
continue;
ret.Data[s] = result[s].ToString();
}
dbcon.Close();
return ret;
}
else
{
dbcon.Close();
return null;
if (s == "UUID")
continue;
ret.Data[s] = result[s].ToString();
}
return ret;
}
else
{
return null;
}
}
}
@ -136,25 +132,25 @@ namespace OpenSim.Data.MySQL
if (!first)
update += ", ";
update += "`" + field + "` = ?"+field;
first = false;
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
}
update += " where UUID = ?principalID";
cmd.CommandText = update;
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
if (ExecuteNonQuery(cmd) < 1)
{
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
String.Join("`, `", fields) +
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
cmd.CommandText = insert;
if (ExecuteNonQuery(cmd) < 1)
return false;
}
@ -170,7 +166,7 @@ namespace OpenSim.Data.MySQL
{
cmd.Parameters.AddWithValue("?"+item, value);
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}
@ -190,7 +186,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
cmd.Parameters.AddWithValue("?token", token);
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}

View File

@ -57,7 +57,7 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?Name", name);
if (ExecuteNonQuery(cmd) > 0)
return true;
}

View File

@ -82,7 +82,6 @@ namespace OpenSim.Data.MySQL
Migration m = new Migration(dbcon, Assembly, "EstateStore");
m.Update();
dbcon.Close();
Type t = typeof(EstateSettings);
m_Fields = t.GetFields(BindingFlags.NonPublic |
@ -144,6 +143,7 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
bool found = false;
@ -171,8 +171,6 @@ namespace OpenSim.Data.MySQL
}
}
}
dbcon.Close();
cmd.Connection = null;
if (!found && create)
{
@ -233,7 +231,6 @@ namespace OpenSim.Data.MySQL
es.Save();
}
dbcon.Close();
}
}
@ -266,7 +263,6 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery();
}
dbcon.Close();
}
SaveBanList(es);
@ -285,7 +281,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from estateban where EstateID = ?EstateID";
cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
using (IDataReader r = cmd.ExecuteReader())
@ -293,16 +289,17 @@ namespace OpenSim.Data.MySQL
while (r.Read())
{
EstateBan eb = new EstateBan();
eb.BannedUserID = DBGuid.FromDB(r["bannedUUID"]); ;
UUID uuid = new UUID();
UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
eb.BannedUserID = uuid;
eb.BannedHostAddress = "0.0.0.0";
eb.BannedHostIPMask = "0.0.0.0";
eb.BanningUserID = DBGuid.FromDB(r["banningUUID"]);
eb.BanTime = Convert.ToInt32(r["banTime"]);
es.AddBan(eb);
}
}
}
dbcon.Close();
}
}
@ -321,20 +318,17 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear();
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask, banningUUID, banTime) values ( ?EstateID, ?bannedUUID, '', '', '', ?banningUUID, ?banTime)";
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )";
foreach (EstateBan b in es.EstateBans)
{
cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString());
cmd.Parameters.AddWithValue("?banningUUID", b.BanningUserID.ToString());
cmd.Parameters.AddWithValue("?banTime", b.BanTime);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
dbcon.Close();
}
}
@ -364,7 +358,6 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear();
}
}
dbcon.Close();
}
}
@ -390,7 +383,6 @@ namespace OpenSim.Data.MySQL
}
}
}
dbcon.Close();
}
return uuids.ToArray();
@ -411,19 +403,19 @@ namespace OpenSim.Data.MySQL
return e;
}
}
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
List<int> allEstateIds = GetEstatesAll();
foreach (int estateId in allEstateIds)
allEstateSettings.Add(LoadEstateSettings(estateId));
return allEstateSettings;
}
public List<int> GetEstatesAll()
{
List<int> result = new List<int>();
@ -445,10 +437,11 @@ namespace OpenSim.Data.MySQL
reader.Close();
}
}
dbcon.Close();
}
return result;
return result;
}
public List<int> GetEstates(string search)
@ -473,6 +466,7 @@ namespace OpenSim.Data.MySQL
reader.Close();
}
}
dbcon.Close();
}

View File

@ -41,8 +41,10 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected MySqlConnection m_Connection = null;
protected string m_ConnectionString;
protected string m_Table;
protected Object m_connLock = new Object();
/// <summary>
/// Number of days that must pass before we update the access time on an asset when it has been fetched
@ -54,7 +56,7 @@ namespace OpenSim.Data.MySQL
{
get { return GetType().Assembly; }
}
public MySQLFSAssetData()
{
}
@ -73,13 +75,10 @@ namespace OpenSim.Data.MySQL
try
{
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
{
conn.Open();
Migration m = new Migration(conn, Assembly, "FSAssetStore");
m.Update();
conn.Close();
}
OpenDatabase();
Migration m = new Migration(m_Connection, Assembly, "FSAssetStore");
m.Update();
}
catch (MySqlException e)
{
@ -101,118 +100,135 @@ namespace OpenSim.Data.MySQL
#endregion
private bool ExecuteNonQuery(MySqlCommand cmd)
private bool OpenDatabase()
{
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
try
{
try
{
conn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
return false;
}
m_Connection = new MySqlConnection(m_ConnectionString);
cmd.Connection = conn;
try
{
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
cmd.Connection = null;
conn.Close();
m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString());
return false;
}
conn.Close();
cmd.Connection = null;
m_Connection.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}",
e.Message.ToString());
return false;
}
return true;
}
private IDataReader ExecuteReader(MySqlCommand c)
{
IDataReader r = null;
MySqlConnection connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
connection.Open();
c.Connection = connection;
r = c.ExecuteReader();
return r;
}
private void ExecuteNonQuery(MySqlCommand c)
{
lock (m_connLock)
{
bool errorSeen = false;
while (true)
{
try
{
c.ExecuteNonQuery();
}
catch (MySqlException)
{
System.Threading.Thread.Sleep(500);
m_Connection.Close();
m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
m_Connection.Open();
c.Connection = m_Connection;
if (!errorSeen)
{
errorSeen = true;
continue;
}
m_log.ErrorFormat("[FSASSETS] MySQL command: {0}", c.CommandText);
throw;
}
break;
}
}
}
#region IFSAssetDataPlugin Members
public AssetMetadata Get(string id, out string hash)
{
hash = String.Empty;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, access_time, asset_flags from {0} where id = ?id", m_Table);
cmd.Parameters.AddWithValue("?id", id);
IDataReader reader = ExecuteReader(cmd);
if (!reader.Read())
{
reader.Close();
FreeCommand(cmd);
return null;
}
AssetMetadata meta = new AssetMetadata();
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
{
try
{
conn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
return null;
}
hash = reader["hash"].ToString();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, asset_flags, access_time from {0} where id = ?id", m_Table);
cmd.Parameters.AddWithValue("?id", id);
meta.ID = id;
meta.FullID = new UUID(id);
using (IDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read())
return null;
meta.Name = reader["name"].ToString();
meta.Description = reader["description"].ToString();
meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
hash = reader["hash"].ToString();
int AccessTime = Convert.ToInt32(reader["access_time"]);
meta.ID = id;
meta.FullID = new UUID(id);
reader.Close();
meta.Name = reader["name"].ToString();
meta.Description = reader["description"].ToString();
meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
UpdateAccessTime(AccessTime, cmd);
int AccessTime = Convert.ToInt32(reader["access_time"]);
UpdateAccessTime(id, AccessTime);
}
}
conn.Close();
}
FreeCommand(cmd);
return meta;
}
private void UpdateAccessTime(string AssetID, int AccessTime)
private void UpdateAccessTime(int AccessTime, MySqlCommand cmd)
{
// Reduce DB work by only updating access time if asset hasn't recently been accessed
// 0 By Default, Config option is "DaysBetweenAccessTimeUpdates"
if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
return;
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
{
try
{
conn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
return;
}
cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table);
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table);
cmd.Parameters.AddWithValue("?id", AssetID);
cmd.ExecuteNonQuery();
}
conn.Close();
}
cmd.ExecuteNonQuery();
}
protected void FreeCommand(MySqlCommand cmd)
{
MySqlConnection c = cmd.Connection;
cmd.Dispose();
c.Close();
c.Dispose();
}
public bool Store(AssetMetadata meta, string hash)
@ -222,41 +238,37 @@ namespace OpenSim.Data.MySQL
string oldhash;
AssetMetadata existingAsset = Get(meta.ID, out oldhash);
using (MySqlCommand cmd = new MySqlCommand())
MySqlCommand cmd = m_Connection.CreateCommand();
cmd.Parameters.AddWithValue("?id", meta.ID);
cmd.Parameters.AddWithValue("?name", meta.Name);
cmd.Parameters.AddWithValue("?description", meta.Description);
cmd.Parameters.AddWithValue("?type", meta.Type.ToString());
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?asset_flags", meta.Flags);
if (existingAsset == null)
{
cmd.Parameters.AddWithValue("?id", meta.ID);
cmd.Parameters.AddWithValue("?name", meta.Name);
cmd.Parameters.AddWithValue("?description", meta.Description);
// cmd.Parameters.AddWithValue("?type", meta.Type.ToString());
cmd.Parameters.AddWithValue("?type", meta.Type);
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?asset_flags", meta.Flags);
cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table);
if (existingAsset == null)
{
cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table);
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd);
return true;
}
//cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table);
//ExecuteNonQuery(cmd);
cmd.Dispose();
return true;
}
// return false;
// if the asset already exits
// assume it was already correctly stored
// or regions will keep retry.
return true;
//cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table);
//ExecuteNonQuery(cmd);
cmd.Dispose();
return false;
}
catch(Exception e)
{
m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID);
m_log.Error(e.ToString());
m_log.Error(e.ToString());
return false;
}
}
@ -271,43 +283,26 @@ namespace OpenSim.Data.MySQL
if (uuids.Length == 0)
return new bool[0];
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = false;
HashSet<UUID> exists = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table);
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
using (MySqlCommand cmd = m_Connection.CreateCommand())
{
try
{
conn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
return results;
}
cmd.CommandText = sql;
using (MySqlCommand cmd = conn.CreateCommand())
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
cmd.CommandText = sql;
using (MySqlDataReader dbReader = cmd.ExecuteReader())
while (dbReader.Read())
{
while (dbReader.Read())
{
UUID id = DBGuid.FromDB(dbReader["ID"]);
exists.Add(id);
}
UUID id = DBGuid.FromDB(dbReader["ID"]);
exists.Add(id);
}
}
conn.Close();
}
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exists.Contains(uuids[i]);
return results;
@ -315,43 +310,27 @@ namespace OpenSim.Data.MySQL
public int Count()
{
int count = 0;
MySqlCommand cmd = m_Connection.CreateCommand();
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
{
try
{
conn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
return 0;
}
cmd.CommandText = String.Format("select count(*) as count from {0}", m_Table);
using(MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = String.Format("select count(*) as count from {0}",m_Table);
IDataReader reader = ExecuteReader(cmd);
using (IDataReader reader = cmd.ExecuteReader())
{
reader.Read();
reader.Read();
count = Convert.ToInt32(reader["count"]);
}
}
conn.Close();
}
int count = Convert.ToInt32(reader["count"]);
reader.Close();
FreeCommand(cmd);
return count;
}
public bool Delete(string id)
{
using(MySqlCommand cmd = new MySqlCommand())
using (MySqlCommand cmd = m_Connection.CreateCommand())
{
cmd.CommandText = String.Format("delete from {0} where id = ?id",m_Table);
cmd.CommandText = String.Format("delete from {0} where id = ?id", m_Table);
cmd.Parameters.AddWithValue("?id", id);
@ -363,67 +342,69 @@ namespace OpenSim.Data.MySQL
public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
{
MySqlConnection importConn;
try
{
importConn = new MySqlConnection(conn);
importConn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}",
e.Message.ToString());
return;
}
int imported = 0;
using (MySqlConnection importConn = new MySqlConnection(conn))
MySqlCommand cmd = importConn.CreateCommand();
string limit = String.Empty;
if (count != -1)
{
try
{
importConn.Open();
}
catch (MySqlException e)
{
m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}",
e.Message.ToString());
return;
}
using (MySqlCommand cmd = importConn.CreateCommand())
{
string limit = String.Empty;
if (count != -1)
{
limit = String.Format(" limit {0},{1}", start, count);
}
cmd.CommandText = String.Format("select * from {0}{1}", table, limit);
MainConsole.Instance.Output("Querying database");
using (IDataReader reader = cmd.ExecuteReader())
{
MainConsole.Instance.Output("Reading data");
while (reader.Read())
{
if ((imported % 100) == 0)
{
MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
}
AssetBase asset = new AssetBase();
AssetMetadata meta = new AssetMetadata();
meta.ID = reader["id"].ToString();
meta.FullID = new UUID(meta.ID);
meta.Name = reader["name"].ToString();
meta.Description = reader["description"].ToString();
meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
asset.Metadata = meta;
asset.Data = (byte[])reader["data"];
store(asset, force);
imported++;
}
}
}
importConn.Close();
limit = String.Format(" limit {0},{1}", start, count);
}
cmd.CommandText = String.Format("select * from {0}{1}", table, limit);
MainConsole.Instance.Output("Querying database");
IDataReader reader = cmd.ExecuteReader();
MainConsole.Instance.Output("Reading data");
while (reader.Read())
{
if ((imported % 100) == 0)
{
MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
}
AssetBase asset = new AssetBase();
AssetMetadata meta = new AssetMetadata();
meta.ID = reader["id"].ToString();
meta.FullID = new UUID(meta.ID);
meta.Name = reader["name"].ToString();
meta.Description = reader["description"].ToString();
meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
asset.Metadata = meta;
asset.Data = (byte[])reader["data"];
store(asset, force);
imported++;
}
reader.Close();
cmd.Dispose();
importConn.Close();
MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
}

View File

@ -36,7 +36,7 @@ using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL
{
/// <summary>
/// Common code for a number of database modules
/// A database interface class to a user profile storage system
/// </summary>
public class MySqlFramework
{
@ -44,78 +44,30 @@ namespace OpenSim.Data.MySQL
log4net.LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString = String.Empty;
protected MySqlTransaction m_trans = null;
protected string m_connectionString;
// Constructor using a connection string. Instances constructed
// this way will open a new connection for each call.
protected MySqlFramework(string connectionString)
{
m_connectionString = connectionString;
}
// Constructor using a connection object. Instances constructed
// this way will use the connection object and never create
// new connections.
protected MySqlFramework(MySqlTransaction trans)
{
m_trans = trans;
}
//////////////////////////////////////////////////////////////
//
// All non queries are funneled through one connection
// to increase performance a little
//
protected int ExecuteNonQuery(MySqlCommand cmd)
{
if (m_trans == null)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
int ret = ExecuteNonQueryWithConnection(cmd, dbcon);
dbcon.Close();
return ret;
}
}
else
{
return ExecuteNonQueryWithTransaction(cmd, m_trans);
}
}
private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
{
cmd.Transaction = trans;
return ExecuteNonQueryWithConnection(cmd, trans.Connection);
}
private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
{
try
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
try
{
int ret = cmd.ExecuteNonQuery();
cmd.Connection = null;
return ret;
return cmd.ExecuteNonQuery();
}
catch (Exception e)
{
m_log.Error(e.Message, e);
m_log.Error(Environment.StackTrace.ToString());
cmd.Connection = null;
return 0;
}
}
catch (Exception e)
{
m_log.Error(e.Message, e);
return 0;
}
}
}
}
}

View File

@ -29,16 +29,18 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Data.MySQL
{
public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new()
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Dictionary<string, FieldInfo> m_Fields =
new Dictionary<string, FieldInfo>();
@ -51,27 +53,14 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySQLGenericTableHandler(MySqlTransaction trans,
string realm, string storeName) : base(trans)
{
m_Realm = realm;
CommonConstruct(storeName);
}
public MySQLGenericTableHandler(string connectionString,
string realm, string storeName) : base(connectionString)
{
m_Realm = realm;
CommonConstruct(storeName);
}
protected void CommonConstruct(string storeName)
{
m_connectionString = connectionString;
if (storeName != String.Empty)
{
// We always use a new connection for any Migrations
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
@ -116,167 +105,102 @@ namespace OpenSim.Data.MySQL
}
public virtual T[] Get(string field, string key)
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Parameters.AddWithValue(field, key);
cmd.CommandText = string.Format("select * from {0} where `{1}` = ?{1}", m_Realm, field);
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 (MySqlCommand cmd = new MySqlCommand())
{
for (int i = 0 ; i < flen ; i++)
{
string fname = field + i.ToString();
cmd.Parameters.AddWithValue(fname, keys[i]);
sb.Append(fname);
if(i < flast)
sb.Append(",?");
else
sb.Append(")");
}
cmd.CommandText = sb.ToString();
return DoQuery(cmd);
}
return Get(new string[] { field }, new string[] { key });
}
public virtual T[] Get(string[] fields, string[] keys)
{
return Get(fields, keys, String.Empty);
}
public virtual T[] Get(string[] fields, string[] keys, string options)
{
int flen = fields.Length;
if (flen == 0 || flen != keys.Length)
if (fields.Length != keys.Length)
return new T[0];
int flast = flen - 1;
StringBuilder sb = new StringBuilder(1024);
sb.AppendFormat("select * from {0} where ", m_Realm);
List<string> terms = new List<string>();
using (MySqlCommand cmd = new MySqlCommand())
{
for (int i = 0 ; i < flen ; i++)
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.AddWithValue(fields[i], keys[i]);
if(i < flast)
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
else
sb.AppendFormat("`{0}` = ?{0} ", fields[i]);
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
}
sb.Append(options);
cmd.CommandText = sb.ToString();
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
cmd.CommandText = query;
return DoQuery(cmd);
}
}
protected T[] DoQuery(MySqlCommand cmd)
{
if (m_trans == null)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
T[] ret = DoQueryWithConnection(cmd, dbcon);
dbcon.Close();
return ret;
}
}
else
{
return DoQueryWithTransaction(cmd, m_trans);
}
}
protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
{
cmd.Transaction = trans;
return DoQueryWithConnection(cmd, trans.Connection);
}
protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
{
List<T> result = new List<T>();
cmd.Connection = dbcon;
using (IDataReader reader = cmd.ExecuteReader())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
if (reader == null)
return new T[0];
dbcon.Open();
cmd.Connection = dbcon;
CheckColumnNames(reader);
while (reader.Read())
using (IDataReader reader = cmd.ExecuteReader())
{
T row = new T();
if (reader == null)
return new T[0];
foreach (string name in m_Fields.Keys)
CheckColumnNames(reader);
while (reader.Read())
{
if (reader[name] is DBNull)
T row = new T();
foreach (string name in m_Fields.Keys)
{
continue;
if (reader[name] is DBNull)
{
continue;
}
if (m_Fields[name].FieldType == typeof(bool))
{
int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v != 0 ? true : false);
}
else if (m_Fields[name].FieldType == typeof(UUID))
{
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
}
else if (m_Fields[name].FieldType == typeof(int))
{
int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v);
}
else
{
m_Fields[name].SetValue(row, reader[name]);
}
}
if (m_Fields[name].FieldType == typeof(bool))
if (m_DataField != null)
{
int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v != 0);
}
else if (m_Fields[name].FieldType == typeof(UUID))
{
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
}
else if (m_Fields[name].FieldType == typeof(int))
{
int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v);
}
else if (m_Fields[name].FieldType == typeof(uint))
{
uint v = Convert.ToUInt32(reader[name]);
m_Fields[name].SetValue(row, v);
}
else
{
m_Fields[name].SetValue(row, reader[name]);
Dictionary<string, string> data =
new Dictionary<string, string>();
foreach (string col in m_ColumnNames)
{
data[col] = reader[col].ToString();
if (data[col] == null)
data[col] = String.Empty;
}
m_DataField.SetValue(row, data);
}
result.Add(row);
}
if (m_DataField != null)
{
Dictionary<string, string> data =
new Dictionary<string, string>();
foreach (string col in m_ColumnNames)
{
data[col] = reader[col].ToString();
if (data[col] == null)
data[col] = String.Empty;
}
m_DataField.SetValue(row, data);
}
result.Add(row);
}
}
cmd.Connection = null;
return result.ToArray();
}
@ -286,9 +210,9 @@ namespace OpenSim.Data.MySQL
{
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
cmd.CommandText = query;
return DoQuery(cmd);
}
}
@ -307,16 +231,16 @@ namespace OpenSim.Data.MySQL
{
names.Add(fi.Name);
values.Add("?" + fi.Name);
// Temporarily return more information about what field is unexpectedly null for
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
// 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(
"[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
"[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
fi.Name, row));
cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString());
}
@ -355,26 +279,25 @@ namespace OpenSim.Data.MySQL
// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
// string.Join(",", fields), string.Join(",", keys));
int flen = fields.Length;
if (flen == 0 || flen != keys.Length)
if (fields.Length != keys.Length)
return false;
int flast = flen - 1;
StringBuilder sb = new StringBuilder(1024);
sb.AppendFormat("delete from {0} where ", m_Realm);
List<string> terms = new List<string>();
using (MySqlCommand cmd = new MySqlCommand())
{
for (int i = 0 ; i < flen ; i++)
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.AddWithValue(fields[i], keys[i]);
if(i < flast)
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
else
sb.AppendFormat("`{0}` = ?{0}", fields[i]);
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
}
cmd.CommandText = sb.ToString();
string where = String.Join(" and ", terms.ToArray());
string query = String.Format("delete from {0} where {1}", m_Realm, where);
cmd.CommandText = query;
return ExecuteNonQuery(cmd) > 0;
}
}
@ -386,27 +309,27 @@ namespace OpenSim.Data.MySQL
public long GetCount(string[] fields, string[] keys)
{
int flen = fields.Length;
if (flen == 0 || flen != keys.Length)
if (fields.Length != keys.Length)
return 0;
int flast = flen - 1;
StringBuilder sb = new StringBuilder(1024);
sb.AppendFormat("select count(*) from {0} where ", m_Realm);
List<string> terms = new List<string>();
using (MySqlCommand cmd = new MySqlCommand())
{
for (int i = 0 ; i < flen ; i++)
for (int i = 0; i < fields.Length; i++)
{
cmd.Parameters.AddWithValue(fields[i], keys[i]);
if(i < flast)
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
else
sb.AppendFormat("`{0}` = ?{0}", fields[i]);
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
}
cmd.CommandText = sb.ToString();
object result = DoQueryScalar(cmd);
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);
}
@ -429,26 +352,14 @@ namespace OpenSim.Data.MySQL
public object DoQueryScalar(MySqlCommand cmd)
{
if (m_trans == null)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
object ret = cmd.ExecuteScalar();
cmd.Connection = null;
dbcon.Close();
return ret;
}
}
else
{
cmd.Connection = m_trans.Connection;
cmd.Transaction = m_trans;
dbcon.Open();
cmd.Connection = dbcon;
return cmd.ExecuteScalar();
}
}
}
}
}

View File

@ -90,7 +90,7 @@ namespace OpenSim.Data.MySQL
else
pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
return m_Groups.Get(string.Format("ShowInList=1 AND ({0})", pattern));
return m_Groups.Get(string.Format("ShowInList=1 AND ({0}) ORDER BY Name LIMIT 100", pattern));
}
public bool DeleteGroup(UUID groupID)
@ -133,10 +133,10 @@ namespace OpenSim.Data.MySQL
public bool DeleteMember(UUID groupID, string pricipalID)
{
return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
new string[] { groupID.ToString(), pricipalID });
}
public int MemberCount(UUID groupID)
{
return (int)m_Membership.GetCount("GroupID", groupID.ToString());
@ -168,7 +168,7 @@ namespace OpenSim.Data.MySQL
public bool DeleteRole(UUID groupID, UUID roleID)
{
return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
new string[] { groupID.ToString(), roleID.ToString() });
}
@ -360,7 +360,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
: base(connectionString, realm, store)
{
}
@ -375,7 +375,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsMembershipHandler(string connectionString, string realm)
public MySqlGroupsMembershipHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}
@ -390,7 +390,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsRolesHandler(string connectionString, string realm)
public MySqlGroupsRolesHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}
@ -405,7 +405,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}
@ -420,7 +420,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsInvitesHandler(string connectionString, string realm)
public MySqlGroupsInvitesHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}
@ -431,7 +431,8 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
ExecuteNonQuery(cmd);
}
@ -447,7 +448,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsNoticesHandler(string connectionString, string realm)
public MySqlGroupsNoticesHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}
@ -475,7 +476,7 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
: base(connectionString, realm, string.Empty)
{
}

View File

@ -78,7 +78,6 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
Migration m = new Migration(dbcon, assem, "InventoryStore");
m.Update();
dbcon.Close();
}
}
@ -131,7 +130,6 @@ namespace OpenSim.Data.MySQL
items.Add(item);
}
dbcon.Close();
return items;
}
}
@ -172,7 +170,6 @@ namespace OpenSim.Data.MySQL
while (reader.Read())
items.Add(readInventoryFolder(reader));
dbcon.Close();
return items;
}
}
@ -224,7 +221,6 @@ namespace OpenSim.Data.MySQL
if (items.Count > 0)
rootFolder = items[0];
dbcon.Close();
return rootFolder;
}
}
@ -265,7 +261,6 @@ namespace OpenSim.Data.MySQL
while (reader.Read())
items.Add(readInventoryFolder(reader));
dbcon.Close();
return items;
}
}
@ -293,7 +288,7 @@ namespace OpenSim.Data.MySQL
// TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these.
// (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero)
item.CreatorId = reader["creatorID"].ToString();
// Be a bit safer in parsing these because the
// database doesn't enforce them to be not null, and
// the inventory still works if these are weird in the
@ -357,7 +352,6 @@ namespace OpenSim.Data.MySQL
if (reader.Read())
item = readInventoryItem(reader);
dbcon.Close();
return item;
}
}
@ -423,7 +417,6 @@ namespace OpenSim.Data.MySQL
if (reader.Read())
folder = readInventoryFolder(reader);
dbcon.Close();
return folder;
}
}
@ -460,7 +453,7 @@ namespace OpenSim.Data.MySQL
itemName = item.Name.Substring(0, 64);
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item");
}
string itemDesc = item.Description;
if (item.Description.Length > 128)
{
@ -497,10 +490,10 @@ namespace OpenSim.Data.MySQL
result.Parameters.AddWithValue("?groupID", item.GroupID);
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
result.Parameters.AddWithValue("?flags", item.Flags);
lock (m_dbLock)
result.ExecuteNonQuery();
result.Dispose();
}
@ -511,7 +504,6 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock)
result.ExecuteNonQuery();
}
dbcon.Close();
}
}
catch (MySqlException e)
@ -548,7 +540,6 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
dbcon.Close();
}
}
catch (MySqlException e)
@ -609,7 +600,6 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString());
}
}
dbcon.Close();
}
}
@ -640,7 +630,7 @@ namespace OpenSim.Data.MySQL
{
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
try
{
lock (m_dbLock)
@ -653,7 +643,6 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString());
}
}
dbcon.Close();
}
}
@ -817,7 +806,6 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
dbcon.Close();
}
}
catch (MySqlException e)
@ -845,7 +833,6 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
dbcon.Close();
}
}
catch (MySqlException e)
@ -873,7 +860,7 @@ namespace OpenSim.Data.MySQL
deleteOneFolder(folderID);
deleteItemsInFolder(folderID);
}
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
{
lock (m_dbLock)
@ -899,7 +886,6 @@ namespace OpenSim.Data.MySQL
if (item != null)
list.Add(item);
}
dbcon.Close();
return list;
}
}

View File

@ -39,16 +39,16 @@ namespace OpenSim.Data.MySQL
{
/// <summary>This is a MySQL-customized migration processor. The only difference is in how
/// it executes SQL scripts (using MySqlScript instead of MyCommand)
///
///
/// </summary>
public class MySqlMigration : Migration
{
public MySqlMigration()
: base()
{
{
}
public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) :
public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) :
base(conn, assem, subtype, type)
{
}

View File

@ -50,7 +50,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
ExecuteNonQuery(cmd);
}

View File

@ -66,9 +66,9 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
}
@ -85,10 +85,10 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
if (ExecuteNonQuery(cmd) == 0)
return false;
}

View File

@ -60,7 +60,6 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "GridStore");
m.Update();
dbcon.Close();
}
}
@ -81,15 +80,16 @@ namespace OpenSim.Data.MySQL
}
}
public RegionData GetSpecific(string regionName, UUID scopeID)
public RegionData Get(int posX, int posY, UUID scopeID)
{
string command = "select * from `" + m_Realm + "` where regionName = ?regionName";
string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?regionName", regionName);
cmd.Parameters.AddWithValue("?posX", posX.ToString());
cmd.Parameters.AddWithValue("?posY", posY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
List<RegionData> ret = RunCommand(cmd);
@ -98,48 +98,6 @@ namespace OpenSim.Data.MySQL
return ret[0];
}
}
public RegionData Get(int posX, int posY, UUID scopeID)
{
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
int startX = posX - (int)Constants.MaximumRegionSize;
int startY = posY - (int)Constants.MaximumRegionSize;
int endX = posX;
int endY = posY;
List<RegionData> ret;
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?startX", startX.ToString());
cmd.Parameters.AddWithValue("?startY", startY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
cmd.Parameters.AddWithValue("?endY", endY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
ret = RunCommand(cmd);
}
if (ret.Count == 0)
return null;
// find the first that contains pos
RegionData rg = null;
foreach (RegionData r in ret)
{
if (posX >= r.posX && posX < r.posX + r.sizeX
&& posY >= r.posY && posY < r.posY + r.sizeY)
{
rg = r;
break;
}
}
return rg;
}
public RegionData Get(UUID regionID, UUID scopeID)
@ -163,7 +121,6 @@ namespace OpenSim.Data.MySQL
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
{
/* fix size regions
string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
@ -178,38 +135,6 @@ namespace OpenSim.Data.MySQL
return RunCommand(cmd);
}
*/
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
int qstartX = startX - (int)Constants.MaximumRegionSize;
int qstartY = startY - (int)Constants.MaximumRegionSize;
List<RegionData> dbret;
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?startX", qstartX.ToString());
cmd.Parameters.AddWithValue("?startY", qstartY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
cmd.Parameters.AddWithValue("?endY", endY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
dbret = RunCommand(cmd);
}
List<RegionData> ret = new List<RegionData>();
if (dbret.Count == 0)
return ret;
foreach (RegionData r in dbret)
{
if (r.posX + r.sizeX > startX && r.posX <= endX
&& r.posY + r.sizeY > startY && r.posY <= endY)
ret.Add(r);
}
return ret;
}
public List<RegionData> RunCommand(MySqlCommand cmd)
@ -262,8 +187,6 @@ namespace OpenSim.Data.MySQL
retList.Add(ret);
}
}
cmd.Connection = null;
dbcon.Close();
}
return retList;
@ -414,7 +337,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
return RunCommand(cmd);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -46,21 +46,17 @@ namespace OpenSim.Data.MySQL
{
string[] words = query.Split(new char[] {' '});
bool valid = false;
for (int i = 0 ; i < words.Length ; i++)
{
if (words[i].Length > 2)
valid = true;
// 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[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 ((!valid) || words.Length == 0)
if (words.Length == 0)
return new UserAccountData[0];
if (words.Length > 2)
@ -70,13 +66,13 @@ namespace OpenSim.Data.MySQL
{
if (words.Length == 1)
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
cmd.CommandText = 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.AddWithValue("?search", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
cmd.CommandText = 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.AddWithValue("?searchFirst", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
@ -85,21 +81,5 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd);
}
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
using (MySqlCommand cmd = new MySqlCommand())
{
if (scopeID != UUID.Zero)
{
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
return DoQuery(cmd);
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More