Merge branch 'master' of opensimulator.org:/var/git/opensim

0.9.1.0-post-fixes
Melanie 2018-09-12 13:22:17 +01:00
commit e874e3a2ad
555 changed files with 112848 additions and 117437 deletions

View File

@ -145,7 +145,12 @@
</exec> </exec>
<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.services.inventoryservice.tests)==0}" />
<delete dir="%temp%"/> <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.permissions">
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
<delete dir="%temp%"/>
</target> </target>
<target name="test-stress" depends="build, find-nunit"> <target name="test-stress" depends="build, find-nunit">
@ -260,6 +265,11 @@
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" /> <arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
</exec> </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.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.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.framework.servers.tests)==0}" />
@ -271,6 +281,7 @@
<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.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.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.services.inventoryservice.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
</target> </target>
<target name="doxygen"> <target name="doxygen">

View File

@ -4,14 +4,10 @@ The following people have contributed to OpenSim (Thank you for your effort!)
These folks represent the current core team for OpenSim, and are the These folks represent the current core team for OpenSim, and are the
people that make the day to day of OpenSim happen. people that make the day to day of OpenSim happen.
* justincc (OSVW Consulting, justincc.org)
* Melanie Thielker * Melanie Thielker
* Diva (Crista Lopes, University of California, Irvine) * Diva (Crista Lopes, University of California, Irvine)
* BlueWall (James Hughes)
* Nebadon Izumi (Michael Cerquoni, OSgrid) * Nebadon Izumi (Michael Cerquoni, OSgrid)
* Snoopy Pfeffer
* Robert Adams (MisterBlue) * Robert Adams (MisterBlue)
* Oren Hurvitz (Kitely)
* Kevin Cozens * Kevin Cozens
* Leal Duarte (Ubit Umarov) * Leal Duarte (Ubit Umarov)
@ -20,11 +16,14 @@ 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 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. been that active lately, so their voting rights are awaiting their come back.
* Teravus (w3z)
* Arthur Rodrigo S Valadares (IBM) * Arthur Rodrigo S Valadares (IBM)
* BlueWall (James Hughes)
* Dan Lake * Dan Lake
* Marck * Marck
* Mic Bowman * Mic Bowman
* Oren Hurvitz (Kitely)
* Snoopy Pfeffer
* Teravus (w3z)
= Past Open Sim Developers = = Past Open Sim Developers =
These folks are alumns of the OpenSim core group, but are now These folks are alumns of the OpenSim core group, but are now
@ -57,7 +56,7 @@ where we are today.
* John Hurliman * John Hurliman
* chi11ken (Genkii) * chi11ken (Genkii)
* dahlia * dahlia
* justincc (OSVW Consulting, justincc.org)
= Additional OpenSim Contributors = = Additional OpenSim Contributors =
These folks have contributed code patches or content to OpenSimulator to help make it These folks have contributed code patches or content to OpenSimulator to help make it
@ -149,6 +148,7 @@ what it is today.
* Micheil Merlin * Micheil Merlin
* Mike Osias (IBM) * Mike Osias (IBM)
* Mike Pitman (IBM) * Mike Pitman (IBM)
* Mike Rieker (Dreamnation)
* mikemig * mikemig
* mikkopa/_someone - RealXtend * mikkopa/_someone - RealXtend
* Misterblue * Misterblue

View File

@ -787,7 +787,7 @@ namespace OpenSim.Groups
remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully");
// Update the founder with new group information. // Update the founder with new group information.
SendAgentGroupDataUpdate(remoteClient, false); SendAgentGroupDataUpdate(remoteClient, true);
} }
else else
remoteClient.SendCreateGroupReply(groupID, false, reason); remoteClient.SendCreateGroupReply(groupID, false, reason);

View File

@ -115,9 +115,10 @@ namespace OpenSim.Groups
protected override byte[] ProcessRequest(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); string body;
string body = sr.ReadToEnd(); using(StreamReader sr = new StreamReader(requestData))
sr.Close(); body = sr.ReadToEnd();
body = body.Trim(); body = body.Trim();
//m_log.DebugFormat("[XXX]: query String: {0}", body); //m_log.DebugFormat("[XXX]: query String: {0}", body);

View File

@ -91,9 +91,10 @@ namespace OpenSim.Groups
protected override byte[] ProcessRequest(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader sr = new StreamReader(requestData); string body;
string body = sr.ReadToEnd(); using(StreamReader sr = new StreamReader(requestData))
sr.Close(); body = sr.ReadToEnd();
body = body.Trim(); body = body.Trim();
//m_log.DebugFormat("[XXX]: query String: {0}", body); //m_log.DebugFormat("[XXX]: query String: {0}", body);

View File

@ -43,7 +43,8 @@ namespace OpenSim.Groups
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome | public const GroupPowers DefaultEveryonePowers =
GroupPowers.AllowSetHome |
GroupPowers.Accountable | GroupPowers.Accountable |
GroupPowers.JoinChat | GroupPowers.JoinChat |
GroupPowers.AllowVoiceChat | GroupPowers.AllowVoiceChat |
@ -51,27 +52,18 @@ namespace OpenSim.Groups
GroupPowers.StartProposal | GroupPowers.StartProposal |
GroupPowers.VoteOnProposal; GroupPowers.VoteOnProposal;
public const GroupPowers OwnerPowers = GroupPowers.Accountable | public const GroupPowers OfficersPowers = DefaultEveryonePowers |
GroupPowers.AllowEditLand |
GroupPowers.AllowFly | GroupPowers.AllowFly |
GroupPowers.AllowLandmark | GroupPowers.AllowLandmark |
GroupPowers.AllowRez | GroupPowers.AllowRez |
GroupPowers.AllowSetHome |
GroupPowers.AllowVoiceChat |
GroupPowers.AssignMember |
GroupPowers.AssignMemberLimited | GroupPowers.AssignMemberLimited |
GroupPowers.ChangeActions |
GroupPowers.ChangeIdentity | GroupPowers.ChangeIdentity |
GroupPowers.ChangeMedia | GroupPowers.ChangeMedia |
GroupPowers.ChangeOptions | GroupPowers.ChangeOptions |
GroupPowers.CreateRole |
GroupPowers.DeedObject | GroupPowers.DeedObject |
GroupPowers.DeleteRole |
GroupPowers.Eject | GroupPowers.Eject |
GroupPowers.FindPlaces | GroupPowers.FindPlaces |
GroupPowers.HostEvent |
GroupPowers.Invite | GroupPowers.Invite |
GroupPowers.JoinChat |
GroupPowers.LandChangeIdentity | GroupPowers.LandChangeIdentity |
GroupPowers.LandDeed | GroupPowers.LandDeed |
GroupPowers.LandDivideJoin | GroupPowers.LandDivideJoin |
@ -84,19 +76,29 @@ namespace OpenSim.Groups
GroupPowers.LandOptions | GroupPowers.LandOptions |
GroupPowers.LandRelease | GroupPowers.LandRelease |
GroupPowers.LandSetSale | GroupPowers.LandSetSale |
GroupPowers.MemberVisible |
GroupPowers.ModerateChat | GroupPowers.ModerateChat |
GroupPowers.ObjectManipulate | GroupPowers.ObjectManipulate |
GroupPowers.ObjectSetForSale | GroupPowers.ObjectSetForSale |
GroupPowers.ReceiveNotices |
GroupPowers.RemoveMember |
GroupPowers.ReturnGroupOwned | GroupPowers.ReturnGroupOwned |
GroupPowers.ReturnGroupSet | GroupPowers.ReturnGroupSet |
GroupPowers.ReturnNonGroup | GroupPowers.ReturnNonGroup |
GroupPowers.RoleProperties | GroupPowers.RoleProperties |
GroupPowers.SendNotices | GroupPowers.SendNotices |
GroupPowers.SetLandingPoint | GroupPowers.SetLandingPoint;
GroupPowers.StartProposal |
GroupPowers.VoteOnProposal; 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;
#region Daily Cleanup #region Daily Cleanup
@ -151,20 +153,25 @@ namespace OpenSim.Groups
data.Data["ShowInList"] = showInList ? "1" : "0"; data.Data["ShowInList"] = showInList ? "1" : "0";
data.Data["AllowPublish"] = allowPublish ? "1" : "0"; data.Data["AllowPublish"] = allowPublish ? "1" : "0";
data.Data["MaturePublish"] = maturePublish ? "1" : "0"; data.Data["MaturePublish"] = maturePublish ? "1" : "0";
UUID roleID = UUID.Random(); UUID ownerRoleID = UUID.Random();
data.Data["OwnerRoleID"] = roleID.ToString(); data.Data["OwnerRoleID"] = ownerRoleID.ToString();
if (!m_Database.StoreGroup(data)) if (!m_Database.StoreGroup(data))
return UUID.Zero; return UUID.Zero;
// Create Everyone role // Create Everyone role
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true); _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);
// Create Owner role // Create Owner role
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true); _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, ownerRoleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
// Add founder to group // Add founder to group
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID); _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, ownerRoleID);
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, officersRoleID);
return data.GroupID; return data.GroupID;
} }
@ -843,7 +850,7 @@ namespace OpenSim.Groups
return false; return false;
} }
if (!add && data == null) // it deosn't exist, can't update if (!add && data == null) // it doesn't exist, can't update
{ {
m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID); m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
return false; return false;

View File

@ -114,7 +114,6 @@ namespace OpenSim.OfflineIM
scene.ForEachClient(delegate(IClientAPI client) scene.ForEachClient(delegate(IClientAPI client)
{ {
client.OnRetrieveInstantMessages -= RetrieveInstantMessages; client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
client.OnMuteListRequest -= OnMuteListRequest;
}); });
} }
@ -162,7 +161,6 @@ namespace OpenSim.OfflineIM
private void OnNewClient(IClientAPI client) private void OnNewClient(IClientAPI client)
{ {
client.OnRetrieveInstantMessages += RetrieveInstantMessages; client.OnRetrieveInstantMessages += RetrieveInstantMessages;
client.OnMuteListRequest += OnMuteListRequest;
} }
private void RetrieveInstantMessages(IClientAPI client) private void RetrieveInstantMessages(IClientAPI client)
@ -194,20 +192,6 @@ 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) private void UndeliveredMessage(GridInstantMessage im)
{ {
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&

View File

@ -1934,7 +1934,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
GetSceneFromRegionParams(requestData, responseData, out scene); GetSceneFromRegionParams(requestData, responseData, out scene);
health = scene.GetHealth(out flags, out text); health = scene.GetHealth(out flags, out text);
} }
catch (Exception e) catch
{ {
responseData["error"] = null; responseData["error"] = null;
} }
@ -3087,15 +3087,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController
/// </summary> /// </summary>
private void ApplyNextOwnerPermissions(InventoryItemBase item) private void ApplyNextOwnerPermissions(InventoryItemBase item)
{ {
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) if (item.InvType == (int)InventoryType.Object)
{ {
if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) uint perms = item.CurrentPermissions;
item.CurrentPermissions &= ~(uint)PermissionMask.Copy; PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) item.CurrentPermissions = perms;
item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
} }
item.CurrentPermissions &= item.NextPermissions; item.CurrentPermissions &= item.NextPermissions;
item.BasePermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions;
item.EveryOnePermissions &= item.NextPermissions; item.EveryOnePermissions &= item.NextPermissions;

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
@ -60,26 +61,10 @@ namespace OpenSim.Capabilities.Handlers
m_Scene = s; m_Scene = s;
} }
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
//m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
// nasty temporary hack here, the linden client falsely
// identifies the uuid 00000000-0000-0000-0000-000000000000
// as a string which breaks us
//
// correctly mark it as a uuid
//
request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
// another hack <integer>1</integer> results in a
// System.ArgumentException: Object type System.Int32 cannot
// be converted to target type: System.Boolean
//
request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
Hashtable hash = new Hashtable(); Hashtable hash = new Hashtable();
try try
{ {
@ -93,9 +78,6 @@ namespace OpenSim.Capabilities.Handlers
ArrayList foldersrequested = (ArrayList)hash["folders"]; ArrayList foldersrequested = (ArrayList)hash["folders"];
string response = "";
string bad_folders_response = "";
List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>(); List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>();
for (int i = 0; i < foldersrequested.Count; i++) for (int i = 0; i < foldersrequested.Count; i++)
{ {
@ -113,15 +95,14 @@ namespace OpenSim.Capabilities.Handlers
continue; continue;
} }
// Filter duplicate folder ids that bad viewers may send
if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null)
folders.Add(llsdRequest); folders.Add(llsdRequest);
} }
if (folders.Count > 0) if(folders.Count == 0)
{ return "<llsd><map><key>folders</key><array /></map></llsd>";
List<UUID> bad_folders = new List<UUID>(); List<UUID> bad_folders = new List<UUID>();
List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders); List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders);
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
@ -133,52 +114,37 @@ namespace OpenSim.Capabilities.Handlers
#pragma warning restore 0612 #pragma warning restore 0612
} }
string inventoryitemstr = string.Empty; StringBuilder lastresponse = new StringBuilder(1024);
lastresponse.Append("<llsd>");
if(invcollSet.Count > 0)
{
lastresponse.Append("<map><key>folders</key><array>");
foreach (InventoryCollectionWithDescendents icoll in invcollSet) foreach (InventoryCollectionWithDescendents icoll in invcollSet)
{ {
LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents); LLSDInventoryFolderContents thiscontents = contentsToLLSD(icoll.Collection, icoll.Descendents);
lastresponse.Append(LLSDHelpers.SerialiseLLSDReplyNoHeader(thiscontents));
inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
response += inventoryitemstr;
} }
lastresponse.Append("</array></map>");
}
else
lastresponse.Append("<map><key>folders</key><array /></map>");
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
if(bad_folders.Count > 0)
{
lastresponse.Append("<map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders) foreach (UUID bad in bad_folders)
bad_folders_response += "<uuid>" + bad + "</uuid>"; {
lastresponse.Append("<map><key>folder_id</key><uuid>");
lastresponse.Append(bad.ToString());
lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");
} }
lastresponse.Append("</array></map>");
}
lastresponse.Append("</llsd>");
if (response.Length == 0) return lastresponse.ToString();;
{
/* Viewers expect a bad_folders array when not available */
if (bad_folders_response.Length != 0)
{
response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
}
else
{
response = "<llsd><map><key>folders</key><array /></map></llsd>";
}
}
else
{
if (bad_folders_response.Length != 0)
{
response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
}
else
{
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
}
}
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count);
//m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response);
return response;
} }
/// <summary> /// <summary>
@ -240,24 +206,19 @@ namespace OpenSim.Capabilities.Handlers
return reply; return reply;
} }
private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents) private LLSDInventoryFolderContents contentsToLLSD(InventoryCollection inv, int descendents)
{ {
LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
contents.agent_id = inv.OwnerID; contents.agent_id = inv.OwnerID;
contents.owner_id = inv.OwnerID; contents.owner_id = inv.OwnerID;
contents.folder_id = inv.FolderID; contents.folder_id = inv.FolderID;
reply.folders.Array.Add(contents);
if (inv.Folders != null) if (inv.Folders != null)
{ {
foreach (InventoryFolderBase invFolder in inv.Folders) foreach (InventoryFolderBase invFolder in inv.Folders)
{ {
contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
} }
descendents += inv.Folders.Count;
} }
if (inv.Items != null) if (inv.Items != null)
@ -271,7 +232,7 @@ namespace OpenSim.Capabilities.Handlers
contents.descendents = descendents; contents.descendents = descendents;
contents.version = inv.Version; contents.version = inv.Version;
return reply; return contents;
} }
/// <summary> /// <summary>
/// Old style. Soon to be deprecated. /// Old style. Soon to be deprecated.
@ -285,8 +246,8 @@ namespace OpenSim.Capabilities.Handlers
{ {
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count);
string response = ""; StringBuilder tmpresponse = new StringBuilder(1024);
string bad_folders_response = ""; StringBuilder tmpbadfolders = new StringBuilder(1024);
for (int i = 0; i < foldersrequested.Count; i++) for (int i = 0; i < foldersrequested.Count; i++)
{ {
@ -308,7 +269,9 @@ namespace OpenSim.Capabilities.Handlers
if (null == reply) if (null == reply)
{ {
bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>"; tmpbadfolders.Append("<map><key>folder_id</key><uuid>");
tmpbadfolders.Append(llsdRequest.folder_id.ToString());
tmpbadfolders.Append("</uuid><key>error</key><string>Unknown</string></map>");
} }
else else
{ {
@ -317,39 +280,29 @@ namespace OpenSim.Capabilities.Handlers
inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
} }
response += inventoryitemstr; tmpresponse.Append(inventoryitemstr);
} }
if (response.Length == 0) StringBuilder lastresponse = new StringBuilder(1024);
lastresponse.Append("<llsd>");
if(tmpresponse.Length > 0)
{ {
/* Viewers expect a bad_folders array when not available */ lastresponse.Append("<map><key>folders</key><array>");
if (bad_folders_response.Length != 0) lastresponse.Append(tmpresponse.ToString());
{ lastresponse.Append("</array></map>");
response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
} }
else else
{ lastresponse.Append("<map><key>folders</key><array /></map>");
response = "<llsd><map><key>folders</key><array /></map></llsd>";
}
}
else
{
if (bad_folders_response.Length != 0)
{
response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
}
else
{
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
}
}
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); if(tmpbadfolders.Length > 0)
//m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response); {
lastresponse.Append("<map><key>bad_folders</key><array>");
lastresponse.Append(tmpbadfolders.ToString());
lastresponse.Append("</array></map>");
}
lastresponse.Append("</llsd>");
return response; return lastresponse.ToString();
// }
} }
/// <summary> /// <summary>
@ -436,110 +389,9 @@ namespace OpenSim.Capabilities.Handlers
itemsToReturn.Insert(0, linkedItem); itemsToReturn.Insert(0, linkedItem);
} }
} }
// Now scan for folder links and insert the items they target and those links at the head of the return data
/* dont send contents of LinkFolders.
from docs seems this was never a spec
foreach (InventoryItemBase item in originalItems)
{
if (item.AssetType == (int)AssetType.LinkFolder)
{
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
List<InventoryItemBase> links = linkedFolderContents.Items;
itemsToReturn.InsertRange(0, links);
foreach (InventoryItemBase link in linkedFolderContents.Items)
{
// Take care of genuinely broken links where the target doesn't exist
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// rather than having to keep track of every folder requested in the recursion.
if (link != null)
{
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
InventoryItemBase linkedItem
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
if (linkedItem != null)
itemsToReturn.Insert(0, linkedItem);
} }
} }
} }
}
*/
}
// foreach (InventoryItemBase item in contents.Items)
// {
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
// }
// =====
//
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
// {
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
// linkedItem.Name, folderID, agentID);
//
// contents.Items.Add(linkedItem);
// }
//
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
// // will be broken in the viewer.
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
// foreach (InventoryItemBase item in contents.Items)
// {
// if (item.AssetType == (int)AssetType.Link)
// {
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
//
// // Take care of genuinely broken links where the target doesn't exist
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// // rather than having to keep track of every folder requested in the recursion.
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
// {
// // We don't need to send the folder if source and destination of the link are in the same
// // folder.
// if (linkedItem.Folder != containingFolder.ID)
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
// }
// }
// }
//
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
// {
// m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
// linkedItemFolderId, folderID, agentID);
//
// int dummyVersion;
// InventoryCollection linkedCollection
// = Fetch(
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
//
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
// linkedFolder.Owner = agentID;
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
//
//// contents.Folders.AddRange(linkedCollection.Folders);
//
// contents.Folders.Add(linkedFolder);
// contents.Items.AddRange(linkedCollection.Items);
// }
// }
}
}
else else
{ {
// Lost items don't really need a version // Lost items don't really need a version
@ -550,36 +402,29 @@ from docs seems this was never a spec
} }
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result) private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollectionWithDescendents> result)
{ {
InventoryFolderImpl fold; InventoryFolderImpl fold;
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) foreach (LLSDFetchInventoryDescendents f in libFolders)
{
List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
fetchFolders.RemoveAll(f => libfolders.Contains(f));
//m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count);
foreach (LLSDFetchInventoryDescendents f in libfolders)
{ {
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
{ {
InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
ret.Collection = new InventoryCollection(); ret.Collection = new InventoryCollection();
ret.Collection.Folders = new List<InventoryFolderBase>(); // ret.Collection.Folders = new List<InventoryFolderBase>();
ret.Collection.Folders = fold.RequestListOfFolders();
ret.Collection.Items = fold.RequestListOfItems(); ret.Collection.Items = fold.RequestListOfItems();
ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
ret.Collection.FolderID = f.folder_id; ret.Collection.FolderID = f.folder_id;
ret.Collection.Version = fold.Version; ret.Collection.Version = fold.Version;
ret.Descendents = ret.Collection.Items.Count; ret.Descendents = ret.Collection.Items.Count + ret.Collection.Folders.Count;
result.Add(ret); result.Add(ret);
//m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
} }
} }
} }
}
private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders) private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
{ {
@ -589,43 +434,74 @@ from docs seems this was never a spec
// FIXME MAYBE: We're not handling sortOrder! // FIXME MAYBE: We're not handling sortOrder!
List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>(); List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>();
List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>();
List<LLSDFetchInventoryDescendents> otherFolders = new List<LLSDFetchInventoryDescendents>();
HashSet<UUID> libIDs = new HashSet<UUID>();
HashSet<UUID> otherIDs = new HashSet<UUID>();
AddLibraryFolders(fetchFolders, result); bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
UUID libOwner = UUID.Zero;
if(dolib)
libOwner = m_LibraryService.LibraryRootFolder.Owner;
// Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
// and can kill the sim (all root folders have parent_id Zero) // and can kill the sim (all root folders have parent_id Zero)
LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero); // send something.
if (zero != null) bool doneZeroID = false;
foreach(LLSDFetchInventoryDescendents f in fetchFolders)
{ {
fetchFolders.Remove(zero); if (f.folder_id == UUID.Zero)
BadFolder(zero, null, bad_folders); {
if(doneZeroID)
continue;
doneZeroID = true;
InventoryCollectionWithDescendents zeroColl = new InventoryCollectionWithDescendents();
zeroColl.Collection = new InventoryCollection();
zeroColl.Collection.OwnerID = f.owner_id;
zeroColl.Collection.Version = 0;
zeroColl.Collection.FolderID = f.folder_id;
zeroColl.Descendents = 0;
result.Add(zeroColl);
continue;
}
if(dolib && f.owner_id == libOwner)
{
if(libIDs.Contains(f.folder_id))
continue;
libIDs.Add(f.folder_id);
libFolders.Add(f);
continue;
}
if(otherIDs.Contains(f.folder_id))
continue;
otherIDs.Add(f.folder_id);
otherFolders.Add(f);
} }
if (fetchFolders.Count > 0) if(otherFolders.Count > 0)
{ {
UUID[] fids = new UUID[fetchFolders.Count];
int i = 0; int i = 0;
foreach (LLSDFetchInventoryDescendents f in fetchFolders)
fids[i++] = f.folder_id;
//m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids)); //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids); InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());
if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0)) if (fetchedContents == null)
{
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
foreach (LLSDFetchInventoryDescendents freq in fetchFolders)
BadFolder(freq, null, bad_folders);
return null; return null;
}
if (fetchedContents.Length == 0)
{
foreach (LLSDFetchInventoryDescendents freq in otherFolders)
BadFolder(freq, null, bad_folders);
}
else
{
i = 0; i = 0;
// Do some post-processing. May need to fetch more from inv server for links // Do some post-processing. May need to fetch more from inv server for links
foreach (InventoryCollection contents in fetchedContents) foreach (InventoryCollection contents in fetchedContents)
{ {
// Find the original request // Find the original request
LLSDFetchInventoryDescendents freq = fetchFolders[i++]; LLSDFetchInventoryDescendents freq = otherFolders[i++];
InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
coll.Collection = contents; coll.Collection = contents;
@ -639,67 +515,41 @@ from docs seems this was never a spec
result.Add(coll); result.Add(coll);
} }
} }
}
if(dolib && libFolders.Count > 0)
{
AddLibraryFolders(libFolders, result);
}
return result; return result;
} }
private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders) private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
{ {
bool bad = false;
if (contents == null) if (contents == null)
{ {
bad_folders.Add(freq.folder_id); bad_folders.Add(freq.folder_id);
bad = true; return true;
} }
// The inventory server isn't sending FolderID in the collection... // The inventory server isn't sending FolderID in the collection...
// Must fetch it individually // Must fetch it individually
else if (contents.FolderID == UUID.Zero) if (contents.FolderID == UUID.Zero)
{ {
InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id); InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id);
if (containingFolder == null)
if (containingFolder != null)
{ {
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
bad_folders.Add(freq.folder_id);
return true;
}
contents.FolderID = containingFolder.ID; contents.FolderID = containingFolder.ID;
contents.OwnerID = containingFolder.Owner; contents.OwnerID = containingFolder.Owner;
contents.Version = containingFolder.Version; contents.Version = containingFolder.Version;
} }
else
{
// Was it really a request for folder Zero?
// This is an overkill, but Firestorm really asks for folder Zero.
// I'm leaving the code here for the time being, but commented.
if (freq.folder_id == UUID.Zero)
{
//coll.Collection.OwnerID = freq.owner_id;
//coll.Collection.FolderID = contents.FolderID;
//containingFolder = m_InventoryService.GetRootFolder(freq.owner_id);
//if (containingFolder != null)
//{
// m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID);
// coll.Collection.Folders.Clear();
// coll.Collection.Folders.Add(containingFolder);
// if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
// {
// InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner);
// lib.Name = m_LibraryService.LibraryRootFolder.Name;
// lib.Type = m_LibraryService.LibraryRootFolder.Type;
// lib.Version = m_LibraryService.LibraryRootFolder.Version;
// coll.Collection.Folders.Add(lib);
// }
// coll.Collection.Items.Clear();
//}
}
else
{
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
bad_folders.Add(freq.folder_id);
}
bad = true;
}
}
return bad; return false;
} }
private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll) private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
@ -708,42 +558,21 @@ from docs seems this was never a spec
if (freq.fetch_items && contents.Items != null) if (freq.fetch_items && contents.Items != null)
{ {
List<InventoryItemBase> itemsToReturn = contents.Items; // viewers are lasy and want a copy of the linked item sent before the link to it
// descendents must only include the links, not the linked items we add // descendents must only include the links, not the linked items we add
coll.Descendents = itemsToReturn.Count; coll.Descendents = contents.Items.Count + contents.Folders.Count;
// Add target items for links in this folder before the links themselves. // look for item links
List<UUID> itemIDs = new List<UUID>(); List<UUID> itemIDs = new List<UUID>();
List<UUID> folderIDs = new List<UUID>(); foreach (InventoryItemBase item in contents.Items)
foreach (InventoryItemBase item in itemsToReturn)
{ {
//m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType);
if (item.AssetType == (int)AssetType.Link) if (item.AssetType == (int)AssetType.Link)
itemIDs.Add(item.AssetID); itemIDs.Add(item.AssetID);
// else if (item.AssetType == (int)AssetType.LinkFolder)
// folderIDs.Add(item.AssetID);
}
//m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);
// Scan for folder links and insert the items they target and those links at the head of the return data
if (folderIDs.Count > 0)
{
InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
foreach (InventoryCollection linkedFolderContents in linkedFolders)
{
if (linkedFolderContents == null)
continue;
List<InventoryItemBase> links = linkedFolderContents.Items;
itemsToReturn.InsertRange(0, links);
}
} }
// get the linked if any
if (itemIDs.Count > 0) if (itemIDs.Count > 0)
{ {
InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
@ -759,12 +588,10 @@ from docs seems this was never a spec
} }
} }
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
//foreach (InventoryItemBase item in itemsToReturn)
// m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);
if (linked != null) if (linked != null)
{ {
List<InventoryItemBase> linkedItems = new List<InventoryItemBase>();
// check for broken
foreach (InventoryItemBase linkedItem in linked) foreach (InventoryItemBase linkedItem in linked)
{ {
// Take care of genuinely broken links where the target doesn't exist // Take care of genuinely broken links where the target doesn't exist
@ -773,14 +600,16 @@ from docs seems this was never a spec
// rather than having to keep track of every folder requested in the recursion. // rather than having to keep track of every folder requested in the recursion.
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
{ {
itemsToReturn.Insert(0, linkedItem); linkedItems.Add(linkedItem);
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
} }
} }
// insert them
if(linkedItems.Count > 0)
contents.Items.InsertRange(0,linkedItems);
} }
} }
} }
} }
/// <summary> /// <summary>
@ -795,6 +624,7 @@ from docs seems this was never a spec
llsdFolder.parent_id = invFolder.ParentID; llsdFolder.parent_id = invFolder.ParentID;
llsdFolder.name = invFolder.Name; llsdFolder.name = invFolder.Name;
llsdFolder.type = invFolder.Type; llsdFolder.type = invFolder.Type;
llsdFolder.version = invFolder.Version;
llsdFolder.preferred_type = -1; llsdFolder.preferred_type = -1;
return llsdFolder; return llsdFolder;

View File

@ -26,6 +26,7 @@
*/ */
using System.Reflection; using System.Reflection;
using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
@ -59,9 +60,6 @@ namespace OpenSim.Capabilities.Handlers
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request)); OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
OSDArray itemsRequested = (OSDArray)requestmap["items"]; OSDArray itemsRequested = (OSDArray)requestmap["items"];
string reply;
LLSDFetchInventory llsdReply = new LLSDFetchInventory();
UUID[] itemIDs = new UUID[itemsRequested.Count]; UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0; int i = 0;
@ -75,15 +73,6 @@ namespace OpenSim.Capabilities.Handlers
if (m_agentID != UUID.Zero) if (m_agentID != UUID.Zero)
{ {
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
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];
foreach (UUID id in itemIDs)
items[i++] = m_inventoryService.GetItem(m_agentID, id);
}
} }
else else
{ {
@ -92,55 +81,31 @@ namespace OpenSim.Capabilities.Handlers
items[i++] = m_inventoryService.GetItem(UUID.Zero, id); 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) foreach (InventoryItemBase item in items)
{ {
if (item != null) if (item != null)
{ item.ToLLSDxml(lsl);
// 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));
} }
LLSDxmlEncode.AddEndArray(lsl);
} }
reply = LLSDHelpers.SerialiseLLSDReply(llsdReply); LLSDxmlEncode.AddEndMap(lsl);
return LLSDxmlEncode.End(lsl);;
return reply;
}
/// <summary>
/// Convert an internal inventory item object into an LLSD object.
/// </summary>
/// <param name="invItem"></param>
/// <returns></returns>
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
{
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
llsdItem.asset_id = invItem.AssetID;
llsdItem.created_at = invItem.CreationDate;
llsdItem.desc = invItem.Description;
llsdItem.flags = ((int)invItem.Flags) & 0xff;
llsdItem.item_id = invItem.ID;
llsdItem.name = invItem.Name;
llsdItem.parent_id = invItem.Folder;
llsdItem.type = invItem.AssetType;
llsdItem.inv_type = invItem.InvType;
llsdItem.permissions = new LLSDPermissions();
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
llsdItem.permissions.group_id = invItem.GroupID;
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
llsdItem.permissions.owner_id = invItem.Owner;
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
llsdItem.sale_info = new LLSDSaleInfo();
llsdItem.sale_info.sale_price = invItem.SalePrice;
llsdItem.sale_info.sale_type = invItem.SaleType;
return llsdItem;
} }
} }
} }

View File

@ -267,6 +267,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
[Test] [Test]
public void Test_005_FolderZero() public void Test_005_FolderZero()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
Init(); Init();
@ -283,11 +284,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response"); Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder"); // we do return a answer now
//Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder");
Console.WriteLine(llsdresponse); Console.WriteLine(llsdresponse);
} }
} }
} }

View File

@ -64,10 +64,7 @@ namespace OpenSim.Capabilities.Handlers
Hashtable ret = new Hashtable(); Hashtable ret = new Hashtable();
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
ret["content_type"] = "text/plain"; ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0; ret["int_bytes"] = 0;
ret["int_lod"] = 0;
string MeshStr = (string)request["mesh_id"]; string MeshStr = (string)request["mesh_id"];
@ -76,6 +73,8 @@ namespace OpenSim.Capabilities.Handlers
if (m_assetService == null) if (m_assetService == null)
{ {
m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
ret["keepalive"] = false;
return ret;
} }
UUID meshID; UUID meshID;
@ -101,10 +100,7 @@ namespace OpenSim.Capabilities.Handlers
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 400; //501; //410; //404; responsedata["int_response_code"] = 400; //501; //410; //404;
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Request wasn't what was expected"; responsedata["str_response_string"] = "Request wasn't what was expected";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
responsedata["int_bytes"] = 0; responsedata["int_bytes"] = 0;
string meshStr = string.Empty; string meshStr = string.Empty;
@ -118,10 +114,8 @@ namespace OpenSim.Capabilities.Handlers
if (m_assetService == null) if (m_assetService == null)
{ {
responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
responsedata["reusecontext"] = false;
return responsedata; return responsedata;
} }
@ -155,10 +149,7 @@ namespace OpenSim.Capabilities.Handlers
{ {
responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "This range doesnt exist."; responsedata["str_response_string"] = "This range doesnt exist.";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
return responsedata; return responsedata;
} }
else else
@ -169,28 +160,11 @@ namespace OpenSim.Capabilities.Handlers
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
if (start > 20000)
{
responsedata["int_lod"] = 3;
}
else if (start < 4097)
{
responsedata["int_lod"] = 1;
}
else
{
responsedata["int_lod"] = 2;
}
if (start == 0 && len == mesh.Data.Length) // well redudante maybe if (start == 0 && len == mesh.Data.Length) // well redudante maybe
{ {
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
responsedata["bin_response_data"] = mesh.Data; responsedata["bin_response_data"] = mesh.Data;
responsedata["int_bytes"] = mesh.Data.Length; responsedata["int_bytes"] = mesh.Data.Length;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
else else
{ {
@ -203,7 +177,6 @@ namespace OpenSim.Capabilities.Handlers
Array.Copy(mesh.Data, start, d, 0, len); Array.Copy(mesh.Data, start, d, 0, len);
responsedata["bin_response_data"] = d; responsedata["bin_response_data"] = d;
responsedata["int_bytes"] = len; responsedata["int_bytes"] = len;
responsedata["reusecontext"] = false;
} }
} }
} }
@ -213,8 +186,6 @@ namespace OpenSim.Capabilities.Handlers
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
} }
else else
@ -222,8 +193,6 @@ namespace OpenSim.Capabilities.Handlers
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
} }
// Optionally add additional mesh types here // Optionally add additional mesh types here
@ -231,10 +200,7 @@ namespace OpenSim.Capabilities.Handlers
{ {
responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 1;
return responsedata; return responsedata;
} }
} }
@ -242,10 +208,7 @@ namespace OpenSim.Capabilities.Handlers
{ {
responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
return responsedata; return responsedata;
} }
} }

View File

@ -66,8 +66,6 @@ namespace OpenSim.Capabilities.Handlers
Hashtable ret = new Hashtable(); Hashtable ret = new Hashtable();
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
ret["content_type"] = "text/plain"; ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0; ret["int_bytes"] = 0;
string textureStr = (string)request["texture_id"]; string textureStr = (string)request["texture_id"];
string format = (string)request["format"]; string format = (string)request["format"];
@ -112,8 +110,6 @@ namespace OpenSim.Capabilities.Handlers
ret["error_status_text"] = "not found"; ret["error_status_text"] = "not found";
ret["str_response_string"] = "not found"; ret["str_response_string"] = "not found";
ret["content_type"] = "text/plain"; ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0; ret["int_bytes"] = 0;
} }
} }
@ -362,8 +358,6 @@ namespace OpenSim.Capabilities.Handlers
{ {
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data // 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 // 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) && image != null)
{ {
@ -404,11 +398,8 @@ namespace OpenSim.Capabilities.Handlers
if(managedImage != null) if(managedImage != null)
managedImage.Clear(); managedImage.Clear();
if (imgstream != null) if (imgstream != null)
{
imgstream.Close();
imgstream.Dispose(); imgstream.Dispose();
} }
}
return data; return data;
} }

View File

@ -131,49 +131,18 @@ namespace OpenSim.Capabilities.Handlers
/// <returns>False for "caller try another codec"; true otherwise</returns> /// <returns>False for "caller try another codec"; true otherwise</returns>
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, 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); // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
AssetBase texture; if(!String.IsNullOrEmpty(m_RedirectURL))
string fullID = textureID.ToString();
if (format != DefaultFormat)
fullID = fullID + "-" + format;
if (!String.IsNullOrEmpty(m_RedirectURL))
{ {
// Only try to fetch locally cached textures. Misses are redirected string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
texture = m_assetService.GetCached(fullID);
if (texture != null)
{
if (texture.Type != (sbyte)AssetType.Texture)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
}
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
else
{
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
httpResponse.RedirectLocation = textureUrl; httpResponse.RedirectLocation = textureUrl;
return true; return true;
} }
}
else // no redirect
{
// try the cache
texture = m_assetService.GetCached(fullID);
if (texture == null)
{
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
// Fetch, Misses or invalid return a 404
AssetBase texture = m_assetService.Get(textureID.ToString());
if (texture != null) if (texture != null)
{ {
if (texture.Type != (sbyte)AssetType.Texture) if (texture.Type != (sbyte)AssetType.Texture)
@ -186,8 +155,8 @@ namespace OpenSim.Capabilities.Handlers
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(httpRequest, httpResponse, texture, format);
return true; return true;
} }
else
{ // need to convert format
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
newTexture.Data = ConvertTextureData(texture, format); newTexture.Data = ConvertTextureData(texture, format);
if (newTexture.Data.Length == 0) if (newTexture.Data.Length == 0)
@ -196,22 +165,12 @@ namespace OpenSim.Capabilities.Handlers
newTexture.Flags = AssetFlags.Collectable; newTexture.Flags = AssetFlags.Collectable;
newTexture.Temporary = true; newTexture.Temporary = true;
newTexture.Local = true; newTexture.Local = true;
m_assetService.Store(newTexture);
WriteTextureData(httpRequest, httpResponse, newTexture, format); WriteTextureData(httpRequest, httpResponse, newTexture, format);
return true; return true;
} }
}
}
else // it was on the cache
{
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
}
// not found // not found
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true; return true;
} }
@ -368,9 +327,6 @@ namespace OpenSim.Capabilities.Handlers
try try
{ {
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data // 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 // 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) && image != null)
{ {
@ -412,11 +368,8 @@ namespace OpenSim.Capabilities.Handlers
managedImage.Clear(); managedImage.Clear();
if (imgstream != null) if (imgstream != null)
{
imgstream.Close();
imgstream.Dispose(); imgstream.Dispose();
} }
}
return data; return data;
} }

View File

@ -26,24 +26,12 @@
*/ */
using System; 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.Reflection;
using System.IO;
using System.Web;
using log4net; using log4net;
using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities; using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps; using Caps = OpenSim.Framework.Capabilities.Caps;
@ -56,13 +44,11 @@ namespace OpenSim.Capabilities.Handlers
private Caps m_HostCapsObj; private Caps m_HostCapsObj;
private IAssetService m_assetService; private IAssetService m_assetService;
private bool m_persistBakedTextures;
public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures) public UploadBakedTextureHandler(Caps caps, IAssetService assetService)
{ {
m_HostCapsObj = caps; m_HostCapsObj = caps;
m_assetService = assetService; m_assetService = assetService;
m_persistBakedTextures = persistBakedTextures;
} }
/// <summary> /// <summary>
@ -125,9 +111,8 @@ namespace OpenSim.Capabilities.Handlers
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
asset.Data = data; asset.Data = data;
asset.Temporary = true; asset.Temporary = true;
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are asset.Local = true;
m_assetService.Store(asset); m_assetService.Store(asset);
} }
} }
@ -151,8 +136,6 @@ namespace OpenSim.Capabilities.Handlers
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
} }
/// <summary> /// <summary>
/// Handle raw uploaded baked texture data. /// Handle raw uploaded baked texture data.
/// </summary> /// </summary>

View File

@ -67,7 +67,7 @@ namespace OpenSim.Capabilities.Handlers
server.AddStreamHandler(new RestStreamHandler( server.AddStreamHandler(new RestStreamHandler(
"POST", "POST",
"/CAPS/UploadBakedTexture/", "/CAPS/UploadBakedTexture/",
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture, new UploadBakedTextureHandler(caps, m_AssetService).UploadBakedTexture,
"UploadBakedTexture", "UploadBakedTexture",
"Upload Baked Texture Capability")); "Upload Baked Texture Capability"));

View File

@ -107,18 +107,18 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns> /// <returns></returns>
public static byte[] LLSDSerialize(object obj) public static byte[] LLSDSerialize(object obj)
{ {
StringWriter sw = new StringWriter(); using(StringWriter sw = new StringWriter())
XmlTextWriter writer = new XmlTextWriter(sw); using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None; writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty); writer.WriteStartElement(String.Empty, "llsd", String.Empty);
LLSDWriteOne(writer, obj); LLSDWriteOne(writer, obj);
writer.WriteEndElement(); writer.WriteEndElement();
writer.Flush();
writer.Close();
return Util.UTF8.GetBytes(sw.ToString()); return Util.UTF8.GetBytes(sw.ToString());
} }
}
/// <summary> /// <summary>
/// ///
@ -566,7 +566,7 @@ namespace OpenSim.Framework.Capabilities
endPos = FindEnd(llsd, 1); endPos = FindEnd(llsd, 1);
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float, if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
Utils.EnUsCulture.NumberFormat, out value)) Culture.NumberFormatInfo, out value))
return value; return value;
else else
throw new LLSDParseException("Failed to parse double value type"); throw new LLSDParseException("Failed to parse double value type");

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Xml; using System.Xml;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities namespace OpenSim.Framework.Capabilities
{ {
@ -40,18 +41,33 @@ namespace OpenSim.Framework.Capabilities
public static string SerialiseLLSDReply(object obj) public static string SerialiseLLSDReply(object obj)
{ {
StringWriter sw = new StringWriter(); using(StringWriter sw = new StringWriter())
XmlTextWriter writer = new XmlTextWriter(sw); using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None; writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty); writer.WriteStartElement(String.Empty, "llsd", String.Empty);
SerializeOSDType(writer, obj); SerializeOSDType(writer, obj);
writer.WriteEndElement(); writer.WriteEndElement();
writer.Close(); writer.Flush();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString()); //m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString(); return sw.ToString();
} }
}
public static string SerialiseLLSDReplyNoHeader(object obj)
{
using(StringWriter sw = new StringWriter())
using(XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.Formatting = Formatting.None;
SerializeOSDType(writer, obj);
writer.Flush();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString();
}
}
private static void SerializeOSDType(XmlTextWriter writer, object obj) private static void SerializeOSDType(XmlTextWriter writer, object obj)
{ {
@ -157,6 +173,22 @@ namespace OpenSim.Framework.Capabilities
// the LLSD map/array types in the array need to be deserialised // 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. // 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 else
{ {
field.SetValue(obj, enumerator.Value); field.SetValue(obj, enumerator.Value);

View File

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

View File

@ -26,37 +26,19 @@
*/ */
using System; using System;
using System.Reflection; using System.Collections.Generic;
using log4net; using OpenMetaverse;
using OpenSim.Framework;
public class GcNotify namespace OpenSim.Data
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// <summary>
/// An interface for connecting to the Mute List datastore
public static bool Enabled /// </summary>
public interface IMuteListData
{ {
get { return s_initialized; } bool Store(MuteData data);
set MuteData[] Get(UUID agentID);
{ bool Delete(UUID agentID, UUID muteID, string muteName);
if (!s_initialized && value)
new GcNotify();
s_initialized = value;
}
}
private static bool s_initialized = false;
private GcNotify() {}
~GcNotify()
{
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
{
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
if (Enabled)
new GcNotify();
}
} }
} }

View File

@ -75,6 +75,7 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "AssetStore"); Migration m = new Migration(dbcon, Assembly, "AssetStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -144,6 +145,7 @@ namespace OpenSim.Data.MySQL
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
} }
} }
dbcon.Close();
} }
return asset; return asset;
@ -156,10 +158,6 @@ namespace OpenSim.Data.MySQL
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public bool StoreAsset(AssetBase asset) override public bool StoreAsset(AssetBase asset)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
string assetName = asset.Name; string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
{ {
@ -178,6 +176,9 @@ namespace OpenSim.Data.MySQL
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
} }
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = using (MySqlCommand cmd =
new MySqlCommand( new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
@ -200,12 +201,14 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data); cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
dbcon.Close();
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message); asset.FullID, asset.Name, e.Message);
dbcon.Close();
return false; return false;
} }
} }
@ -238,6 +241,7 @@ namespace OpenSim.Data.MySQL
e); e);
} }
} }
dbcon.Close();
} }
} }
@ -270,6 +274,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
bool[] results = new bool[uuids.Length]; bool[] results = new bool[uuids.Length];
@ -334,6 +339,7 @@ namespace OpenSim.Data.MySQL
e); e);
} }
} }
dbcon.Close();
} }
return retList; return retList;
@ -350,6 +356,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?id", id); cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
return true; return true;

View File

@ -59,6 +59,7 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "AuthStore"); Migration m = new Migration(dbcon, Assembly, "AuthStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -76,31 +77,34 @@ namespace OpenSim.Data.MySQL
{ {
cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
IDataReader result = cmd.ExecuteReader(); using(IDataReader result = cmd.ExecuteReader())
{
if (result.Read()) if(result.Read())
{ {
ret.PrincipalID = principalID; ret.PrincipalID = principalID;
CheckColumnNames(result); CheckColumnNames(result);
foreach (string s in m_ColumnNames) foreach(string s in m_ColumnNames)
{ {
if (s == "UUID") if(s == "UUID")
continue; continue;
ret.Data[s] = result[s].ToString(); ret.Data[s] = result[s].ToString();
} }
dbcon.Close();
return ret; return ret;
} }
else else
{ {
dbcon.Close();
return null; return null;
} }
} }
} }
} }
}
private void CheckColumnNames(IDataReader result) private void CheckColumnNames(IDataReader result)
{ {

View File

@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL
Migration m = new Migration(dbcon, Assembly, "EstateStore"); Migration m = new Migration(dbcon, Assembly, "EstateStore");
m.Update(); m.Update();
dbcon.Close();
Type t = typeof(EstateSettings); Type t = typeof(EstateSettings);
m_Fields = t.GetFields(BindingFlags.NonPublic | m_Fields = t.GetFields(BindingFlags.NonPublic |
@ -143,7 +144,6 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
cmd.Connection = dbcon; cmd.Connection = dbcon;
bool found = false; bool found = false;
@ -171,6 +171,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
cmd.Connection = null;
if (!found && create) if (!found && create)
{ {
@ -231,6 +233,7 @@ namespace OpenSim.Data.MySQL
es.Save(); es.Save();
} }
dbcon.Close();
} }
} }
@ -263,6 +266,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
SaveBanList(es); SaveBanList(es);
@ -300,6 +304,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
@ -329,6 +334,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear(); cmd.Parameters.Clear();
} }
} }
dbcon.Close();
} }
} }
@ -358,6 +364,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear(); cmd.Parameters.Clear();
} }
} }
dbcon.Close();
} }
} }
@ -383,6 +390,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
return uuids.ToArray(); return uuids.ToArray();
@ -437,7 +445,6 @@ namespace OpenSim.Data.MySQL
reader.Close(); reader.Close();
} }
} }
dbcon.Close(); dbcon.Close();
} }
@ -466,7 +473,6 @@ namespace OpenSim.Data.MySQL
reader.Close(); reader.Close();
} }
} }
dbcon.Close(); dbcon.Close();
} }

View File

@ -78,6 +78,7 @@ namespace OpenSim.Data.MySQL
conn.Open(); conn.Open();
Migration m = new Migration(conn, Assembly, "FSAssetStore"); Migration m = new Migration(conn, Assembly, "FSAssetStore");
m.Update(); m.Update();
conn.Close();
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -121,9 +122,13 @@ namespace OpenSim.Data.MySQL
} }
catch (MySqlException e) catch (MySqlException e)
{ {
cmd.Connection = null;
conn.Close();
m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString()); m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString());
return false; return false;
} }
conn.Close();
cmd.Connection = null;
} }
return true; return true;
@ -175,7 +180,7 @@ namespace OpenSim.Data.MySQL
UpdateAccessTime(id, AccessTime); UpdateAccessTime(id, AccessTime);
} }
} }
conn.Close();
} }
return meta; return meta;
@ -206,6 +211,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?id", AssetID); cmd.Parameters.AddWithValue("?id", AssetID);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
conn.Close();
} }
} }
@ -299,6 +305,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
conn.Close();
} }
for (int i = 0; i < uuids.Length; i++) for (int i = 0; i < uuids.Length; i++)
@ -333,6 +340,7 @@ namespace OpenSim.Data.MySQL
count = Convert.ToInt32(reader["count"]); count = Convert.ToInt32(reader["count"]);
} }
} }
conn.Close();
} }
return count; return count;
@ -413,8 +421,8 @@ namespace OpenSim.Data.MySQL
imported++; imported++;
} }
} }
} }
importConn.Close();
} }
MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));

View File

@ -74,7 +74,9 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
return ExecuteNonQueryWithConnection(cmd, dbcon); int ret = ExecuteNonQueryWithConnection(cmd, dbcon);
dbcon.Close();
return ret;
} }
} }
else else
@ -97,12 +99,15 @@ namespace OpenSim.Data.MySQL
try try
{ {
return cmd.ExecuteNonQuery(); int ret = cmd.ExecuteNonQuery();
cmd.Connection = null;
return ret;
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error(e.Message, e); m_log.Error(e.Message, e);
m_log.Error(Environment.StackTrace.ToString()); m_log.Error(Environment.StackTrace.ToString());
cmd.Connection = null;
return 0; return 0;
} }
} }

View File

@ -29,11 +29,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Reflection; using System.Reflection;
using log4net; using System.Text;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Data.MySQL namespace OpenSim.Data.MySQL
{ {
@ -129,25 +127,27 @@ namespace OpenSim.Data.MySQL
public virtual T[] Get(string[] fields, string[] keys, string options) public virtual T[] Get(string[] fields, string[] keys, string options)
{ {
if (fields.Length != keys.Length) int flen = fields.Length;
if (flen == 0 || flen != keys.Length)
return new T[0]; return new T[0];
List<string> terms = new List<string>(); int flast = flen - 1;
StringBuilder sb = new StringBuilder(1024);
sb.AppendFormat("select * from {0} where ", m_Realm);
using (MySqlCommand cmd = new MySqlCommand()) using (MySqlCommand cmd = new MySqlCommand())
{ {
for (int i = 0 ; i < fields.Length ; i++) for (int i = 0 ; i < flen ; i++)
{ {
cmd.Parameters.AddWithValue(fields[i], keys[i]); cmd.Parameters.AddWithValue(fields[i], keys[i]);
terms.Add("`" + fields[i] + "` = ?" + fields[i]); if(i< flast)
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
else
sb.AppendFormat("`{0}` = ?{0} ", fields[i]);
} }
string where = String.Join(" and ", terms.ToArray()); sb.Append(options);
cmd.CommandText = sb.ToString();
string query = String.Format("select * from {0} where {1} {2}",
m_Realm, where, options);
cmd.CommandText = query;
return DoQuery(cmd); return DoQuery(cmd);
} }
@ -160,8 +160,9 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
T[] ret = DoQueryWithConnection(cmd, dbcon);
return DoQueryWithConnection(cmd, dbcon); dbcon.Close();
return ret;
} }
} }
else else
@ -203,7 +204,7 @@ namespace OpenSim.Data.MySQL
if (m_Fields[name].FieldType == typeof(bool)) if (m_Fields[name].FieldType == typeof(bool))
{ {
int v = Convert.ToInt32(reader[name]); int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v != 0 ? true : false); m_Fields[name].SetValue(row, v != 0);
} }
else if (m_Fields[name].FieldType == typeof(UUID)) else if (m_Fields[name].FieldType == typeof(UUID))
{ {
@ -243,7 +244,7 @@ namespace OpenSim.Data.MySQL
result.Add(row); result.Add(row);
} }
} }
cmd.Connection = null;
return result.ToArray(); return result.ToArray();
} }
@ -402,7 +403,10 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
cmd.Connection = dbcon; cmd.Connection = dbcon;
return cmd.ExecuteScalar(); Object ret = cmd.ExecuteScalar();
cmd.Connection = null;
dbcon.Close();
return ret;
} }
} }
else else

View File

@ -78,6 +78,7 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, assem, "InventoryStore"); Migration m = new Migration(dbcon, assem, "InventoryStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL
items.Add(item); items.Add(item);
} }
dbcon.Close();
return items; return items;
} }
} }
@ -170,6 +172,7 @@ namespace OpenSim.Data.MySQL
while (reader.Read()) while (reader.Read())
items.Add(readInventoryFolder(reader)); items.Add(readInventoryFolder(reader));
dbcon.Close();
return items; return items;
} }
} }
@ -221,6 +224,7 @@ namespace OpenSim.Data.MySQL
if (items.Count > 0) if (items.Count > 0)
rootFolder = items[0]; rootFolder = items[0];
dbcon.Close();
return rootFolder; return rootFolder;
} }
} }
@ -261,6 +265,7 @@ namespace OpenSim.Data.MySQL
while (reader.Read()) while (reader.Read())
items.Add(readInventoryFolder(reader)); items.Add(readInventoryFolder(reader));
dbcon.Close();
return items; return items;
} }
} }
@ -352,6 +357,7 @@ namespace OpenSim.Data.MySQL
if (reader.Read()) if (reader.Read())
item = readInventoryItem(reader); item = readInventoryItem(reader);
dbcon.Close();
return item; return item;
} }
} }
@ -417,6 +423,7 @@ namespace OpenSim.Data.MySQL
if (reader.Read()) if (reader.Read())
folder = readInventoryFolder(reader); folder = readInventoryFolder(reader);
dbcon.Close();
return folder; return folder;
} }
} }
@ -504,6 +511,7 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock) lock (m_dbLock)
result.ExecuteNonQuery(); result.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -540,6 +548,7 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock) lock (m_dbLock)
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -600,6 +609,7 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString()); m_log.Error(e.ToString());
} }
} }
dbcon.Close();
} }
} }
@ -643,6 +653,7 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString()); m_log.Error(e.ToString());
} }
} }
dbcon.Close();
} }
} }
@ -806,6 +817,7 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock) lock (m_dbLock)
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -833,6 +845,7 @@ namespace OpenSim.Data.MySQL
lock (m_dbLock) lock (m_dbLock)
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (MySqlException e) catch (MySqlException e)
@ -886,6 +899,7 @@ namespace OpenSim.Data.MySQL
if (item != null) if (item != null)
list.Add(item); list.Add(item);
} }
dbcon.Close();
return list; return list;
} }
} }

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using OpenMetaverse;
using OpenSim.Framework;
using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL
{
public class MySqlMuteListData : MySQLGenericTableHandler<MuteData>, IMuteListData
{
public MySqlMuteListData(string connectionString)
: base(connectionString, "MuteList", "MuteListStore")
{
}
public MuteData[] Get(UUID agentID)
{
MuteData[] data = base.Get("AgentID", agentID.ToString());
return data;
}
public bool Delete(UUID agentID, UUID muteID, string muteName)
{
string cmnd ="delete from MuteList where AgentID = ?AgentID and MuteID = ?MuteID and MuteName = ?MuteName";
using (MySqlCommand cmd = new MySqlCommand(cmnd))
{
cmd.Parameters.AddWithValue("?AgentID", agentID.ToString());
cmd.Parameters.AddWithValue("?MuteID", muteID.ToString());
cmd.Parameters.AddWithValue("?MuteName", muteName);
if (ExecuteNonQuery(cmd) > 0)
return true;
return false;
}
}
}
}

View File

@ -60,6 +60,7 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "GridStore"); Migration m = new Migration(dbcon, Assembly, "GridStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -260,6 +261,8 @@ namespace OpenSim.Data.MySQL
retList.Add(ret); retList.Add(ret);
} }
} }
cmd.Connection = null;
dbcon.Close();
} }
return retList; return retList;

View File

@ -88,6 +88,7 @@ namespace OpenSim.Data.MySQL
// //
Migration m = new Migration(dbcon, Assembly, "RegionStore"); Migration m = new Migration(dbcon, Assembly, "RegionStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -187,7 +188,7 @@ namespace OpenSim.Data.MySQL
"LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " + "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
"AttachedPosY, AttachedPosZ, " + "AttachedPosY, AttachedPosZ, " +
"PhysicsShapeType, Density, GravityModifier, " + "PhysicsShapeType, Density, GravityModifier, " +
"Friction, Restitution, Vehicle, DynAttrs, " + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " +
"RotationAxisLocks" + "RotationAxisLocks" +
") values (" + "?UUID, " + ") values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " + "?CreationDate, ?Name, ?Text, " +
@ -224,7 +225,7 @@ namespace OpenSim.Data.MySQL
"?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
"?AttachedPosY, ?AttachedPosZ, " + "?AttachedPosY, ?AttachedPosZ, " +
"?PhysicsShapeType, ?Density, ?GravityModifier, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " +
"?Friction, ?Restitution, ?Vehicle, ?DynAttrs," + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," +
"?RotationAxisLocks)"; "?RotationAxisLocks)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID); FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -261,6 +262,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
} }
dbcon.Close();
} }
} }
} }
@ -300,6 +302,7 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; cmd.CommandText = "delete from prims where SceneGroupID= ?UUID";
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
@ -334,6 +337,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
} }
@ -372,6 +376,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
} }
@ -411,6 +416,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
} }
@ -460,6 +466,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
@ -535,6 +542,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
@ -580,6 +588,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
prim.Inventory.RestoreInventoryItems(inventory); prim.Inventory.RestoreInventoryItems(inventory);
@ -598,6 +607,10 @@ namespace OpenSim.Data.MySQL
{ {
m_log.Info("[REGION DB]: Storing terrain"); m_log.Info("[REGION DB]: Storing terrain");
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
lock (m_dbLock) lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@ -617,10 +630,6 @@ namespace OpenSim.Data.MySQL
"Revision, Heightfield) values (?RegionUUID, " + "Revision, Heightfield) values (?RegionUUID, " +
"?Revision, ?Heightfield)"; "?Revision, ?Heightfield)";
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
@ -634,6 +643,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
}); });
@ -645,6 +655,10 @@ namespace OpenSim.Data.MySQL
{ {
m_log.Info("[REGION DB]: Storing Baked terrain"); m_log.Info("[REGION DB]: Storing Baked terrain");
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
lock (m_dbLock) lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@ -664,10 +678,6 @@ namespace OpenSim.Data.MySQL
"Revision, Heightfield) values (?RegionUUID, " + "Revision, Heightfield) values (?RegionUUID, " +
"?Revision, ?Heightfield)"; "?Revision, ?Heightfield)";
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
@ -681,6 +691,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
}); });
@ -700,9 +711,12 @@ namespace OpenSim.Data.MySQL
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{ {
TerrainData terrData = null; TerrainData terrData = null;
byte[] blob = null;
int rev = 0;
lock (m_dbLock) lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -718,17 +732,20 @@ namespace OpenSim.Data.MySQL
{ {
while (reader.Read()) while (reader.Read())
{ {
int rev = Convert.ToInt32(reader["Revision"]); rev = Convert.ToInt32(reader["Revision"]);
if ((reader["Heightfield"] != DBNull.Value)) if ((reader["Heightfield"] != DBNull.Value))
{ {
byte[] blob = (byte[])reader["Heightfield"]; blob = (byte[])reader["Heightfield"];
}
}
}
}
dbcon.Close();
}
}
if(blob != null)
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
}
}
}
}
}
return terrData; return terrData;
} }
@ -736,6 +753,8 @@ namespace OpenSim.Data.MySQL
public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{ {
TerrainData terrData = null; TerrainData terrData = null;
byte[] blob = null;
int rev = 0;
lock (m_dbLock) lock (m_dbLock)
{ {
@ -753,17 +772,19 @@ namespace OpenSim.Data.MySQL
{ {
while (reader.Read()) while (reader.Read())
{ {
int rev = Convert.ToInt32(reader["Revision"]); rev = Convert.ToInt32(reader["Revision"]);
if ((reader["Heightfield"] != DBNull.Value)) if ((reader["Heightfield"] != DBNull.Value))
{ {
byte[] blob = (byte[])reader["Heightfield"]; blob = (byte[])reader["Heightfield"];
}
}
}
}
dbcon.Close();
}
}
if(blob != null)
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
}
}
}
}
}
return terrData; return terrData;
} }
@ -783,6 +804,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
} }
@ -842,6 +864,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear(); cmd.Parameters.Clear();
} }
} }
dbcon.Close();
} }
} }
} }
@ -863,12 +886,13 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd); using(IDataReader result = ExecuteReader(cmd))
if (!result.Read()) {
if(!result.Read())
{ {
//No result, so store our default windlight profile and return it //No result, so store our default windlight profile and return it
nWP.regionID = regionUUID; nWP.regionID = regionUUID;
// StoreRegionWindlightSettings(nWP); // StoreRegionWindlightSettings(nWP);
return nWP; return nWP;
} }
else else
@ -891,7 +915,7 @@ namespace OpenSim.Data.MySQL
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
@ -940,6 +964,8 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
}
return nWP; return nWP;
} }
@ -947,6 +973,7 @@ namespace OpenSim.Data.MySQL
public virtual RegionSettings LoadRegionSettings(UUID regionUUID) public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
{ {
RegionSettings rs = null; RegionSettings rs = null;
bool needStore = false;
lock (m_dbLock) lock (m_dbLock)
{ {
@ -972,12 +999,16 @@ namespace OpenSim.Data.MySQL
rs.RegionUUID = regionUUID; rs.RegionUUID = regionUUID;
rs.OnSave += StoreRegionSettings; rs.OnSave += StoreRegionSettings;
needStore = true;
}
}
}
dbcon.Close();
}
}
if(needStore)
StoreRegionSettings(rs); StoreRegionSettings(rs);
}
}
}
}
}
LoadSpawnPoints(rs); LoadSpawnPoints(rs);
@ -992,31 +1023,32 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = dbcon.CreateCommand()) using (MySqlCommand cmd = dbcon.CreateCommand())
{ {
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"
;
cmd.Parameters.AddWithValue("region_id", wl.regionID); cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
@ -1084,6 +1116,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
@ -1099,6 +1132,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
@ -1117,14 +1151,19 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd); using(IDataReader result = ExecuteReader(cmd))
if (!result.Read())
{ {
if(!result.Read())
{
dbcon.Close();
return String.Empty; return String.Empty;
} }
else else
{ {
return Convert.ToString(result["llsd_settings"]); string ret = Convert.ToString(result["llsd_settings"]);
dbcon.Close();
return ret;
}
} }
} }
} }
@ -1145,6 +1184,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
@ -1160,6 +1200,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
} }
} }
#endregion #endregion
@ -1212,7 +1253,7 @@ namespace OpenSim.Data.MySQL
FillRegionSettingsCommand(cmd, rs); FillRegionSettingsCommand(cmd, rs);
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
dbcon.Close();
SaveSpawnPoints(rs); SaveSpawnPoints(rs);
} }
} }
@ -1259,6 +1300,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
@ -1452,6 +1494,11 @@ namespace OpenSim.Data.MySQL
prim.VehicleParams = vehicle; prim.VehicleParams = vehicle;
} }
PhysicsInertiaData pdata = null;
if (row["PhysInertia"].ToString() != String.Empty)
pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString());
prim.PhysicsInertia = pdata;
return prim; return prim;
} }
@ -1810,6 +1857,11 @@ namespace OpenSim.Data.MySQL
else else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
if (prim.PhysicsInertia != null)
cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2());
else
cmd.Parameters.AddWithValue("PhysInertia", String.Empty);
if (prim.VehicleParams != null) if (prim.VehicleParams != null)
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
else else
@ -2113,6 +2165,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
} }
dbcon.Close();
} }
} }
} }
@ -2142,6 +2195,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
@ -2177,6 +2231,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
} }
@ -2211,6 +2266,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear(); cmd.Parameters.Clear();
} }
} }
dbcon.Close();
} }
} }
} }
@ -2230,6 +2286,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
@ -2247,6 +2304,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
@ -2270,6 +2328,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
return ret; return ret;

View File

@ -69,6 +69,7 @@ namespace OpenSim.Data.MySQL
Migration m = new Migration(dbcon, Assembly, "UserProfiles"); Migration m = new Migration(dbcon, Assembly, "UserProfiles");
m.Update(); m.Update();
dbcon.Close();
} }
} }
#endregion Member Functions #endregion Member Functions
@ -89,7 +90,7 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
{ {
string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; const string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id";
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{ {
@ -111,8 +112,7 @@ namespace OpenSim.Data.MySQL
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA] GetClassifiedRecords exception {0}", e.Message);
": UserAccount exception {0}", e.Message);
} }
n.Add("classifieduuid", OSD.FromUUID(Id)); n.Add("classifieduuid", OSD.FromUUID(Id));
n.Add("name", OSD.FromString(Name)); n.Add("name", OSD.FromString(Name));
@ -121,58 +121,58 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
return data; return data;
} }
public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
{ {
string query = string.Empty; const string query =
"INSERT INTO classifieds ("
+ "`classifieduuid`,"
query += "INSERT INTO classifieds ("; + "`creatoruuid`,"
query += "`classifieduuid`,"; + "`creationdate`,"
query += "`creatoruuid`,"; + "`expirationdate`,"
query += "`creationdate`,"; + "`category`,"
query += "`expirationdate`,"; + "`name`,"
query += "`category`,"; + "`description`,"
query += "`name`,"; + "`parceluuid`,"
query += "`description`,"; + "`parentestate`,"
query += "`parceluuid`,"; + "`snapshotuuid`,"
query += "`parentestate`,"; + "`simname`,"
query += "`snapshotuuid`,"; + "`posglobal`,"
query += "`simname`,"; + "`parcelname`,"
query += "`posglobal`,"; + "`classifiedflags`,"
query += "`parcelname`,"; + "`priceforlisting`) "
query += "`classifiedflags`,"; + "VALUES ("
query += "`priceforlisting`) "; + "?ClassifiedId,"
query += "VALUES ("; + "?CreatorId,"
query += "?ClassifiedId,"; + "?CreatedDate,"
query += "?CreatorId,"; + "?ExpirationDate,"
query += "?CreatedDate,"; + "?Category,"
query += "?ExpirationDate,"; + "?Name,"
query += "?Category,"; + "?Description,"
query += "?Name,"; + "?ParcelId,"
query += "?Description,"; + "?ParentEstate,"
query += "?ParcelId,"; + "?SnapshotId,"
query += "?ParentEstate,"; + "?SimName,"
query += "?SnapshotId,"; + "?GlobalPos,"
query += "?SimName,"; + "?ParcelName,"
query += "?GlobalPos,"; + "?Flags,"
query += "?ParcelName,"; + "?ListingPrice ) "
query += "?Flags,"; + "ON DUPLICATE KEY UPDATE "
query += "?ListingPrice ) "; + "category=?Category, "
query += "ON DUPLICATE KEY UPDATE "; + "expirationdate=?ExpirationDate, "
query += "category=?Category, "; + "name=?Name, "
query += "expirationdate=?ExpirationDate, "; + "description=?Description, "
query += "name=?Name, "; + "parentestate=?ParentEstate, "
query += "description=?Description, "; + "posglobal=?GlobalPos, "
query += "parentestate=?ParentEstate, "; + "parcelname=?ParcelName, "
query += "posglobal=?GlobalPos, "; + "classifiedflags=?Flags, "
query += "parcelname=?ParcelName, "; + "priceforlisting=?ListingPrice, "
query += "classifiedflags=?Flags, "; + "snapshotuuid=?SnapshotId"
query += "priceforlisting=?ListingPrice, "; ;
query += "snapshotuuid=?SnapshotId";
if(string.IsNullOrEmpty(ad.ParcelName)) if(string.IsNullOrEmpty(ad.ParcelName))
ad.ParcelName = "Unknown"; ad.ParcelName = "Unknown";
@ -228,12 +228,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdateClassifiedRecord exception {0}", e.Message);
": ClassifiedesUpdate exception {0}", e.Message);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -242,10 +242,7 @@ namespace OpenSim.Data.MySQL
public bool DeleteClassifiedRecord(UUID recordId) public bool DeleteClassifiedRecord(UUID recordId)
{ {
string query = string.Empty; const string query = "DELETE FROM classifieds WHERE classifieduuid = ?recordId";
query += "DELETE FROM classifieds WHERE ";
query += "classifieduuid = ?recordId";
try try
{ {
@ -258,12 +255,12 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?recordId", recordId.ToString()); cmd.Parameters.AddWithValue("?recordId", recordId.ToString());
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: DeleteClassifiedRecord exception {0}", e.Message);
": DeleteClassifiedRecord exception {0}", e.Message);
return false; return false;
} }
return true; return true;
@ -271,10 +268,8 @@ namespace OpenSim.Data.MySQL
public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result)
{ {
string query = string.Empty;
query += "SELECT * FROM classifieds WHERE "; const string query = "SELECT * FROM classifieds WHERE classifieduuid = ?AdId";
query += "classifieduuid = ?AdId";
try try
{ {
@ -312,8 +307,7 @@ namespace OpenSim.Data.MySQL
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetClassifiedInfo exception {0}", e.Message);
": GetPickInfo exception {0}", e.Message);
} }
return true; return true;
} }
@ -322,10 +316,8 @@ namespace OpenSim.Data.MySQL
#region Picks Queries #region Picks Queries
public OSDArray GetAvatarPicks(UUID avatarId) public OSDArray GetAvatarPicks(UUID avatarId)
{ {
string query = string.Empty; const string query = "SELECT `pickuuid`,`name` FROM userpicks WHERE creatoruuid = ?Id";
query += "SELECT `pickuuid`,`name` FROM userpicks WHERE ";
query += "creatoruuid = ?Id";
OSDArray data = new OSDArray(); OSDArray data = new OSDArray();
try try
@ -352,24 +344,20 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarPicks exception {0}", e.Message);
": GetAvatarPicks exception {0}", e.Message);
} }
return data; return data;
} }
public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId)
{ {
string query = string.Empty;
UserProfilePick pick = new UserProfilePick(); UserProfilePick pick = new UserProfilePick();
const string query = "SELECT * FROM userpicks WHERE creatoruuid = ?CreatorId AND pickuuid = ?PickId";
query += "SELECT * FROM userpicks WHERE ";
query += "creatoruuid = ?CreatorId AND ";
query += "pickuuid = ?PickId";
try try
{ {
@ -414,41 +402,40 @@ namespace OpenSim.Data.MySQL
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetPickInfo exception {0}", e.Message);
": GetPickInfo exception {0}", e.Message);
} }
return pick; return pick;
} }
public bool UpdatePicksRecord(UserProfilePick pick) public bool UpdatePicksRecord(UserProfilePick pick)
{ {
string query = string.Empty; const string query =
"INSERT INTO userpicks VALUES ("
query += "INSERT INTO userpicks VALUES ("; + "?PickId,"
query += "?PickId,"; + "?CreatorId,"
query += "?CreatorId,"; + "?TopPick,"
query += "?TopPick,"; + "?ParcelId,"
query += "?ParcelId,"; + "?Name,"
query += "?Name,"; + "?Desc,"
query += "?Desc,"; + "?SnapshotId,"
query += "?SnapshotId,"; + "?User,"
query += "?User,"; + "?Original,"
query += "?Original,"; + "?SimName,"
query += "?SimName,"; + "?GlobalPos,"
query += "?GlobalPos,"; + "?SortOrder,"
query += "?SortOrder,"; + "?Enabled,"
query += "?Enabled,"; + "?Gatekeeper)"
query += "?Gatekeeper)"; + "ON DUPLICATE KEY UPDATE "
query += "ON DUPLICATE KEY UPDATE "; + "parceluuid=?ParcelId,"
query += "parceluuid=?ParcelId,"; + "name=?Name,"
query += "name=?Name,"; + "description=?Desc,"
query += "description=?Desc,"; + "user=?User,"
query += "user=?User,"; + "simname=?SimName,"
query += "simname=?SimName,"; + "snapshotuuid=?SnapshotId,"
query += "snapshotuuid=?SnapshotId,"; + "pickuuid=?PickId,"
query += "pickuuid=?PickId,"; + "posglobal=?GlobalPos,"
query += "posglobal=?GlobalPos,"; + "gatekeeper=?Gatekeeper"
query += "gatekeeper=?Gatekeeper"; ;
try try
{ {
@ -474,12 +461,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdatePicksRecord exception {0}", e.Message);
": UpdateAvatarNotes exception {0}", e.Message);
return false; return false;
} }
return true; return true;
@ -487,10 +474,7 @@ namespace OpenSim.Data.MySQL
public bool DeletePicksRecord(UUID pickId) public bool DeletePicksRecord(UUID pickId)
{ {
string query = string.Empty; string query = "DELETE FROM userpicks WHERE pickuuid = ?PickId";
query += "DELETE FROM userpicks WHERE ";
query += "pickuuid = ?PickId";
try try
{ {
@ -504,12 +488,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: DeletePicksRecord exception {0}", e.Message);
": DeleteUserPickRecord exception {0}", e.Message);
return false; return false;
} }
return true; return true;
@ -519,11 +503,7 @@ namespace OpenSim.Data.MySQL
#region Avatar Notes Queries #region Avatar Notes Queries
public bool GetAvatarNotes(ref UserProfileNotes notes) public bool GetAvatarNotes(ref UserProfileNotes notes)
{ // WIP { // WIP
string query = string.Empty; const string query = "SELECT `notes` FROM usernotes WHERE useruuid = ?Id AND targetuuid = ?TargetId";
query += "SELECT `notes` FROM usernotes WHERE ";
query += "useruuid = ?Id AND ";
query += "targetuuid = ?TargetId";
try try
{ {
@ -548,38 +528,37 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarNotes exception {0}", e.Message);
": GetAvatarNotes exception {0}", e.Message);
} }
return true; return true;
} }
public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result)
{ {
string query = string.Empty; string query;
bool remove; bool remove;
if(string.IsNullOrEmpty(note.Notes)) if(string.IsNullOrEmpty(note.Notes))
{ {
remove = true; remove = true;
query += "DELETE FROM usernotes WHERE "; query = "DELETE FROM usernotes WHERE useruuid=?UserId AND targetuuid=?TargetId";
query += "useruuid=?UserId AND ";
query += "targetuuid=?TargetId";
} }
else else
{ {
remove = false; remove = false;
query += "INSERT INTO usernotes VALUES ( "; query = "INSERT INTO usernotes VALUES ("
query += "?UserId,"; + "?UserId,"
query += "?TargetId,"; + "?TargetId,"
query += "?Notes )"; + "?Notes )"
query += "ON DUPLICATE KEY "; + "ON DUPLICATE KEY "
query += "UPDATE "; + "UPDATE "
query += "notes=?Notes"; + "notes=?Notes"
;
} }
try try
@ -596,12 +575,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarNotes exception {0}", e.Message);
": UpdateAvatarNotes exception {0}", e.Message);
return false; return false;
} }
return true; return true;
@ -612,10 +591,7 @@ namespace OpenSim.Data.MySQL
#region Avatar Properties #region Avatar Properties
public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) public bool GetAvatarProperties(ref UserProfileProperties props, ref string result)
{ {
string query = string.Empty; string query = "SELECT * FROM userprofile WHERE useruuid = ?Id";
query += "SELECT * FROM userprofile WHERE ";
query += "useruuid = ?Id";
try try
{ {
@ -664,35 +640,36 @@ namespace OpenSim.Data.MySQL
props.PublishProfile = false; props.PublishProfile = false;
props.PublishMature = false; props.PublishMature = false;
query = "INSERT INTO userprofile ("; query = "INSERT INTO userprofile ("
query += "useruuid, "; + "useruuid, "
query += "profilePartner, "; + "profilePartner, "
query += "profileAllowPublish, "; + "profileAllowPublish, "
query += "profileMaturePublish, "; + "profileMaturePublish, "
query += "profileURL, "; + "profileURL, "
query += "profileWantToMask, "; + "profileWantToMask, "
query += "profileWantToText, "; + "profileWantToText, "
query += "profileSkillsMask, "; + "profileSkillsMask, "
query += "profileSkillsText, "; + "profileSkillsText, "
query += "profileLanguages, "; + "profileLanguages, "
query += "profileImage, "; + "profileImage, "
query += "profileAboutText, "; + "profileAboutText, "
query += "profileFirstImage, "; + "profileFirstImage, "
query += "profileFirstText) VALUES ("; + "profileFirstText) VALUES ("
query += "?userId, "; + "?userId, "
query += "?profilePartner, "; + "?profilePartner, "
query += "?profileAllowPublish, "; + "?profileAllowPublish, "
query += "?profileMaturePublish, "; + "?profileMaturePublish, "
query += "?profileURL, "; + "?profileURL, "
query += "?profileWantToMask, "; + "?profileWantToMask, "
query += "?profileWantToText, "; + "?profileWantToText, "
query += "?profileSkillsMask, "; + "?profileSkillsMask, "
query += "?profileSkillsText, "; + "?profileSkillsText, "
query += "?profileLanguages, "; + "?profileLanguages, "
query += "?profileImage, "; + "?profileImage, "
query += "?profileAboutText, "; + "?profileAboutText, "
query += "?profileFirstImage, "; + "?profileFirstImage, "
query += "?profileFirstText)"; + "?profileFirstText)"
;
dbcon.Close(); dbcon.Close();
dbcon.Open(); dbcon.Open();
@ -719,12 +696,12 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarProperties exception {0}", e.Message);
": Requst properties exception {0}", e.Message);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -733,15 +710,10 @@ namespace OpenSim.Data.MySQL
public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result)
{ {
string query = string.Empty; const string query = "UPDATE userprofile SET profileURL=?profileURL,"
+ "profileImage=?image, profileAboutText=?abouttext,"
query += "UPDATE userprofile SET "; + "profileFirstImage=?firstlifeimage, profileFirstText=?firstlifetext "
query += "profileURL=?profileURL, "; + "WHERE useruuid=?uuid";
query += "profileImage=?image, ";
query += "profileAboutText=?abouttext,";
query += "profileFirstImage=?firstlifeimage,";
query += "profileFirstText=?firstlifetext ";
query += "WHERE useruuid=?uuid";
try try
{ {
@ -759,12 +731,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarProperties exception {0}", e.Message);
": AgentPropertiesUpdate exception {0}", e.Message);
return false; return false;
} }
@ -775,15 +747,13 @@ namespace OpenSim.Data.MySQL
#region Avatar Interests #region Avatar Interests
public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) public bool UpdateAvatarInterests(UserProfileProperties up, ref string result)
{ {
string query = string.Empty; const string query = "UPDATE userprofile SET "
+ "profileWantToMask=?WantMask, "
query += "UPDATE userprofile SET "; + "profileWantToText=?WantText,"
query += "profileWantToMask=?WantMask, "; + "profileSkillsMask=?SkillsMask,"
query += "profileWantToText=?WantText,"; + "profileSkillsText=?SkillsText, "
query += "profileSkillsMask=?SkillsMask,"; + "profileLanguages=?Languages "
query += "profileSkillsText=?SkillsText, "; + "WHERE useruuid=?uuid";
query += "profileLanguages=?Languages ";
query += "WHERE useruuid=?uuid";
try try
{ {
@ -805,8 +775,7 @@ namespace OpenSim.Data.MySQL
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarInterests exception {0}", e.Message);
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -817,18 +786,17 @@ namespace OpenSim.Data.MySQL
public OSDArray GetUserImageAssets(UUID avatarId) public OSDArray GetUserImageAssets(UUID avatarId)
{ {
OSDArray data = new OSDArray(); OSDArray data = new OSDArray();
string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; const string queryA = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id";
// Get classified image assets // Get classified image assets
try try
{ {
using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
{ {
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon)) using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`classifieds`"), dbcon))
{ {
cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
@ -847,7 +815,7 @@ namespace OpenSim.Data.MySQL
dbcon.Close(); dbcon.Close();
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`userpicks`"), dbcon))
{ {
cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
@ -866,9 +834,9 @@ namespace OpenSim.Data.MySQL
dbcon.Close(); dbcon.Close();
dbcon.Open(); dbcon.Open();
query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; const string queryB = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id";
using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) using (MySqlCommand cmd = new MySqlCommand(queryB, dbcon))
{ {
cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
@ -884,12 +852,12 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetUserImageAssets exception {0}", e.Message);
": GetAvatarNotes exception {0}", e.Message);
} }
return data; return data;
} }
@ -897,11 +865,7 @@ namespace OpenSim.Data.MySQL
#region User Preferences #region User Preferences
public bool GetUserPreferences(ref UserPreferences pref, ref string result) public bool GetUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; const string query = "SELECT imviaemail,visible,email FROM usersettings WHERE useruuid = ?Id";
query += "SELECT imviaemail,visible,email FROM ";
query += "usersettings WHERE ";
query += "useruuid = ?Id";
try try
{ {
@ -925,10 +889,9 @@ namespace OpenSim.Data.MySQL
dbcon.Close(); dbcon.Close();
dbcon.Open(); dbcon.Open();
query = "INSERT INTO usersettings VALUES "; const string queryB = "INSERT INTO usersettings VALUES (?uuid,'false','false', ?Email)";
query += "(?uuid,'false','false', ?Email)";
using (MySqlCommand put = new MySqlCommand(query, dbcon)) using (MySqlCommand put = new MySqlCommand(queryB, dbcon))
{ {
put.Parameters.AddWithValue("?Email", pref.EMail); put.Parameters.AddWithValue("?Email", pref.EMail);
@ -939,12 +902,12 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetUserPreferences exception {0}", e.Message);
": Get preferences exception {0}", e.Message);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -953,13 +916,9 @@ namespace OpenSim.Data.MySQL
public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; const string query = "UPDATE usersettings SET imviaemail=?ImViaEmail,"
+ "visible=?Visible, email=?EMail "
query += "UPDATE usersettings SET "; + "WHERE useruuid=?uuid";
query += "imviaemail=?ImViaEmail, ";
query += "visible=?Visible, ";
query += "email=?EMail ";
query += "WHERE useruuid=?uuid";
try try
{ {
@ -975,12 +934,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: UpdateUserPreferences exception {0} {1}", e.Message, e.InnerException);
": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -991,11 +950,7 @@ namespace OpenSim.Data.MySQL
#region Integration #region Integration
public bool GetUserAppData(ref UserAppData props, ref string result) public bool GetUserAppData(ref UserAppData props, ref string result)
{ {
string query = string.Empty; const string query = "SELECT * FROM `userdata` WHERE UserId = ?Id AND TagId = ?TagId";
query += "SELECT * FROM `userdata` WHERE ";
query += "UserId = ?Id AND ";
query += "TagId = ?TagId";
try try
{ {
@ -1017,13 +972,8 @@ namespace OpenSim.Data.MySQL
} }
else else
{ {
query += "INSERT INTO userdata VALUES ( "; const string queryB = "INSERT INTO userdata VALUES (?UserId, ?TagId, ?DataKey, ?DataVal)";
query += "?UserId,"; using (MySqlCommand put = new MySqlCommand(queryB, dbcon))
query += "?TagId,";
query += "?DataKey,";
query += "?DataVal) ";
using (MySqlCommand put = new MySqlCommand(query, dbcon))
{ {
put.Parameters.AddWithValue("?UserId", props.UserId.ToString()); put.Parameters.AddWithValue("?UserId", props.UserId.ToString());
put.Parameters.AddWithValue("?TagId", props.TagId.ToString()); put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
@ -1035,12 +985,12 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: GetUserAppData exception {0}", e.Message);
": Requst application data exception {0}", e.Message);
result = e.Message; result = e.Message;
return false; return false;
} }
@ -1049,14 +999,7 @@ namespace OpenSim.Data.MySQL
public bool SetUserAppData(UserAppData props, ref string result) public bool SetUserAppData(UserAppData props, ref string result)
{ {
string query = string.Empty; const string query = "UPDATE userdata SET TagId = ?TagId, DataKey = ?DataKey, DataVal = ?DataVal WHERE UserId = ?UserId AND TagId = ?TagId";
query += "UPDATE userdata SET ";
query += "TagId = ?TagId, ";
query += "DataKey = ?DataKey, ";
query += "DataVal = ?DataVal WHERE ";
query += "UserId = ?UserId AND ";
query += "TagId = ?TagId";
try try
{ {
@ -1072,12 +1015,12 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]: SetUserAppData exception {0}", e.Message);
": SetUserData exception {0}", e.Message);
return false; return false;
} }
return true; return true;

View File

@ -97,6 +97,7 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "XAssetStore"); Migration m = new Migration(dbcon, Assembly, "XAssetStore");
m.Update(); m.Update();
dbcon.Close();
} }
} }
@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
AssetBase asset = null; AssetBase asset = null;
int accessTime = 0;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -140,7 +142,6 @@ namespace OpenSim.Data.MySQL
dbcon)) dbcon))
{ {
cmd.Parameters.AddWithValue("?ID", assetID.ToString()); cmd.Parameters.AddWithValue("?ID", assetID.ToString());
try try
{ {
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
@ -159,23 +160,7 @@ namespace OpenSim.Data.MySQL
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]); asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
accessTime = (int)dbReader["AccessTime"];
if (m_enableCompression)
{
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
{
MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
} }
} }
} }
@ -184,8 +169,37 @@ namespace OpenSim.Data.MySQL
m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e); m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
} }
} }
dbcon.Close();
} }
if(asset == null)
return asset;
if(accessTime > 0)
{
try
{
UpdateAccessTime(asset.Metadata, accessTime);
}
catch { }
}
if (m_enableCompression && asset.Data != null)
{
using(MemoryStream ms = new MemoryStream(asset.Data))
using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress))
{
using(MemoryStream outputStream = new MemoryStream())
{
decompressionStream.CopyTo(outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
}
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
return asset; return asset;
} }
@ -303,6 +317,7 @@ namespace OpenSim.Data.MySQL
transaction.Commit(); transaction.Commit();
} }
dbcon.Close();
} }
} }
@ -344,6 +359,7 @@ namespace OpenSim.Data.MySQL
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
assetMetadata.ID, assetMetadata.Name); assetMetadata.ID, assetMetadata.Name);
} }
dbcon.Close();
} }
} }
@ -474,6 +490,7 @@ namespace OpenSim.Data.MySQL
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
} }
} }
dbcon.Close();
} }
return retList; return retList;
@ -492,9 +509,9 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?ID", id); cmd.Parameters.AddWithValue("?ID", id);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?) // keep a reference count (?)
dbcon.Close();
} }
return true; return true;

View File

@ -328,7 +328,6 @@ namespace OpenSim.Data.MySQL
{ {
return false; return false;
} }
cmd.Dispose();
} }
dbcon.Close(); dbcon.Close();

View File

@ -0,0 +1,16 @@
:VERSION 1
BEGIN;
CREATE TABLE `MuteList` (
`AgentID` char(36) NOT NULL,
`MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
`MuteName` varchar(64) NOT NULL DEFAULT '',
`MuteType` int(11) NOT NULL DEFAULT '1',
`MuteFlags` int(11) NOT NULL DEFAULT '0',
`Stamp` int(11) NOT NULL,
UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`),
KEY `AgentID` (`AgentID`)
);
COMMIT;

View File

@ -461,3 +461,9 @@ BEGIN;
ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL;
COMMIT; COMMIT;
:VERSION 57 #----- Add physics inertia data
BEGIN;
ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL;
COMMIT;

View File

@ -18,7 +18,7 @@ CREATE TABLE `os_groups_groups` (
PRIMARY KEY (`GroupID`), PRIMARY KEY (`GroupID`),
UNIQUE KEY `Name` (`Name`), UNIQUE KEY `Name` (`Name`),
FULLTEXT KEY `Name_2` (`Name`) FULLTEXT KEY `Name_2` (`Name`)
) ENGINE=InnoDB; ) ENGINE=MyISAM;
CREATE TABLE `os_groups_membership` ( CREATE TABLE `os_groups_membership` (

View File

@ -0,0 +1,316 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Data;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using log4net;
using OpenMetaverse;
using Npgsql;
using NpgsqlTypes;
namespace OpenSim.Data.PGSQL
{
public class PGSQLFSAssetData : IFSAssetDataPlugin
{
private const string _migrationStore = "FSAssetStore";
private static string m_Table = "fsassets";
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private long m_ticksToEpoch;
private PGSQLManager m_database;
private string m_connectionString;
public PGSQLFSAssetData()
{
}
public void Initialise(string connect, string realm, int UpdateAccessTime)
{
DaysBetweenAccessTimeUpdates = UpdateAccessTime;
m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
m_connectionString = connect;
m_database = new PGSQLManager(m_connectionString);
//New migration to check for DB changes
m_database.CheckMigration(_migrationStore);
}
public void Initialise()
{
throw new NotImplementedException();
}
/// <summary>
/// Number of days that must pass before we update the access time on an asset when it has been fetched
/// Config option to change this is "DaysBetweenAccessTimeUpdates"
/// </summary>
private int DaysBetweenAccessTimeUpdates = 0;
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
#region IPlugin Members
public string Version { get { return "1.0.0.0"; } }
public void Dispose() { }
public string Name
{
get { return "PGSQL FSAsset storage engine"; }
}
#endregion
#region IFSAssetDataPlugin Members
public AssetMetadata Get(string id, out string hash)
{
hash = String.Empty;
AssetMetadata meta = null;
UUID uuid = new UUID(id);
string query = String.Format("select \"id\", \"type\", \"hash\", \"create_time\", \"access_time\", \"asset_flags\" from {0} where \"id\" = :id", m_Table);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
cmd.Parameters.Add(m_database.CreateParameter("id", uuid));
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
{
if (reader.Read())
{
meta = new AssetMetadata();
hash = reader["hash"].ToString();
meta.ID = id;
meta.FullID = uuid;
meta.Name = String.Empty;
meta.Description = String.Empty;
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"]);
int atime = Convert.ToInt32(reader["access_time"]);
UpdateAccessTime(atime, uuid);
}
}
}
return meta;
}
private void UpdateAccessTime(int AccessTime, UUID id)
{
// 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;
string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
cmd.Parameters.Add(m_database.CreateParameter("id", id));
cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
cmd.ExecuteNonQuery();
}
}
public bool Store(AssetMetadata meta, string hash)
{
try
{
bool found = false;
string oldhash;
AssetMetadata existingAsset = Get(meta.ID, out oldhash);
string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
if (existingAsset == null)
{
query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table);
found = true;
}
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID));
cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type));
cmd.Parameters.Add(m_database.CreateParameter("hash", hash));
cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags)));
cmd.Parameters.Add(m_database.CreateParameter("create_time", now));
cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
cmd.ExecuteNonQuery();
}
return found;
}
catch(Exception e)
{
m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID);
m_log.Error(e.ToString());
return false;
}
}
/// <summary>
/// Check if the assets exist in the database.
/// </summary>
/// <param name="uuids">The asset UUID's</param>
/// <returns>For each asset: true if it exists, false otherwise</returns>
public bool[] AssetsExist(UUID[] uuids)
{
if (uuids.Length == 0)
return new bool[0];
HashSet<UUID> exists = new HashSet<UUID>();
string ids = "'" + string.Join("','", uuids) + "'";
string query = string.Format("select \"id\" from {1} where id in ({0})", ids, m_Table);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
{
while (reader.Read())
{
UUID id = DBGuid.FromDB(reader["id"]);;
exists.Add(id);
}
}
}
bool[] results = new bool[uuids.Length];
for (int i = 0; i < uuids.Length; i++)
results[i] = exists.Contains(uuids[i]);
return results;
}
public int Count()
{
int count = 0;
string query = String.Format("select count(*) as count from {0}", m_Table);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
IDataReader reader = cmd.ExecuteReader();
reader.Read();
count = Convert.ToInt32(reader["count"]);
reader.Close();
}
return count;
}
public bool Delete(string id)
{
string query = String.Format("delete from {0} where \"id\" = :id", m_Table);
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{
dbcon.Open();
cmd.Parameters.Add(m_database.CreateParameter("id", new UUID(id)));
cmd.ExecuteNonQuery();
}
return true;
}
public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
{
int imported = 0;
string limit = String.Empty;
if(count != -1)
{
limit = String.Format(" limit {0} offset {1}", start, count);
}
string query = String.Format("select * from {0}{1}", table, limit);
try
{
using (NpgsqlConnection remote = new NpgsqlConnection(conn))
using (NpgsqlCommand cmd = new NpgsqlCommand(query, remote))
{
remote.Open();
MainConsole.Instance.Output("Querying database");
MainConsole.Instance.Output("Reading data");
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
{
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 = String.Empty;
meta.Description = String.Empty;
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++;
}
}
}
}
catch (Exception e)
{
m_log.ErrorFormat("[PGSQL FSASSETS]: Error importing assets: {0}",
e.Message.ToString());
return;
}
MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
}
#endregion
}
}

View File

@ -435,7 +435,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand()) using (NpgsqlCommand cmd = new NpgsqlCommand())
{ {
cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm);
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }
@ -461,7 +461,7 @@ namespace OpenSim.Data.PGSQL
using (NpgsqlCommand cmd = new NpgsqlCommand()) using (NpgsqlCommand cmd = new NpgsqlCommand())
{ {
cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm);
ExecuteNonQuery(cmd); ExecuteNonQuery(cmd);
} }

View File

@ -350,10 +350,11 @@ namespace OpenSim.Data.PGSQL
""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX, ""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX,
""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook, ""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook,
""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice, ""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice,
""SaleType"" = :SaleType, ""ColorR"" = :ColorR, ""ColorG"" = :ColorG, ""ColorB"" = :ColorB, ""ColorA"" = :ColorA, ""ParticleSystem"" = :ParticleSystem, ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution,
""PassCollisions"" = :PassCollisions, ""RotationAxisLocks"" = :RotationAxisLocks, ""RezzerID"" = :RezzerID,
""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches, ""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches,
""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, ""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs,
""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution ""PhysInertia"" = :PhysInertia
WHERE ""UUID"" = :UUID ; WHERE ""UUID"" = :UUID ;
INSERT INTO INSERT INTO
@ -367,7 +368,7 @@ namespace OpenSim.Data.PGSQL
""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"", ""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"",
""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"",
""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"", ""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"",
""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"" ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""PhysInertia""
) Select ) Select
:UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask,
:EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX,
@ -378,7 +379,7 @@ namespace OpenSim.Data.PGSQL
:OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ, :OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ,
:ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA, :ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA,
:ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs, :ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs,
:PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :PhysInertia
where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID); where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID);
"; ";
@ -1678,6 +1679,12 @@ namespace OpenSim.Data.PGSQL
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
prim.GroupID = new UUID((Guid)primRow["GroupID"]); prim.GroupID = new UUID((Guid)primRow["GroupID"]);
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
if (primRow["RezzerID"] != DBNull.Value)
prim.RezzerID = new UUID((Guid)primRow["RezzerID"]);
else
prim.RezzerID = UUID.Zero;
prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]);
prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]);
prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]);
@ -1782,6 +1789,7 @@ namespace OpenSim.Data.PGSQL
prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]);
prim.PassTouches = (bool)primRow["PassTouches"]; prim.PassTouches = (bool)primRow["PassTouches"];
prim.PassCollisions = (bool)primRow["PassCollisions"];
if (!(primRow["MediaURL"] is System.DBNull)) if (!(primRow["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)primRow["MediaURL"]; prim.MediaUrl = (string)primRow["MediaURL"];
@ -1796,6 +1804,13 @@ namespace OpenSim.Data.PGSQL
prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]); prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]);
prim.Friction = Convert.ToSingle(primRow["Friction"]); prim.Friction = Convert.ToSingle(primRow["Friction"]);
prim.Restitution = Convert.ToSingle(primRow["Restitution"]); prim.Restitution = Convert.ToSingle(primRow["Restitution"]);
prim.RotationAxisLocks = Convert.ToByte(primRow["RotationAxisLocks"]);
PhysicsInertiaData pdata = null;
if (!(primRow["PhysInertia"] is System.DBNull))
pdata = PhysicsInertiaData.FromXml2(primRow["PhysInertia"].ToString());
prim.PhysicsInertia = pdata;
return prim; return prim;
} }
@ -2097,6 +2112,7 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID));
parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID));
parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID));
parameters.Add(_Database.CreateParameter("RezzerID", prim.RezzerID));
parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask));
parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask));
parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask));
@ -2196,11 +2212,29 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound));
parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume));
parameters.Add(_Database.CreateParameter("PassTouches", prim.PassTouches)); parameters.Add(_Database.CreateParameter("PassTouches", (bool)prim.PassTouches));
parameters.Add(_Database.CreateParameter("PassCollisions", (bool)prim.PassCollisions));
if (prim.PassTouches)
parameters.Add(_Database.CreateParameter("PassTouches", true));
else
parameters.Add(_Database.CreateParameter("PassTouches", false));
if (prim.PassCollisions)
parameters.Add(_Database.CreateParameter("PassCollisions", true));
else
parameters.Add(_Database.CreateParameter("PassCollisions", false));
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
if (prim.PhysicsInertia != null)
parameters.Add(_Database.CreateParameter("PhysInertia", prim.PhysicsInertia.ToXml2()));
else
parameters.Add(_Database.CreateParameter("PhysInertia", String.Empty));
if (prim.DynAttrs.CountNamespaces > 0) if (prim.DynAttrs.CountNamespaces > 0)
parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
else else
@ -2211,12 +2245,13 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier)); parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier));
parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction)); parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction));
parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution)); parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution));
parameters.Add(_Database.CreateParameter("RotationAxisLocks", prim.RotationAxisLocks));
return parameters.ToArray(); return parameters.ToArray();
} }
/// <summary> /// <summary>
/// Creates the primshape parameters for stroing in DB. /// Creates the primshape parameters for storing in DB.
/// </summary> /// </summary>
/// <param name="prim">Basic data of SceneObjectpart prim.</param> /// <param name="prim">Basic data of SceneObjectpart prim.</param>
/// <param name="sceneGroupID">The scene group ID.</param> /// <param name="sceneGroupID">The scene group ID.</param>

View File

@ -845,7 +845,7 @@ namespace OpenSim.Data.PGSQL
query = "SELECT \"profileImage\", \"profileFirstImage\" FROM \"userprofile\" WHERE \"useruuid\" = :Id"; query = "SELECT \"profileImage\", \"profileFirstImage\" FROM \"userprofile\" WHERE \"useruuid\" = :Id";
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format(query, "\"userpicks\""), dbcon)) using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{ {
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId)); cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));

View File

@ -173,13 +173,15 @@ namespace OpenSim.Data.PGSQL
if (m_enableCompression) if (m_enableCompression)
{ {
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) using(MemoryStream ms = new MemoryStream(asset.Data))
using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress))
{ {
MemoryStream outputStream = new MemoryStream(); using(MemoryStream outputStream = new MemoryStream())
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); {
decompressionStream.CopyTo(outputStream,int.MaxValue);
// int compressedLength = asset.Data.Length; // int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray(); asset.Data = outputStream.ToArray();
}
// m_log.DebugFormat( // m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength); // asset.ID, asset.Name, asset.Data.Length, compressedLength);

View File

@ -206,7 +206,7 @@ namespace OpenSim.Data.PGSQL
cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions""
from inventoryitems from inventoryitems
where ""avatarID""::uuid = :PrincipalID where ""avatarID""::uuid = :PrincipalID
and ""assetID"" = :AssetID and ""assetID""::uuid = :AssetID
group by ""assetID"" "); group by ""assetID"" ");
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID)); cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID));

View File

@ -0,0 +1,19 @@
:VERSION 1
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "public"."agentprefs" (
"PrincipalID" uuid NOT NULL,
"AccessPrefs" char(2) NOT NULL DEFAULT 'M'::bpchar COLLATE "default",
"HoverHeight" float8 NOT NULL DEFAULT 0,
"Language" char(5) NOT NULL DEFAULT 'en-us'::bpchar COLLATE "default",
"LanguageIsPublic" bool NOT NULL DEFAULT true,
"PermEveryone" int4 NOT NULL DEFAULT 0,
"PermGroup" int4 NOT NULL DEFAULT 0,
"PermNextOwner" int4 NOT NULL DEFAULT 532480
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."agentprefs" ADD PRIMARY KEY ("PrincipalID") NOT DEFERRABLE INITIALLY IMMEDIATE;
COMMIT;

View File

@ -1,307 +1,127 @@
:VERSION 1 :VERSION 12
BEGIN TRANSACTION; BEGIN TRANSACTION;
CREATE TABLE estate_managers( -- ----------------------------
"EstateID" int NOT NULL Primary Key, -- Table structure for estate_groups
uuid varchar(36) NOT NULL -- ----------------------------
); CREATE TABLE IF NOT EXISTS "public"."estate_groups" (
"EstateID" int4 NOT NULL,
CREATE TABLE estate_groups( "uuid" uuid NOT NULL
"EstateID" int NOT NULL, )
uuid varchar(36) NOT NULL WITH (OIDS=FALSE);
);
-- Indexes structure for table estate_groups
-- ----------------------------
CREATE TABLE estate_users( CREATE INDEX IF NOT EXISTS "ix_estate_groups" ON "public"."estate_groups" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST);
"EstateID" int NOT NULL,
uuid varchar(36) NOT NULL -- ----------------------------
); -- Table structure for estate_managers
-- ----------------------------
CREATE TABLE IF NOT EXISTS "public"."estate_managers" (
CREATE TABLE estateban( "EstateID" int4 NOT NULL,
"EstateID" int NOT NULL, "uuid" uuid NOT NULL
"bannedUUID" varchar(36) NOT NULL, )
"bannedIp" varchar(16) NOT NULL, WITH (OIDS=FALSE);
"bannedIpHostMask" varchar(16) NOT NULL,
"bannedNameMask" varchar(64) NULL DEFAULT NULL -- Indexes structure for table estate_managers
); -- ----------------------------
CREATE INDEX IF NOT EXISTS "ix_estate_managers" ON "public"."estate_managers" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST);
Create Sequence estate_settings_id increment by 100 start with 100;
-- ----------------------------
CREATE TABLE estate_settings( -- Table structure for estate_map
"EstateID" integer DEFAULT nextval('estate_settings_id') NOT NULL, -- ----------------------------
"EstateName" varchar(64) NULL DEFAULT (NULL), CREATE TABLE IF NOT EXISTS "public"."estate_map" (
"AbuseEmailToEstateOwner" boolean NOT NULL, "RegionID" uuid NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'::uuid,
"DenyAnonymous" boolean NOT NULL, "EstateID" int4 NOT NULL
"ResetHomeOnTeleport" boolean NOT NULL, )
"FixedSun" boolean NOT NULL, WITH (OIDS=FALSE);
"DenyTransacted" boolean NOT NULL,
"BlockDwell" boolean NOT NULL, -- Primary key structure for table estate_map
"DenyIdentified" boolean NOT NULL, -- ----------------------------
"AllowVoice" boolean NOT NULL, ALTER TABLE "public"."estate_map" ADD PRIMARY KEY ("RegionID") NOT DEFERRABLE INITIALLY IMMEDIATE;
"UseGlobalTime" boolean NOT NULL,
"PricePerMeter" int NOT NULL, -- ----------------------------
"TaxFree" boolean NOT NULL, -- Table structure for estate_settings
"AllowDirectTeleport" boolean NOT NULL, -- ----------------------------
"RedirectGridX" int NOT NULL, CREATE TABLE IF NOT EXISTS "public"."estate_settings" (
"RedirectGridY" int NOT NULL, "EstateID" int4 NOT NULL DEFAULT nextval('estate_settings_id'::regclass),
"ParentEstateID" int NOT NULL, "EstateName" varchar(64) DEFAULT NULL::character varying COLLATE "default",
"SunPosition" double precision NOT NULL, "AbuseEmailToEstateOwner" bool NOT NULL,
"EstateSkipScripts" boolean NOT NULL, "DenyAnonymous" bool NOT NULL,
"BillableFactor" double precision NOT NULL, "ResetHomeOnTeleport" bool NOT NULL,
"PublicAccess" boolean NOT NULL, "FixedSun" bool NOT NULL,
"AbuseEmail" varchar(255) NOT NULL, "DenyTransacted" bool NOT NULL,
"EstateOwner" varchar(36) NOT NULL, "BlockDwell" bool NOT NULL,
"DenyMinors" boolean NOT NULL "DenyIdentified" bool NOT NULL,
); "AllowVoice" bool NOT NULL,
"UseGlobalTime" bool NOT NULL,
"PricePerMeter" int4 NOT NULL,
CREATE TABLE estate_map( "TaxFree" bool NOT NULL,
"RegionID" varchar(36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), "AllowDirectTeleport" bool NOT NULL,
"EstateID" int NOT NULL "RedirectGridX" int4 NOT NULL,
); "RedirectGridY" int4 NOT NULL,
"ParentEstateID" int4 NOT NULL,
COMMIT; "SunPosition" float8 NOT NULL,
"EstateSkipScripts" bool NOT NULL,
:VERSION 2 "BillableFactor" float8 NOT NULL,
"PublicAccess" bool NOT NULL,
BEGIN TRANSACTION; "AbuseEmail" varchar(255) NOT NULL COLLATE "default",
CREATE INDEX IX_estate_managers ON estate_managers
(
"EstateID"
);
CREATE INDEX IX_estate_groups ON estate_groups
(
"EstateID"
);
CREATE INDEX IX_estate_users ON estate_users
(
"EstateID"
);
COMMIT;
:VERSION 3
BEGIN TRANSACTION;
CREATE TABLE Tmp_estateban
(
"EstateID" int NOT NULL,
"bannedUUID" varchar(36) NOT NULL,
"bannedIp" varchar(16) NULL,
"bannedIpHostMask" varchar(16) NULL,
"bannedNameMask" varchar(64) NULL
);
INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask")
SELECT "EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban;
DROP TABLE estateban;
Alter table Tmp_estateban
rename to estateban;
CREATE INDEX IX_estateban ON estateban
(
"EstateID"
);
COMMIT;
:VERSION 4
BEGIN TRANSACTION;
CREATE TABLE Tmp_estate_managers
(
"EstateID" int NOT NULL,
uuid uuid NOT NULL
);
INSERT INTO Tmp_estate_managers ("EstateID", uuid)
SELECT "EstateID", cast(uuid as uuid) FROM estate_managers;
DROP TABLE estate_managers;
Alter table Tmp_estate_managers
rename to estate_managers;
CREATE INDEX IX_estate_managers ON estate_managers
(
"EstateID"
);
COMMIT;
:VERSION 5
BEGIN TRANSACTION;
CREATE TABLE Tmp_estate_groups
(
"EstateID" int NOT NULL,
uuid uuid NOT NULL
) ;
INSERT INTO Tmp_estate_groups ("EstateID", uuid)
SELECT "EstateID", cast(uuid as uuid) FROM estate_groups;
DROP TABLE estate_groups;
Alter table Tmp_estate_groups
rename to estate_groups;
CREATE INDEX IX_estate_groups ON estate_groups
(
"EstateID"
);
COMMIT;
:VERSION 6
BEGIN TRANSACTION;
CREATE TABLE Tmp_estate_users
(
"EstateID" int NOT NULL,
uuid uuid NOT NULL
);
INSERT INTO Tmp_estate_users ("EstateID", uuid)
SELECT "EstateID", cast(uuid as uuid) FROM estate_users ;
DROP TABLE estate_users;
Alter table Tmp_estate_users
rename to estate_users;
CREATE INDEX IX_estate_users ON estate_users
(
"EstateID"
);
COMMIT;
:VERSION 7
BEGIN TRANSACTION;
CREATE TABLE Tmp_estateban
(
"EstateID" int NOT NULL,
"bannedUUID" uuid NOT NULL,
"bannedIp" varchar(16) NULL,
"bannedIpHostMask" varchar(16) NULL,
"bannedNameMask" varchar(64) NULL
);
INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask")
SELECT "EstateID", cast("bannedUUID" as uuid), "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban ;
DROP TABLE estateban;
Alter table Tmp_estateban
rename to estateban;
CREATE INDEX IX_estateban ON estateban
(
"EstateID"
);
COMMIT;
:VERSION 8
BEGIN TRANSACTION;
CREATE TABLE Tmp_estate_settings
(
"EstateID" integer default nextval('estate_settings_id') NOT NULL,
"EstateName" varchar(64) NULL DEFAULT (NULL),
"AbuseEmailToEstateOwner" boolean NOT NULL,
"DenyAnonymous" boolean NOT NULL,
"ResetHomeOnTeleport" boolean NOT NULL,
"FixedSun" boolean NOT NULL,
"DenyTransacted" boolean NOT NULL,
"BlockDwell" boolean NOT NULL,
"DenyIdentified" boolean NOT NULL,
"AllowVoice" boolean NOT NULL,
"UseGlobalTime" boolean NOT NULL,
"PricePerMeter" int NOT NULL,
"TaxFree" boolean NOT NULL,
"AllowDirectTeleport" boolean NOT NULL,
"RedirectGridX" int NOT NULL,
"RedirectGridY" int NOT NULL,
"ParentEstateID" int NOT NULL,
"SunPosition" double precision NOT NULL,
"EstateSkipScripts" boolean NOT NULL,
"BillableFactor" double precision NOT NULL,
"PublicAccess" boolean NOT NULL,
"AbuseEmail" varchar(255) NOT NULL,
"EstateOwner" uuid NOT NULL, "EstateOwner" uuid NOT NULL,
"DenyMinors" boolean NOT NULL "DenyMinors" bool NOT NULL,
); "AllowLandmark" bool NOT NULL DEFAULT true,
"AllowParcelChanges" bool NOT NULL DEFAULT true,
"AllowSetHome" bool NOT NULL DEFAULT true
)
WITH (OIDS=FALSE);
INSERT INTO Tmp_estate_settings ("EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", "EstateOwner", "DenyMinors") -- Primary key structure for table estate_settings
SELECT "EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", cast("EstateOwner" as uuid), "DenyMinors" FROM estate_settings ; -- ----------------------------
ALTER TABLE "public"."estate_settings" ADD PRIMARY KEY ("EstateID") NOT DEFERRABLE INITIALLY IMMEDIATE;
DROP TABLE estate_settings; -- ----------------------------
-- Table structure for estate_users
-- ----------------------------
CREATE TABLE IF NOT EXISTS "public"."estate_users" (
"EstateID" int4 NOT NULL,
"uuid" uuid NOT NULL
)
WITH (OIDS=FALSE);
-- Indexes structure for table estate_users
-- ----------------------------
CREATE INDEX IF NOT EXISTS "ix_estate_users" ON "public"."estate_users" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST);
Alter table Tmp_estate_settings -- ----------------------------
rename to estate_settings; -- Table structure for estateban
-- ----------------------------
CREATE TABLE IF NOT EXISTS "public"."estateban" (
"EstateID" int4 NOT NULL,
"bannedUUID" uuid NOT NULL,
"bannedIp" varchar(16) COLLATE "default",
"bannedIpHostMask" varchar(16) COLLATE "default",
"bannedNameMask" varchar(64) COLLATE "default"
)
WITH (OIDS=FALSE);
-- Indexes structure for table estateban
Create index on estate_settings (lower("EstateName")); -- ----------------------------
CREATE INDEX IF NOT EXISTS "ix_estateban" ON "public"."estateban" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST);
COMMIT; COMMIT;
:VERSION 13
:VERSION 9 BEGIN TRASACTION;
BEGIN TRANSACTION; -- ----------------------------
-- SEQUENCE estate_settings_id
CREATE TABLE Tmp_estate_map -- ----------------------------
( CREATE SEQUENCE IF NOT EXISTS "public"."estate_settings_id"
"RegionID" uuid NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), INCREMENT 100
"EstateID" int NOT NULL MINVALUE 1
); MAXVALUE 9223372036854775807
START 100
INSERT INTO Tmp_estate_map ("RegionID", "EstateID") CACHE 1;
SELECT cast("RegionID" as uuid), "EstateID" FROM estate_map ;
DROP TABLE estate_map;
Alter table Tmp_estate_map
rename to estate_map;
COMMIT; COMMIT;
:VERSION 10
BEGIN TRANSACTION;
ALTER TABLE estate_settings ADD COLUMN "AllowLandmark" boolean NOT NULL default true;
ALTER TABLE estate_settings ADD COLUMN "AllowParcelChanges" boolean NOT NULL default true;
ALTER TABLE estate_settings ADD COLUMN "AllowSetHome" boolean NOT NULL default true;
COMMIT;
:VERSION 11
Begin transaction;
Commit;

View File

@ -0,0 +1,14 @@
:VERSION 1
BEGIN TRANSACTION;
CREATE TABLE fsassets (
"id" uuid NOT NULL PRIMARY KEY,
"type" integer NOT NULL,
"hash" char(64) NOT NULL,
"create_time" integer NOT NULL DEFAULT '0',
"access_time" integer NOT NULL DEFAULT '0',
"asset_flags" integer NOT NULL DEFAULT '0'
);
COMMIT;

View File

@ -1195,3 +1195,33 @@ CREATE TABLE bakedterrain
); );
COMMIT; COMMIT;
:VERSION 45 #---- Add RezzerID filed in table prims
BEGIN TRANSACTION;
ALTER TABLE prims ADD "RezzerID" uuid NULL;
COMMIT;
:VERSION 46 #---- Add physics inertia data to table prims
BEGIN TRANSACTION;
ALTER TABLE prims ADD "PhysInertia" TEXT;
COMMIT;
:VERSION 47 #---- Convert field PassCollisions in table prims to BOOLEAN
BEGIN TRANSACTION;
ALTER TABLE "public"."prims" ALTER COLUMN "PassCollisions" DROP DEFAULT;
ALTER TABLE "public"."prims"
ALTER COLUMN "PassCollisions" TYPE BOOLEAN
USING CASE WHEN "PassCollisions" = 0 THEN FALSE
WHEN "PassCollisions" = 1 THEN TRUE
ELSE NULL
END;
COMMIT;

View File

@ -0,0 +1,16 @@
:VERSION 1
BEGIN TRANSACTION;
CREATE TABLE MuteList (
AgentID char(36) NOT NULL,
MuteID char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
MuteName varchar(64) NOT NULL DEFAULT '',
MuteType int(11) NOT NULL DEFAULT '1',
MuteFlags int(11) NOT NULL DEFAULT '0',
Stamp int(11) NOT NULL,
UNIQUE (AgentID, MuteID, MuteName),
PRIMARY KEY(AgentID)
);
COMMIT;

View File

@ -371,3 +371,9 @@ BEGIN;
ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL;
COMMIT; COMMIT;
:VERSION 36 #----- Add physics inertia data
BEGIN;
ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL;
COMMIT;

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using OpenMetaverse;
using OpenSim.Framework;
#if CSharpSqlite
using Community.CsharpSqlite.Sqlite;
#else
using Mono.Data.Sqlite;
#endif
namespace OpenSim.Data.SQLite
{
public class SQLiteMuteListData : SQLiteGenericTableHandler<MuteData>, IMuteListData
{
public SQLiteMuteListData(string connectionString)
: base(connectionString, "MuteList", "MuteListStore")
{
}
public MuteData[] Get(UUID agentID)
{
MuteData[] data = base.Get("AgentID", agentID.ToString());
return data;
}
public bool Delete(UUID agentID, UUID muteID, string muteName)
{
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = "delete from MuteList where `AgentID` = :AgentID and `MuteID` = :MuteID and `MuteName` = :MuteName";
cmd.Parameters.AddWithValue(":AgentID", agentID.ToString());
cmd.Parameters.AddWithValue(":MuteID", muteID.ToString());
cmd.Parameters.AddWithValue(":MuteName", muteName);
if (ExecuteNonQuery(cmd, m_Connection) > 0)
return true;
return false;
}
}
}
}

View File

@ -1843,6 +1843,12 @@ namespace OpenSim.Data.SQLite
if (vehicle != null) if (vehicle != null)
prim.VehicleParams = vehicle; prim.VehicleParams = vehicle;
} }
PhysicsInertiaData pdata = null;
if (!(row["PhysInertia"] is DBNull) && row["PhysInertia"].ToString() != String.Empty)
pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString());
prim.PhysicsInertia = pdata;
return prim; return prim;
} }
@ -2266,6 +2272,11 @@ namespace OpenSim.Data.SQLite
else else
row["Vehicle"] = String.Empty; row["Vehicle"] = String.Empty;
if (prim.PhysicsInertia != null)
row["PhysInertia"] = prim.PhysicsInertia.ToXml2();
else
row["PhysInertia"] = String.Empty;
} }
/// <summary> /// <summary>

View File

@ -926,7 +926,7 @@ namespace OpenSim.Data.SQLite
{ {
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{ {
cmd.CommandText = query; cmd.CommandText = string.Format(query, "\"classifieds\"");
cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); cmd.Parameters.AddWithValue(":Id", avatarId.ToString());
using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
@ -940,7 +940,7 @@ namespace OpenSim.Data.SQLite
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{ {
cmd.CommandText = query; cmd.CommandText = string.Format(query, "\"userpicks\"");
cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); cmd.Parameters.AddWithValue(":Id", avatarId.ToString());
using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow))

View File

@ -305,18 +305,12 @@ namespace OpenSim.Data.SQLite
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID";
cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
try if(ExecuteNonQuery(cmd, m_Connection) == 0)
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false; return false;
} }
}
return true; return true;
} }

View File

@ -83,6 +83,7 @@ namespace OpenSim.Framework
public bool UseClientAgentPosition; public bool UseClientAgentPosition;
public bool NeedsCameraCollision; public bool NeedsCameraCollision;
public uint lastpacketSequence; public uint lastpacketSequence;
public double lastUpdateTS;
public AgentUpdateArgs() public AgentUpdateArgs()
{ {

View File

@ -31,7 +31,8 @@ using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public delegate bool AnimationSetValidator(UUID animID); // public delegate bool AnimationSetValidator(UUID animID);
public delegate uint AnimationSetValidator(UUID animID);
public class AnimationSet public class AnimationSet
{ {
@ -141,7 +142,7 @@ namespace OpenSim.Framework
assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
return System.Text.Encoding.ASCII.GetBytes(assetData); return System.Text.Encoding.ASCII.GetBytes(assetData);
} }
/*
public bool Validate(AnimationSetValidator val) public bool Validate(AnimationSetValidator val)
{ {
if (m_parseError) if (m_parseError)
@ -164,5 +165,22 @@ namespace OpenSim.Framework
return allOk; return allOk;
} }
*/
public uint Validate(AnimationSetValidator val)
{
if (m_parseError)
return 0;
uint ret = 0x7fffffff;
uint t;
foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
{
t = val(kvp.Value.Value);
if (t == 0)
return 0;
ret &= t;
}
return ret;
}
} }
} }

View File

@ -42,11 +42,13 @@ namespace OpenSim.Framework.AssetLoader.Filesystem
public class AssetLoaderFileSystem : IAssetLoader public class AssetLoaderFileSystem : IAssetLoader
{ {
private static readonly UUID LIBRARY_OWNER_ID = new UUID("11111111-1111-0000-0000-000100bba000"); private static readonly UUID LIBRARY_OWNER_ID = new UUID("11111111-1111-0000-0000-000100bba000");
private static readonly string LIBRARY_OWNER_IDstr = "11111111-1111-0000-0000-000100bba000";
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected static AssetBase CreateAsset(string assetIdStr, string name, string path, sbyte type) protected static AssetBase CreateAsset(string assetIdStr, string name, string path, sbyte type)
{ {
AssetBase asset = new AssetBase(new UUID(assetIdStr), name, type, LIBRARY_OWNER_ID.ToString()); AssetBase asset = new AssetBase(new UUID(assetIdStr), name, type, LIBRARY_OWNER_IDstr);
if (!String.IsNullOrEmpty(path)) if (!String.IsNullOrEmpty(path))
{ {

View File

@ -91,11 +91,11 @@ namespace OpenSim.Framework
public static readonly UUID DEFAULT_PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111"); public static readonly UUID DEFAULT_PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111");
public static readonly UUID DEFAULT_PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120"); public static readonly UUID DEFAULT_PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120");
// public static readonly UUID DEFAULT_ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8"); public static readonly UUID DEFAULT_ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8");
// public static readonly UUID DEFAULT_ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594"); public static readonly UUID DEFAULT_ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594");
// public static readonly UUID DEFAULT_TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); public static readonly UUID DEFAULT_TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1");
// public static readonly UUID DEFAULT_TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); public static readonly UUID DEFAULT_TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007");
protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>(); protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>();
protected List<UUID> m_ids = new List<UUID>(); protected List<UUID> m_ids = new List<UUID>();

View File

@ -1,148 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Threading;
namespace OpenSim.Framework
{
public class BlockingQueue<T>
{
private readonly Queue<T> m_pqueue = new Queue<T>();
private readonly Queue<T> m_queue = new Queue<T>();
private readonly object m_queueSync = new object();
public void PriorityEnqueue(T value)
{
lock (m_queueSync)
{
m_pqueue.Enqueue(value);
Monitor.Pulse(m_queueSync);
}
}
public void Enqueue(T value)
{
lock (m_queueSync)
{
m_queue.Enqueue(value);
Monitor.Pulse(m_queueSync);
}
}
public T Dequeue()
{
lock (m_queueSync)
{
while (m_queue.Count < 1 && m_pqueue.Count < 1)
{
Monitor.Wait(m_queueSync);
}
if (m_pqueue.Count > 0)
return m_pqueue.Dequeue();
if (m_queue.Count > 0)
return m_queue.Dequeue();
return default(T);
}
}
public T Dequeue(int msTimeout)
{
lock (m_queueSync)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
{
if(!Monitor.Wait(m_queueSync, msTimeout))
return default(T);
}
if (m_pqueue.Count > 0)
return m_pqueue.Dequeue();
if (m_queue.Count > 0)
return m_queue.Dequeue();
return default(T);
}
}
/// <summary>
/// Indicate whether this queue contains the given item.
/// </summary>
/// <remarks>
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
/// </remarks>
public bool Contains(T item)
{
lock (m_queueSync)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return false;
if (m_pqueue.Contains(item))
return true;
return m_queue.Contains(item);
}
}
/// <summary>
/// Return a count of the number of requests on this queue.
/// </summary>
public int Count()
{
lock (m_queueSync)
return m_queue.Count + m_pqueue.Count;
}
/// <summary>
/// Return the array of items on this queue.
/// </summary>
/// <remarks>
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
/// </remarks>
public T[] GetQueueArray()
{
lock (m_queueSync)
{
if (m_queue.Count < 1 && m_pqueue.Count < 1)
return new T[0];
return m_queue.ToArray();
}
}
public void Clear()
{
lock (m_queueSync)
{
m_pqueue.Clear();
m_queue.Clear();
Monitor.Pulse(m_queueSync);
}
}
}
}

View File

@ -390,9 +390,10 @@ namespace OpenSim.Framework
Object data = fetch(index); Object data = fetch(index);
if (data == null && (m_Flags & CacheFlags.CacheMissing) == 0) if (data == null)
return null; {
if((m_Flags & CacheFlags.CacheMissing) != 0)
{
lock (m_Index) lock (m_Index)
{ {
CacheItemBase missing = new CacheItemBase(index); CacheItemBase missing = new CacheItemBase(index);
@ -402,6 +403,9 @@ namespace OpenSim.Framework
m_Lookup[index] = missing; m_Lookup[index] = missing;
} }
} }
}
return null;
}
Store(index, data); Store(index, data);
return data; return data;

View File

@ -375,6 +375,7 @@ namespace OpenSim.Framework
public string ActiveGroupTitle = null; public string ActiveGroupTitle = null;
public UUID agentCOF; public UUID agentCOF;
public byte CrossingFlags; public byte CrossingFlags;
public byte CrossExtraFlags;
public Dictionary<ulong, string> ChildrenCapSeeds = null; public Dictionary<ulong, string> ChildrenCapSeeds = null;
public Animation[] Anims; public Animation[] Anims;
@ -454,6 +455,8 @@ namespace OpenSim.Framework
args["agent_cof"] = OSD.FromUUID(agentCOF); args["agent_cof"] = OSD.FromUUID(agentCOF);
args["crossingflags"] = OSD.FromInteger(CrossingFlags); args["crossingflags"] = OSD.FromInteger(CrossingFlags);
if(CrossingFlags != 0)
args["crossExtraFlags"] = OSD.FromInteger(CrossExtraFlags);
args["active_group_id"] = OSD.FromUUID(ActiveGroupID); args["active_group_id"] = OSD.FromUUID(ActiveGroupID);
args["active_group_name"] = OSD.FromString(ActiveGroupName); args["active_group_name"] = OSD.FromString(ActiveGroupName);
@ -646,6 +649,12 @@ namespace OpenSim.Framework
if (args.ContainsKey("crossingflags") && args["crossingflags"] != null) if (args.ContainsKey("crossingflags") && args["crossingflags"] != null)
CrossingFlags = (byte)args["crossingflags"].AsInteger(); CrossingFlags = (byte)args["crossingflags"].AsInteger();
if(CrossingFlags != 0)
{
if (args.ContainsKey("crossExtraFlags") && args["crossExtraFlags"] != null)
CrossExtraFlags = (byte)args["crossExtraFlags"].AsInteger();
}
if (args.ContainsKey("active_group_id") && args["active_group_id"] != null) if (args.ContainsKey("active_group_id") && args["active_group_id"] != null)
ActiveGroupID = args["active_group_id"].AsUUID(); ActiveGroupID = args["active_group_id"].AsUUID();

View File

@ -34,6 +34,6 @@ namespace OpenSim.Framework.Client
{ {
public interface IClientIPEndpoint public interface IClientIPEndpoint
{ {
IPAddress EndPoint { get; } IPEndPoint RemoteEndPoint { get; }
} }
} }

View File

@ -36,14 +36,8 @@ namespace OpenSim.Framework
public readonly DateTime StartedTime = DateTime.Now; public readonly DateTime StartedTime = DateTime.Now;
public AgentCircuitData agentcircuit = null; public AgentCircuitData agentcircuit = null;
public Dictionary<uint, byte[]> needAck;
public List<byte[]> out_packets = new List<byte[]>();
public Dictionary<uint, uint> pendingAcks = new Dictionary<uint,uint>();
public EndPoint proxyEP; public EndPoint proxyEP;
public uint sequence;
public byte[] usecircuit;
public EndPoint userEP; public EndPoint userEP;
public int resendThrottle; public int resendThrottle;
@ -59,9 +53,5 @@ namespace OpenSim.Framework
public int targetThrottle; public int targetThrottle;
public int maxThrottle; public int maxThrottle;
public Dictionary<string, int> SyncRequests = new Dictionary<string,int>();
public Dictionary<string, int> AsyncRequests = new Dictionary<string,int>();
public Dictionary<string, int> GenericRequests = new Dictionary<string,int>();
} }
} }

View File

@ -27,10 +27,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Net; using System.Net;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
@ -76,20 +74,16 @@ namespace OpenSim.Framework
{ {
lock (m_syncRoot) lock (m_syncRoot)
{ {
if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) // allow self healing
return false; // if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint))
// return false;
m_dict1[value.AgentId] = value; m_dict1[value.AgentId] = value;
m_dict2[value.RemoteEndPoint] = value; m_dict2[value.RemoteEndPoint] = value;
IClientAPI[] oldArray = m_array; // dict1 is the master
int oldLength = oldArray.Length; IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
m_dict1.Values.CopyTo(newArray, 0);
IClientAPI[] newArray = new IClientAPI[oldLength + 1];
for (int i = 0; i < oldLength; i++)
newArray[i] = oldArray[i];
newArray[oldLength] = value;
m_array = newArray; m_array = newArray;
} }
@ -112,22 +106,12 @@ namespace OpenSim.Framework
m_dict1.Remove(key); m_dict1.Remove(key);
m_dict2.Remove(value.RemoteEndPoint); m_dict2.Remove(value.RemoteEndPoint);
IClientAPI[] oldArray = m_array; IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
int oldLength = oldArray.Length; m_dict1.Values.CopyTo(newArray, 0);
IClientAPI[] newArray = new IClientAPI[oldLength - 1];
int j = 0;
for (int i = 0; i < oldLength; i++)
{
if (oldArray[i] != value)
newArray[j++] = oldArray[i];
}
m_array = newArray; m_array = newArray;
return true; return true;
} }
} }
return false; return false;
} }
@ -196,26 +180,12 @@ namespace OpenSim.Framework
} }
} }
/// <summary>
/// Performs a given task in parallel for each of the elements in the
/// collection
/// </summary>
/// <param name="action">Action to perform on each element</param>
public void ForEach(Action<IClientAPI> action)
{
IClientAPI[] localArray = m_array;
Parallel.For(0, localArray.Length,
delegate(int i)
{ action(localArray[i]); }
);
}
/// <summary> /// <summary>
/// Performs a given task synchronously for each of the elements in /// Performs a given task synchronously for each of the elements in
/// the collection /// the collection
/// </summary> /// </summary>
/// <param name="action">Action to perform on each element</param> /// <param name="action">Action to perform on each element</param>
public void ForEachSync(Action<IClientAPI> action) public void ForEach(Action<IClientAPI> action)
{ {
IClientAPI[] localArray = m_array; IClientAPI[] localArray = m_array;
for (int i = 0; i < localArray.Length; i++) for (int i = 0; i < localArray.Length; i++)

View File

@ -46,6 +46,7 @@ namespace OpenSim.Framework.Console
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_historyPath; private string m_historyPath;
private bool m_historyEnable; private bool m_historyEnable;
private bool m_historytimestamps;
// private readonly object m_syncRoot = new object(); // private readonly object m_syncRoot = new object();
private const string LOGLEVEL_NONE = "(none)"; private const string LOGLEVEL_NONE = "(none)";
@ -98,15 +99,30 @@ namespace OpenSim.Framework.Console
string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt"); string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt");
int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100); int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100);
m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile)); m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile));
m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath); m_historytimestamps = startupConfig.GetBoolean("ConsoleHistoryTimeStamp", false);
m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1} {2} timestamps",
m_historySize, m_historyPath, m_historytimestamps?"with":"without");
if (File.Exists(m_historyPath)) if (File.Exists(m_historyPath))
{ {
List<string> originallines = new List<string>();
using (StreamReader history_file = new StreamReader(m_historyPath)) using (StreamReader history_file = new StreamReader(m_historyPath))
{ {
string line; string line;
while ((line = history_file.ReadLine()) != null) while ((line = history_file.ReadLine()) != null)
{ {
originallines.Add(line);
if(line.StartsWith("["))
{
int indx = line.IndexOf("]:> ");
if(indx > 0)
{
if(indx + 4 >= line.Length)
line = String.Empty;
else
line = line.Substring(indx + 4);
}
}
m_history.Add(line); m_history.Add(line);
} }
} }
@ -114,11 +130,14 @@ namespace OpenSim.Framework.Console
if (m_history.Count > m_historySize) if (m_history.Count > m_historySize)
{ {
while (m_history.Count > m_historySize) while (m_history.Count > m_historySize)
{
m_history.RemoveAt(0); m_history.RemoveAt(0);
originallines.RemoveAt(0);
}
using (StreamWriter history_file = new StreamWriter(m_historyPath)) using (StreamWriter history_file = new StreamWriter(m_historyPath))
{ {
foreach (string line in m_history) foreach (string line in originallines)
{ {
history_file.WriteLine(line); history_file.WriteLine(line);
} }
@ -141,6 +160,8 @@ namespace OpenSim.Framework.Console
m_history.Add(text); m_history.Add(text);
if (m_historyEnable) if (m_historyEnable)
{ {
if (m_historytimestamps)
text = String.Format("[{0} {1}]:> {2}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), text);
File.AppendAllText(m_historyPath, text + Environment.NewLine); File.AppendAllText(m_historyPath, text + Environment.NewLine);
} }
} }

View File

@ -403,7 +403,7 @@ namespace OpenSim.Framework.Console
string uri = "/ReadResponses/" + sessionID.ToString() + "/"; string uri = "/ReadResponses/" + sessionID.ToString() + "/";
m_Server.AddPollServiceHTTPHandler( m_Server.AddPollServiceHTTPHandler(
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, null, sessionID,25000)); // 25 secs timeout
// Our reply is an XML document. // Our reply is an XML document.
// TODO: Change this to Linq.Xml // TODO: Change this to Linq.Xml
@ -687,7 +687,6 @@ namespace OpenSim.Framework.Console
result["int_response_code"] = 200; result["int_response_code"] = 200;
result["content_type"] = "application/xml"; result["content_type"] = "application/xml";
result["keepalive"] = false; result["keepalive"] = false;
result["reusecontext"] = false;
result = CheckOrigin(result); result = CheckOrigin(result);
return result; return result;
@ -713,7 +712,6 @@ namespace OpenSim.Framework.Console
result["int_response_code"] = 200; result["int_response_code"] = 200;
result["content_type"] = "text/xml"; result["content_type"] = "text/xml";
result["keepalive"] = false; result["keepalive"] = false;
result["reusecontext"] = false;
result = CheckOrigin(result); result = CheckOrigin(result);
return result; return result;

139
OpenSim/Framework/Crc32.cs Normal file
View File

@ -0,0 +1,139 @@
/*
* 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.Security.Cryptography;
namespace OpenSim.Framework
{
// this is more generic than openmetaverse CRC32
public class Crc32 : HashAlgorithm
{
public const UInt32 DefaultPolynomial = 0xedb88320;
public const UInt32 DefaultSeed = 0xffffffff;
private UInt32 hash;
private UInt32 seed;
private UInt32[] table;
private static UInt32[] defaultTable;
public Crc32()
{
table = InitializeTable(DefaultPolynomial);
seed = DefaultSeed;
Initialize();
}
public Crc32(UInt32 polynomial, UInt32 seed)
{
table = InitializeTable(polynomial);
this.seed = seed;
Initialize();
}
public override void Initialize()
{
hash = seed;
}
protected override void HashCore(byte[] buffer, int start, int length)
{
hash = CalculateHash(table, hash, buffer, start, length);
}
protected override byte[] HashFinal()
{
byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
this.HashValue = hashBuffer;
return hashBuffer;
}
public override int HashSize
{
get { return 32; }
}
public static UInt32 Compute(byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
}
private static UInt32[] InitializeTable(UInt32 polynomial)
{
if (polynomial == DefaultPolynomial && defaultTable != null)
return defaultTable;
UInt32[] createTable = new UInt32[256];
for (int i = 0; i < 256; i++)
{
UInt32 entry = (UInt32)i;
for (int j = 0; j < 8; j++)
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
createTable[i] = entry;
}
if (polynomial == DefaultPolynomial)
defaultTable = createTable;
return createTable;
}
private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
{
UInt32 crc = seed;
for (int i = start; i < size; i++)
unchecked
{
crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
}
return crc;
}
private byte[] UInt32ToBigEndianBytes(UInt32 x)
{
return new byte[] {
(byte)((x >> 24) & 0xff),
(byte)((x >> 16) & 0xff),
(byte)((x >> 8) & 0xff),
(byte)(x & 0xff) };
}
}
}

View File

@ -74,8 +74,6 @@ namespace OpenSim.Framework
{ {
rwLock.EnterWriteLock(); rwLock.EnterWriteLock();
gotLock = true; gotLock = true;
}
if (Dictionary1.ContainsKey(key1)) if (Dictionary1.ContainsKey(key1))
{ {
if (!Dictionary2.ContainsKey(key2)) if (!Dictionary2.ContainsKey(key2))
@ -86,10 +84,10 @@ namespace OpenSim.Framework
if (!Dictionary1.ContainsKey(key1)) if (!Dictionary1.ContainsKey(key1))
throw new ArgumentException("key2 exists in the dictionary but not key1"); throw new ArgumentException("key2 exists in the dictionary but not key1");
} }
Dictionary1[key1] = value; Dictionary1[key1] = value;
Dictionary2[key2] = value; Dictionary2[key2] = value;
} }
}
finally finally
{ {
if (gotLock) if (gotLock)
@ -112,11 +110,10 @@ namespace OpenSim.Framework
{ {
rwLock.EnterWriteLock(); rwLock.EnterWriteLock();
gotLock = true; gotLock = true;
}
Dictionary1.Remove(key1); Dictionary1.Remove(key1);
success = Dictionary2.Remove(key2); success = Dictionary2.Remove(key2);
} }
}
finally finally
{ {
if (gotLock) if (gotLock)
@ -150,9 +147,13 @@ namespace OpenSim.Framework
foreach (KeyValuePair<TKey2, TValue> kvp in Dictionary2) foreach (KeyValuePair<TKey2, TValue> kvp in Dictionary2)
{ {
if (kvp.Value.Equals(value)) if (kvp.Value.Equals(value))
{
try { }
finally
{ {
Dictionary1.Remove(key1); Dictionary1.Remove(key1);
Dictionary2.Remove(kvp.Key); Dictionary2.Remove(kvp.Key);
}
found = true; found = true;
break; break;
} }
@ -192,9 +193,13 @@ namespace OpenSim.Framework
foreach (KeyValuePair<TKey1, TValue> kvp in Dictionary1) foreach (KeyValuePair<TKey1, TValue> kvp in Dictionary1)
{ {
if (kvp.Value.Equals(value)) if (kvp.Value.Equals(value))
{
try { }
finally
{ {
Dictionary2.Remove(key2); Dictionary2.Remove(key2);
Dictionary1.Remove(kvp.Key); Dictionary1.Remove(kvp.Key);
}
found = true; found = true;
break; break;
} }
@ -224,11 +229,10 @@ namespace OpenSim.Framework
{ {
rwLock.EnterWriteLock(); rwLock.EnterWriteLock();
gotLock = true; gotLock = true;
}
Dictionary1.Clear(); Dictionary1.Clear();
Dictionary2.Clear(); Dictionary2.Clear();
} }
}
finally finally
{ {
if (gotLock) if (gotLock)
@ -485,9 +489,8 @@ namespace OpenSim.Framework
try {} try {}
finally finally
{ {
rwLock.EnterUpgradeableReadLock(); rwLock.EnterWriteLock();
gotWriteLock = true; gotWriteLock = true;
}
for (int i = 0; i < list.Count; i++) for (int i = 0; i < list.Count; i++)
Dictionary1.Remove(list[i]); Dictionary1.Remove(list[i]);
@ -495,6 +498,7 @@ namespace OpenSim.Framework
for (int i = 0; i < list2.Count; i++) for (int i = 0; i < list2.Count; i++)
Dictionary2.Remove(list2[i]); Dictionary2.Remove(list2[i]);
} }
}
finally finally
{ {
if (gotWriteLock) if (gotWriteLock)

View File

@ -44,7 +44,6 @@ namespace OpenSim.Framework
// Only the client uses these // Only the client uses these
// //
private uint m_EstateID = 0; private uint m_EstateID = 0;
public uint EstateID public uint EstateID
{ {
get { return m_EstateID; } get { return m_EstateID; }
@ -52,7 +51,6 @@ namespace OpenSim.Framework
} }
private string m_EstateName = "My Estate"; private string m_EstateName = "My Estate";
public string EstateName public string EstateName
{ {
get { return m_EstateName; } get { return m_EstateName; }
@ -60,7 +58,6 @@ namespace OpenSim.Framework
} }
private bool m_AllowLandmark = true; private bool m_AllowLandmark = true;
public bool AllowLandmark public bool AllowLandmark
{ {
get { return m_AllowLandmark; } get { return m_AllowLandmark; }
@ -68,7 +65,6 @@ namespace OpenSim.Framework
} }
private bool m_AllowParcelChanges = true; private bool m_AllowParcelChanges = true;
public bool AllowParcelChanges public bool AllowParcelChanges
{ {
get { return m_AllowParcelChanges; } get { return m_AllowParcelChanges; }
@ -76,7 +72,6 @@ namespace OpenSim.Framework
} }
private bool m_AllowSetHome = true; private bool m_AllowSetHome = true;
public bool AllowSetHome public bool AllowSetHome
{ {
get { return m_AllowSetHome; } get { return m_AllowSetHome; }
@ -84,7 +79,6 @@ namespace OpenSim.Framework
} }
private uint m_ParentEstateID = 1; private uint m_ParentEstateID = 1;
public uint ParentEstateID public uint ParentEstateID
{ {
get { return m_ParentEstateID; } get { return m_ParentEstateID; }
@ -92,7 +86,6 @@ namespace OpenSim.Framework
} }
private float m_BillableFactor = 0.0f; private float m_BillableFactor = 0.0f;
public float BillableFactor public float BillableFactor
{ {
get { return m_BillableFactor; } get { return m_BillableFactor; }
@ -100,7 +93,6 @@ namespace OpenSim.Framework
} }
private int m_PricePerMeter = 1; private int m_PricePerMeter = 1;
public int PricePerMeter public int PricePerMeter
{ {
get { return m_PricePerMeter; } get { return m_PricePerMeter; }
@ -108,7 +100,6 @@ namespace OpenSim.Framework
} }
private int m_RedirectGridX = 0; private int m_RedirectGridX = 0;
public int RedirectGridX public int RedirectGridX
{ {
get { return m_RedirectGridX; } get { return m_RedirectGridX; }
@ -116,7 +107,6 @@ namespace OpenSim.Framework
} }
private int m_RedirectGridY = 0; private int m_RedirectGridY = 0;
public int RedirectGridY public int RedirectGridY
{ {
get { return m_RedirectGridY; } get { return m_RedirectGridY; }
@ -126,7 +116,6 @@ namespace OpenSim.Framework
// Used by the sim // Used by the sim
// //
private bool m_UseGlobalTime = true; private bool m_UseGlobalTime = true;
public bool UseGlobalTime public bool UseGlobalTime
{ {
get { return m_UseGlobalTime; } get { return m_UseGlobalTime; }
@ -134,7 +123,6 @@ namespace OpenSim.Framework
} }
private bool m_FixedSun = false; private bool m_FixedSun = false;
public bool FixedSun public bool FixedSun
{ {
get { return m_FixedSun; } get { return m_FixedSun; }
@ -142,7 +130,6 @@ namespace OpenSim.Framework
} }
private double m_SunPosition = 0.0; private double m_SunPosition = 0.0;
public double SunPosition public double SunPosition
{ {
get { return m_SunPosition; } get { return m_SunPosition; }
@ -150,7 +137,6 @@ namespace OpenSim.Framework
} }
private bool m_AllowVoice = true; private bool m_AllowVoice = true;
public bool AllowVoice public bool AllowVoice
{ {
get { return m_AllowVoice; } get { return m_AllowVoice; }
@ -158,7 +144,6 @@ namespace OpenSim.Framework
} }
private bool m_AllowDirectTeleport = true; private bool m_AllowDirectTeleport = true;
public bool AllowDirectTeleport public bool AllowDirectTeleport
{ {
get { return m_AllowDirectTeleport; } get { return m_AllowDirectTeleport; }
@ -166,23 +151,22 @@ namespace OpenSim.Framework
} }
private bool m_DenyAnonymous = false; private bool m_DenyAnonymous = false;
public bool DenyAnonymous public bool DenyAnonymous
{ {
get { return m_DenyAnonymous; } get { return m_DenyAnonymous; }
set { m_DenyAnonymous = value; } set { m_DenyAnonymous = value; }
} }
// no longer in used, may be reassigned
private bool m_DenyIdentified = false; private bool m_DenyIdentified = false;
public bool DenyIdentified public bool DenyIdentified
{ {
get { return m_DenyIdentified; } get { return m_DenyIdentified; }
set { m_DenyIdentified = value; } set { m_DenyIdentified = value; }
} }
// no longer in used, may be reassigned
private bool m_DenyTransacted = false; private bool m_DenyTransacted = false;
public bool DenyTransacted public bool DenyTransacted
{ {
get { return m_DenyTransacted; } get { return m_DenyTransacted; }
@ -190,7 +174,6 @@ namespace OpenSim.Framework
} }
private bool m_AbuseEmailToEstateOwner = false; private bool m_AbuseEmailToEstateOwner = false;
public bool AbuseEmailToEstateOwner public bool AbuseEmailToEstateOwner
{ {
get { return m_AbuseEmailToEstateOwner; } get { return m_AbuseEmailToEstateOwner; }
@ -198,7 +181,6 @@ namespace OpenSim.Framework
} }
private bool m_BlockDwell = false; private bool m_BlockDwell = false;
public bool BlockDwell public bool BlockDwell
{ {
get { return m_BlockDwell; } get { return m_BlockDwell; }
@ -206,7 +188,6 @@ namespace OpenSim.Framework
} }
private bool m_EstateSkipScripts = false; private bool m_EstateSkipScripts = false;
public bool EstateSkipScripts public bool EstateSkipScripts
{ {
get { return m_EstateSkipScripts; } get { return m_EstateSkipScripts; }
@ -214,7 +195,6 @@ namespace OpenSim.Framework
} }
private bool m_ResetHomeOnTeleport = false; private bool m_ResetHomeOnTeleport = false;
public bool ResetHomeOnTeleport public bool ResetHomeOnTeleport
{ {
get { return m_ResetHomeOnTeleport; } get { return m_ResetHomeOnTeleport; }
@ -222,15 +202,13 @@ namespace OpenSim.Framework
} }
private bool m_TaxFree = false; private bool m_TaxFree = false;
public bool TaxFree // this is now AllowAccessOverride, keeping same name to reuse DB entries
public bool TaxFree
{ {
get { return m_TaxFree; } get { return m_TaxFree; }
set { m_TaxFree = value; } set { m_TaxFree = value; }
} }
private bool m_PublicAccess = true; private bool m_PublicAccess = true;
public bool PublicAccess public bool PublicAccess
{ {
get { return m_PublicAccess; } get { return m_PublicAccess; }
@ -246,7 +224,6 @@ namespace OpenSim.Framework
} }
private UUID m_EstateOwner = UUID.Zero; private UUID m_EstateOwner = UUID.Zero;
public UUID EstateOwner public UUID EstateOwner
{ {
get { return m_EstateOwner; } get { return m_EstateOwner; }
@ -254,7 +231,6 @@ namespace OpenSim.Framework
} }
private bool m_DenyMinors = false; private bool m_DenyMinors = false;
public bool DenyMinors public bool DenyMinors
{ {
get { return m_DenyMinors; } get { return m_DenyMinors; }
@ -280,7 +256,6 @@ namespace OpenSim.Framework
} }
private List<UUID> l_EstateAccess = new List<UUID>(); private List<UUID> l_EstateAccess = new List<UUID>();
public UUID[] EstateAccess public UUID[] EstateAccess
{ {
get { return l_EstateAccess.ToArray(); } get { return l_EstateAccess.ToArray(); }
@ -288,13 +263,15 @@ namespace OpenSim.Framework
} }
private List<UUID> l_EstateGroups = new List<UUID>(); private List<UUID> l_EstateGroups = new List<UUID>();
public UUID[] EstateGroups public UUID[] EstateGroups
{ {
get { return l_EstateGroups.ToArray(); } get { return l_EstateGroups.ToArray(); }
set { l_EstateGroups = new List<UUID>(value); } set { l_EstateGroups = new List<UUID>(value); }
} }
public bool DoDenyMinors = true;
public bool DoDenyAnonymous = true;
public EstateSettings() public EstateSettings()
{ {
} }
@ -402,14 +379,14 @@ namespace OpenSim.Framework
if (!HasAccess(avatarID)) if (!HasAccess(avatarID))
{ {
if (DenyMinors) if (DoDenyMinors && DenyMinors)
{ {
if ((userFlags & 32) == 0) if ((userFlags & 32) == 0)
{ {
return true; return true;
} }
} }
if (DenyAnonymous) if (DoDenyAnonymous && DenyAnonymous)
{ {
if ((userFlags & 4) == 0) if ((userFlags & 4) == 0)
{ {
@ -572,9 +549,35 @@ namespace OpenSim.Framework
// EstateBans are special // EstateBans are special
if (map.ContainsKey("EstateBans")) if (map.ContainsKey("EstateBans"))
{
if(map["EstateBans"] is string)
{
// JSON encoded bans map
Dictionary<string, EstateBan> bdata = new Dictionary<string, EstateBan>();
try
{
// bypass libovm, we dont need even more useless high level maps
// this should only be called once.. but no problem, i hope
// (other uses may need more..)
LitJson.JsonMapper.RegisterImporter<string, UUID>((input) => new UUID(input));
bdata = LitJson.JsonMapper.ToObject<Dictionary<string,EstateBan>>((string)map["EstateBans"]);
}
// catch(Exception e)
catch
{
return;
}
EstateBan[] jbans = new EstateBan[bdata.Count];
bdata.Values.CopyTo(jbans,0);
PropertyInfo jbansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance);
jbansProperty.SetValue(this, jbans, null);
}
else
{ {
var banData = ((Dictionary<string, object>)map["EstateBans"]).Values; var banData = ((Dictionary<string, object>)map["EstateBans"]).Values;
EstateBan[] bans = new EstateBan[banData.Count]; EstateBan[] bans = new EstateBan[banData.Count];
int b = 0; int b = 0;
foreach (Dictionary<string, object> ban in banData) foreach (Dictionary<string, object> ban in banData)
bans[b++] = new EstateBan(ban); bans[b++] = new EstateBan(ban);
@ -583,4 +586,5 @@ namespace OpenSim.Framework
} }
} }
} }
}
} }

View File

@ -443,7 +443,7 @@ namespace OpenSim.Framework
public delegate void DeclineCallingCard(IClientAPI remoteClient, UUID transactionID); public delegate void DeclineCallingCard(IClientAPI remoteClient, UUID transactionID);
public delegate void SoundTrigger( public delegate void SoundTrigger(
UUID soundId, UUID ownerid, UUID objid, UUID parentid, double Gain, Vector3 Position, UInt64 Handle, float radius); UUID soundId, UUID ownerid, UUID objid, UUID parentid, double Gain, Vector3 Position, UInt64 Handle);
public delegate void StartLure(byte lureType, string message, UUID targetID, IClientAPI client); public delegate void StartLure(byte lureType, string message, UUID targetID, IClientAPI client);
public delegate void TeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client); public delegate void TeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client);
@ -685,9 +685,10 @@ namespace OpenSim.Framework
ExtraData = 1 << 20, ExtraData = 1 << 20,
Sound = 1 << 21, Sound = 1 << 21,
Joint = 1 << 22, Joint = 1 << 22,
FullUpdate = 0x3fffffff, FullUpdate = 0x0fffffff,
CancelKill = 0x7fffffff, SendInTransit = 0x20000000,
Kill = 0x80000000 CancelKill = 0x4fffffff, // 1 << 30
Kill = 0x80000000 // 1 << 31
} }
/* included in .net 4.0 /* included in .net 4.0
@ -1187,7 +1188,8 @@ namespace OpenSim.Framework
void SetAgentThrottleSilent(int throttle, int setting); void SetAgentThrottleSilent(int throttle, int setting);
int GetAgentThrottleSilent(int throttle); int GetAgentThrottleSilent(int throttle);
void SendAvatarDataImmediate(ISceneEntity avatar); void SendEntityFullUpdateImmediate(ISceneEntity entity);
void SendEntityTerseUpdateImmediate(ISceneEntity entity);
/// <summary> /// <summary>
/// Send a positional, velocity, etc. update to the viewer for a given entity. /// Send a positional, velocity, etc. update to the viewer for a given entity.
@ -1483,7 +1485,7 @@ namespace OpenSim.Framework
void SendUserInfoReply(bool imViaEmail, bool visible, string email); void SendUserInfoReply(bool imViaEmail, bool visible, string email);
void SendUseCachedMuteList(); void SendUseCachedMuteList();
void SendEmpytMuteList();
void SendMuteListUpdate(string filename); void SendMuteListUpdate(string filename);
void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals); void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals);

View File

@ -33,6 +33,8 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
public interface ILandChannel public interface ILandChannel
{ {
float BanLineSafeHeight {get;}
/// <summary> /// <summary>
/// Get all parcels /// Get all parcels
/// </summary> /// </summary>
@ -76,6 +78,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns> /// <returns></returns>
ILandObject GetLandObject(int localID); ILandObject GetLandObject(int localID);
ILandObject GetLandObject(UUID GlobalID);
/// <summary> /// <summary>
/// Clear the land channel of all parcels. /// Clear the land channel of all parcels.
/// </summary> /// </summary>
@ -86,6 +90,7 @@ namespace OpenSim.Region.Framework.Interfaces
bool IsForcefulBansAllowed(); bool IsForcefulBansAllowed();
void UpdateLandObject(int localID, LandData data); void UpdateLandObject(int localID, LandData data);
void SendParcelsOverlay(IClientAPI client);
void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient); void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient);
void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
@ -94,6 +99,5 @@ namespace OpenSim.Region.Framework.Interfaces
void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void sendClientInitialLandInfo(IClientAPI remoteClient); void sendClientInitialLandInfo(IClientAPI remoteClient);
} }
} }

View File

@ -189,5 +189,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <returns>The music url.</returns> /// <returns>The music url.</returns>
string GetMusicUrl(); string GetMusicUrl();
void Clear();
} }
} }

View File

@ -41,6 +41,7 @@ namespace OpenSim.Framework
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = "");
void ApplyUploadCharge(UUID agentID, int amount, string text); void ApplyUploadCharge(UUID agentID, int amount, string text);
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text);
int UploadCharge { get; } int UploadCharge { get; }
int GroupCreationCharge { get; } int GroupCreationCharge { get; }

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Text;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
@ -415,5 +416,40 @@ namespace OpenSim.Framework
{ {
return MemberwiseClone(); return MemberwiseClone();
} }
public void ToLLSDxml(StringBuilder lsl)
{
LLSDxmlEncode.AddMap(lsl);
LLSDxmlEncode.AddElem("parent_id", Folder, lsl);
LLSDxmlEncode.AddElem("asset_id", AssetID, lsl);
LLSDxmlEncode.AddElem("item_id", ID, lsl);
LLSDxmlEncode.AddMap("permissions",lsl);
LLSDxmlEncode.AddElem("creator_id", CreatorIdAsUuid, lsl);
LLSDxmlEncode.AddElem("owner_id", Owner, lsl);
LLSDxmlEncode.AddElem("group_id", GroupID, lsl);
LLSDxmlEncode.AddElem("base_mask", (int)CurrentPermissions, lsl);
LLSDxmlEncode.AddElem("owner_mask", (int)CurrentPermissions, lsl);
LLSDxmlEncode.AddElem("group_mask", (int)GroupPermissions, lsl);
LLSDxmlEncode.AddElem("everyone_mask", (int)EveryOnePermissions, lsl);
LLSDxmlEncode.AddElem("next_owner_mask", (int)NextPermissions, lsl);
LLSDxmlEncode.AddElem("is_owner_group", GroupOwned, lsl);
LLSDxmlEncode.AddEndMap(lsl);
LLSDxmlEncode.AddElem("type", AssetType, lsl);
LLSDxmlEncode.AddElem("inv_type", InvType, lsl);
LLSDxmlEncode.AddElem("flags", ((int)Flags) & 0xff, lsl);
LLSDxmlEncode.AddMap("sale_info",lsl);
LLSDxmlEncode.AddElem("sale_price", SalePrice, lsl);
LLSDxmlEncode.AddElem("sale_type", SaleType, lsl);
LLSDxmlEncode.AddEndMap(lsl);
LLSDxmlEncode.AddElem("name", Name, lsl);
LLSDxmlEncode.AddElem("desc", Description, lsl);
LLSDxmlEncode.AddElem("created_at", CreationDate, lsl);
LLSDxmlEncode.AddEndMap(lsl);
}
} }
} }

View File

@ -0,0 +1,725 @@
/*
* 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.
*/
// a class for low level LLSD encoding into a provided StringBuilder
// for cases where we already need to know the low level detail
// and so using something like OSD or even protbuf is just a pure waste
using System;
using System.Globalization;
using System.Text;
using OpenMetaverse;
namespace OpenSim.Framework
{
public static class LLSDxmlEncode
{
static readonly DateTime depoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static void AddStart(StringBuilder sb, bool addxmlversion = false)
{
if(addxmlversion)
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
else
sb.Append("<llsd>");
}
// got tired of creating a stringbuilder all the time;
public static StringBuilder Start(int size = 256, bool addxmlversion = false)
{
StringBuilder sb = new StringBuilder(size);
if(addxmlversion)
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
else
sb.Append("<llsd>");
return sb;
}
public static void AddEnd(StringBuilder sb)
{
sb.Append("</llsd>");
}
public static string End(StringBuilder sb)
{
sb.Append("</llsd>");
return sb.ToString();
}
// map == a list of key value pairs
public static void AddMap(StringBuilder sb)
{
sb.Append("<map>");
}
public static void AddEndMap(StringBuilder sb)
{
sb.Append("</map>");
}
public static void AddEmptyMap(StringBuilder sb)
{
sb.Append("<map />");
}
// array == a list values
public static void AddArray(StringBuilder sb)
{
sb.Append("<array>");
}
public static void AddEndArray(StringBuilder sb)
{
sb.Append("</array>");
}
public static void AddEmptyArray(StringBuilder sb)
{
sb.Append("<array />");
}
// undefined or null
public static void AddUnknownElem(StringBuilder sb)
{
sb.Append("<undef />");
}
public static void AddElem(bool e, StringBuilder sb)
{
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean />");
}
public static void AddElem(byte e, StringBuilder sb)
{
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(byte[] e, StringBuilder sb)
{
if(e == null || e.Length == 0)
sb.Append("binary />");
else
{
sb.Append("<binary>"); // encode64 is default
sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
sb.Append("</binary>");
}
}
public static void AddElem(int e, StringBuilder sb)
{
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(float e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(Vector2 e, StringBuilder sb)
{
sb.Append("<map><key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(Vector3 e, StringBuilder sb)
{
sb.Append("<map>key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /><key>z</key>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>z</key>");
}
if(e.Z == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(Quaternion e, StringBuilder sb)
{
sb.Append("<map><key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /><key>z</key>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>z</key>");
}
if(e.Z == 0)
sb.Append("<real /><key>w</key>");
else
{
sb.Append("<real>");
sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>w</key>");
}
if(e.W == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.W.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(double e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(UUID e, StringBuilder sb)
{
if(e == UUID.Zero)
sb.Append("<uuid />");
else
{
sb.Append("<uuid>");
EscapeToXML(e.ToString(), sb);
sb.Append("</uuid>");
}
}
public static void AddElem(string e, StringBuilder sb)
{
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
EscapeToXML(e.ToString(), sb);
sb.Append("</string>");
}
}
public static void AddRawElem(string e, StringBuilder sb)
{
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e);
sb.Append("</string>");
}
}
public static void AddElem(Uri e, StringBuilder sb)
{
if(e == null)
{
sb.Append("<uri />");
return;
}
string s;
if (e.IsAbsoluteUri)
s = e.AbsoluteUri;
else
s = e.ToString();
if(String.IsNullOrEmpty(s))
sb.Append("<uri />");
else
{
sb.Append("<uri>");
sb.Append(s);
sb.Append("</uri>");
}
}
public static void AddElem(DateTime e, StringBuilder sb)
{
DateTime u = e.ToUniversalTime();
if(u == depoch)
{
sb.Append("<date />");
return;
}
string format;
if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
format = "yyyy-MM-dd";
else if (u.Millisecond > 0)
format = "yyyy-MM-ddTHH:mm:ss.ffZ";
else
format = "yyyy-MM-ddTHH:mm:ssZ";
sb.Append("<date>");
sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
sb.Append("</date>");
}
//************ key value *******************
// assumes name is a valid llsd key
public static void AddMap(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map>");
}
public static void AddEmptyMap(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map />");
}
// array == a list values
public static void AddArray(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><array>");
}
public static void AddEmptyArray(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><array />");
}
// undefined or null
public static void AddUnknownElem(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><undef />");
}
public static void AddElem(string name, bool e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean />");
}
public static void AddElem(string name, byte e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(string name, byte[] e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == null || e.Length == 0)
sb.Append("binary />");
else
{
sb.Append("<binary>"); // encode64 is default
sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
sb.Append("</binary>");
}
}
public static void AddElem(string name, int e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(string name, float e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(string name, Vector2 e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map><key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(string name, Vector3 e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map>key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /><key>z</key>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>z</key>");
}
if(e.Z == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(string name, Quaternion e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map><key>x</key>");
if(e.X == 0)
sb.Append("<real /><key>y</key>");
else
{
sb.Append("<real>");
sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>y</key>");
}
if(e.Y == 0)
sb.Append("<real /><key>z</key>");
else
{
sb.Append("<real>");
sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>z</key>");
}
if(e.Z == 0)
sb.Append("<real /><key>w</key>");
else
{
sb.Append("<real>");
sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
sb.Append("</real><key>w</key>");
}
if(e.W == 0)
sb.Append("<real /></map>");
else
{
sb.Append("<real>");
sb.Append(e.W.ToString(CultureInfo.InvariantCulture));
sb.Append("</real></map>");
}
}
public static void AddElem(string name, double e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(string name, UUID e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == UUID.Zero)
sb.Append("<uuid />");
else
{
sb.Append("<uuid>");
EscapeToXML(e.ToString(), sb);
sb.Append("</uuid>");
}
}
public static void AddElem(string name, string e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
EscapeToXML(e.ToString(), sb);
sb.Append("</string>");
}
}
public static void AddRawElem(string name, string e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e);
sb.Append("</string>");
}
}
public static void AddElem(string name, Uri e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == null)
{
sb.Append("<uri />");
return;
}
string s;
if (e.IsAbsoluteUri)
s = e.AbsoluteUri;
else
s = e.ToString();
if(String.IsNullOrEmpty(s))
sb.Append("<uri />");
else
{
sb.Append("<uri>");
sb.Append(s);
sb.Append("</uri>");
}
}
public static void AddElem(string name, DateTime e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
DateTime u = e.ToUniversalTime();
if(u == depoch)
{
sb.Append("<date />");
return;
}
string format;
if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
format = "yyyy-MM-dd";
else if (u.Millisecond > 0)
format = "yyyy-MM-ddTHH:mm:ss.ffZ";
else
format = "yyyy-MM-ddTHH:mm:ssZ";
sb.Append("<date>");
sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
sb.Append("</date>");
}
public static void AddLLSD(string e, StringBuilder sb)
{
sb.Append(e);
}
public static void EscapeToXML(string s, StringBuilder sb)
{
int i;
char c;
int len = s.Length;
for (i = 0; i < len; i++)
{
c = s[i];
switch (c)
{
case '<':
sb.Append("&lt;");
break;
case '>':
sb.Append("&gt;");
break;
case '&':
sb.Append("&amp;");
break;
case '"':
sb.Append("&quot;");
break;
case '\\':
sb.Append("&apos;");
break;
default:
sb.Append(c);
break;
}
}
}
}
}

View File

@ -97,7 +97,9 @@ namespace OpenSim.Framework
private bool _mediaLoop = false; private bool _mediaLoop = false;
private bool _obscureMusic = false; private bool _obscureMusic = false;
private bool _obscureMedia = false; private bool _obscureMedia = false;
private float _dwell = 0;
private float m_dwell = 0;
public double LastDwellTimeMS;
public bool SeeAVs { get; set; } public bool SeeAVs { get; set; }
public bool AnyAVSounds { get; set; } public bool AnyAVSounds { get; set; }
@ -111,11 +113,12 @@ namespace OpenSim.Framework
{ {
get get
{ {
return _dwell; return m_dwell;
} }
set set
{ {
_dwell = value; m_dwell = value;
LastDwellTimeMS = Util.GetTimeStampMS();
} }
} }
@ -735,6 +738,7 @@ namespace OpenSim.Framework
SeeAVs = true; SeeAVs = true;
AnyAVSounds = true; AnyAVSounds = true;
GroupAVSounds = true; GroupAVSounds = true;
LastDwellTimeMS = Util.GetTimeStampMS();
} }
/// <summary> /// <summary>
@ -784,7 +788,7 @@ namespace OpenSim.Framework
landData._obscureMedia = _obscureMedia; landData._obscureMedia = _obscureMedia;
landData._simwideArea = _simwideArea; landData._simwideArea = _simwideArea;
landData._simwidePrims = _simwidePrims; landData._simwidePrims = _simwidePrims;
landData._dwell = _dwell; landData.m_dwell = m_dwell;
landData.SeeAVs = SeeAVs; landData.SeeAVs = SeeAVs;
landData.AnyAVSounds = AnyAVSounds; landData.AnyAVSounds = AnyAVSounds;
landData.GroupAVSounds = GroupAVSounds; landData.GroupAVSounds = GroupAVSounds;

View File

@ -45,8 +45,8 @@ namespace OpenSim.Framework
internal void Clear() internal void Clear()
{ {
this.index = -1; index = -1;
this.heap = null; heap = null;
} }
} }
@ -55,23 +55,26 @@ namespace OpenSim.Framework
internal T value; internal T value;
internal Handle handle; internal Handle handle;
internal HeapItem(T value, Handle handle) internal HeapItem(T _value, Handle _handle)
{ {
this.value = value; value = _value;
this.handle = handle; handle = _handle;
} }
internal void Clear() internal void Clear()
{ {
if (this.handle != null) if (handle != null)
this.handle.Clear(); {
ClearRef(); handle.Clear();
handle = null;
}
value = default(T);
} }
internal void ClearRef() internal void ClearRef()
{ {
this.value = default(T); value = default(T);
this.handle = null; handle = null;
} }
} }
@ -81,6 +84,7 @@ namespace OpenSim.Framework
private int size; private int size;
private object sync_root; private object sync_root;
private int version; private int version;
private int capacity;
private Comparison<T> comparison; private Comparison<T> comparison;
@ -90,14 +94,15 @@ namespace OpenSim.Framework
public MinHeap(int capacity, IComparer<T> comparer) : public MinHeap(int capacity, IComparer<T> comparer) :
this(capacity, new Comparison<T>(comparer.Compare)) { } this(capacity, new Comparison<T>(comparer.Compare)) { }
public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { } public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { }
public MinHeap(int capacity, Comparison<T> comparison) public MinHeap(int _capacity, Comparison<T> _comparison)
{ {
this.items = new HeapItem[capacity]; capacity = _capacity;
this.comparison = comparison; items = new HeapItem[capacity];
this.size = this.version = 0; comparison = _comparison;
size = version = 0;
} }
public int Count { get { return this.size; } } public int Count { get { return size; } }
public bool IsReadOnly { get { return false; } } public bool IsReadOnly { get { return false; } }
@ -108,15 +113,16 @@ namespace OpenSim.Framework
get get
{ {
Handle handle = ValidateThisHandle(key); Handle handle = ValidateThisHandle(key);
return this.items[handle.index].value; return items[handle.index].value;
} }
set set
{ {
Handle handle = ValidateThisHandle(key); Handle handle = ValidateThisHandle(key);
this.items[handle.index].value = value; int indx = handle.index;
if (!BubbleUp(handle.index)) items[indx].value = value;
BubbleDown(handle.index); if (!BubbleUp(indx))
BubbleDown(indx);
} }
} }
@ -124,9 +130,9 @@ namespace OpenSim.Framework
{ {
get get
{ {
if (this.sync_root == null) if (sync_root == null)
Interlocked.CompareExchange<object>(ref this.sync_root, new object(), null); Interlocked.CompareExchange<object>(ref sync_root, new object(), null);
return this.sync_root; return sync_root;
} }
} }
@ -152,27 +158,27 @@ namespace OpenSim.Framework
private void Set(HeapItem item, int index) private void Set(HeapItem item, int index)
{ {
this.items[index] = item; items[index] = item;
if (item.handle != null) if (item.handle != null)
item.handle.index = index; item.handle.index = index;
} }
private bool BubbleUp(int index) private bool BubbleUp(int index)
{ {
HeapItem item = this.items[index]; HeapItem item = items[index];
int current, parent; int current, parent;
for (current = index, parent = (current - 1) / 2; for (current = index, parent = (current - 1) / 2;
(current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0; (current > 0) && (comparison(items[parent].value, item.value)) > 0;
current = parent, parent = (current - 1) / 2) current = parent, parent = (current - 1) / 2)
{ {
Set(this.items[parent], current); Set(items[parent], current);
} }
if (current != index) if (current != index)
{ {
Set(item, current); Set(item, current);
++this.version; ++version;
return true; return true;
} }
return false; return false;
@ -180,24 +186,24 @@ namespace OpenSim.Framework
private void BubbleDown(int index) private void BubbleDown(int index)
{ {
HeapItem item = this.items[index]; HeapItem item = items[index];
int current, child; int current, child;
for (current = index, child = (2 * current) + 1; for (current = index, child = (2 * current) + 1;
current < this.size / 2; current < size / 2;
current = child, child = (2 * current) + 1) current = child, child = (2 * current) + 1)
{ {
if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0) if ((child < size - 1) && comparison(items[child].value, items[child + 1].value) > 0)
++child; ++child;
if (this.comparison(this.items[child].value, item.value) >= 0) if (comparison(items[child].value, item.value) >= 0)
break; break;
Set(this.items[child], current); Set(items[child], current);
} }
if (current != index) if (current != index)
{ {
Set(item, current); Set(item, current);
++this.version; ++version;
} }
} }
@ -206,7 +212,7 @@ namespace OpenSim.Framework
Handle handle = ValidateHandle(key); Handle handle = ValidateHandle(key);
if (handle.index > -1) if (handle.index > -1)
{ {
value = this.items[handle.index].value; value = items[handle.index].value;
return true; return true;
} }
value = default(T); value = default(T);
@ -228,12 +234,12 @@ namespace OpenSim.Framework
public void Add(T value, IHandle ihandle) public void Add(T value, IHandle ihandle)
{ {
if (this.size == this.items.Length) if (size == items.Length)
{ {
int capacity = (int)((this.items.Length * 200L) / 100L); int capacity = (int)((items.Length * 200L) / 100L);
if (capacity < (this.items.Length + DEFAULT_CAPACITY)) if (capacity < (items.Length + DEFAULT_CAPACITY))
capacity = this.items.Length + DEFAULT_CAPACITY; capacity = items.Length + DEFAULT_CAPACITY;
Array.Resize<HeapItem>(ref this.items, capacity); Array.Resize<HeapItem>(ref items, capacity);
} }
Handle handle = null; Handle handle = null;
@ -245,8 +251,8 @@ namespace OpenSim.Framework
HeapItem item = new MinHeap<T>.HeapItem(value, handle); HeapItem item = new MinHeap<T>.HeapItem(value, handle);
Set(item, this.size); Set(item, size);
BubbleUp(this.size++); BubbleUp(size++);
} }
public void Add(T value) public void Add(T value)
@ -256,50 +262,54 @@ namespace OpenSim.Framework
public T Min() public T Min()
{ {
if (this.size == 0) if (size == 0)
throw new InvalidOperationException("Heap is empty"); throw new InvalidOperationException("Heap is empty");
return this.items[0].value; return items[0].value;
} }
public void Clear() public void Clear()
{ {
for (int index = 0; index < this.size; ++index) for (int index = 0; index < size; ++index)
this.items[index].Clear(); items[index].Clear();
this.size = 0; size = 0;
++this.version; if(items.Length > capacity)
items = new HeapItem[capacity];
++version;
} }
public void TrimExcess() public void TrimExcess()
{ {
int length = (int)(this.items.Length * 0.9); int length = (int)(items.Length * 0.9);
if (this.size < length) if (size < length)
Array.Resize<HeapItem>(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY)); Array.Resize<HeapItem>(ref items, Math.Min(size, capacity));
} }
private void RemoveAt(int index) private void RemoveAt(int index)
{ {
if (this.size == 0) if (size == 0)
throw new InvalidOperationException("Heap is empty"); throw new InvalidOperationException("Heap is empty");
if (index >= this.size) if (index >= size)
throw new ArgumentOutOfRangeException("index"); throw new ArgumentOutOfRangeException("index");
this.items[index].Clear(); items[index].Clear();
if (--this.size > 0 && index != this.size) if (--size > 0 && index != size)
{ {
Set(this.items[this.size], index); Set(items[size], index);
this.items[this.size].ClearRef(); items[size].ClearRef();
if (!BubbleUp(index)) if (!BubbleUp(index))
BubbleDown(index); BubbleDown(index);
} }
if(size == 0 && items.Length > 4 * capacity)
items = new HeapItem[capacity];
} }
public T RemoveMin() public T RemoveMin()
{ {
if (this.size == 0) if (size == 0)
throw new InvalidOperationException("Heap is empty"); throw new InvalidOperationException("Heap is empty");
HeapItem item = this.items[0]; HeapItem item = items[0];
RemoveAt(0); RemoveAt(0);
return item.value; return item.value;
} }
@ -307,7 +317,7 @@ namespace OpenSim.Framework
public T Remove(IHandle ihandle) public T Remove(IHandle ihandle)
{ {
Handle handle = ValidateThisHandle(ihandle); Handle handle = ValidateThisHandle(ihandle);
HeapItem item = this.items[handle.index]; HeapItem item = items[handle.index];
RemoveAt(handle.index); RemoveAt(handle.index);
return item.value; return item.value;
} }
@ -317,9 +327,9 @@ namespace OpenSim.Framework
EqualityComparer<T> comparer = EqualityComparer<T>.Default; EqualityComparer<T> comparer = EqualityComparer<T>.Default;
int index; int index;
for (index = 0; index < this.size; ++index) for (index = 0; index < size; ++index)
{ {
if (comparer.Equals(this.items[index].value, value)) if (comparer.Equals(items[index].value, value))
return index; return index;
} }
return -1; return -1;
@ -356,8 +366,8 @@ namespace OpenSim.Framework
if ((length - index) < this.size) if ((length - index) < this.size)
throw new ArgumentException("Not enough space available in array starting at index"); throw new ArgumentException("Not enough space available in array starting at index");
for (int i = 0; i < this.size; ++i) for (int i = 0; i < size; ++i)
array[index + i] = this.items[i].value; array[index + i] = items[i].value;
} }
public void CopyTo(Array array, int index) public void CopyTo(Array array, int index)
@ -372,13 +382,13 @@ namespace OpenSim.Framework
int length = array.Length; int length = array.Length;
if ((index < 0) || (index > length)) if ((index < 0) || (index > length))
throw new ArgumentOutOfRangeException("index"); throw new ArgumentOutOfRangeException("index");
if ((length - index) < this.size) if ((length - index) < size)
throw new ArgumentException("Not enough space available in array starting at index"); throw new ArgumentException("Not enough space available in array starting at index");
try try
{ {
for (int i = 0; i < this.size; ++i) for (int i = 0; i < size; ++i)
array.SetValue(this.items[i].value, index + i); array.SetValue(items[i].value, index + i);
} }
catch (ArrayTypeMismatchException) catch (ArrayTypeMismatchException)
{ {
@ -388,13 +398,13 @@ namespace OpenSim.Framework
public IEnumerator<T> GetEnumerator() public IEnumerator<T> GetEnumerator()
{ {
int version = this.version; int cversion = version;
for (int index = 0; index < this.size; ++index) for (int index = 0; index < size; ++index)
{ {
if (version != this.version) if (cversion != version)
throw new InvalidOperationException("Heap was modified while enumerating"); throw new InvalidOperationException("Heap was modified while enumerating");
yield return this.items[index].value; yield return items[index].value;
} }
} }

View File

@ -57,7 +57,8 @@ namespace OpenSim.Framework.Monitoring
/// <remarks> /// <remarks>
/// Will be null if no job is currently running. /// Will be null if no job is currently running.
/// </remarks> /// </remarks>
public Job CurrentJob { get; private set; } private Job m_currentJob;
public Job CurrentJob { get { return m_currentJob;} }
/// <summary> /// <summary>
/// Number of jobs waiting to be processed. /// Number of jobs waiting to be processed.
@ -78,20 +79,19 @@ namespace OpenSim.Framework.Monitoring
/// </remarks> /// </remarks>
private bool m_warnOverMaxQueue = true; private bool m_warnOverMaxQueue = true;
private BlockingCollection<Job> m_jobQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000); private BlockingCollection<Job> m_jobQueue = new BlockingCollection<Job>(5000);
private CancellationTokenSource m_cancelSource; private CancellationTokenSource m_cancelSource;
/// <summary> private int m_timeout = -1;
/// Used to signal that we are ready to complete stop.
/// </summary>
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
public JobEngine(string name, string loggingName) private bool m_threadRunnig = false;
public JobEngine(string name, string loggingName, int timeout = -1)
{ {
Name = name; Name = name;
LoggingName = loggingName; LoggingName = loggingName;
m_timeout = timeout;
RequestProcessTimeoutOnStop = 5000; RequestProcessTimeoutOnStop = 5000;
} }
@ -104,18 +104,9 @@ namespace OpenSim.Framework.Monitoring
IsRunning = true; IsRunning = true;
m_finishedProcessingAfterStop.Reset();
m_cancelSource = new CancellationTokenSource(); m_cancelSource = new CancellationTokenSource();
WorkManager.RunInThreadPool(ProcessRequests, null, Name, false);
WorkManager.StartThread( m_threadRunnig = true;
ProcessRequests,
Name,
ThreadPriority.Normal,
false,
true,
null,
int.MaxValue);
} }
} }
@ -131,16 +122,15 @@ namespace OpenSim.Framework.Monitoring
m_log.DebugFormat("[JobEngine] Stopping {0}", Name); m_log.DebugFormat("[JobEngine] Stopping {0}", Name);
IsRunning = false; IsRunning = false;
if(m_threadRunnig)
m_finishedProcessingAfterStop.Reset(); {
if(m_jobQueue.Count <= 0)
m_cancelSource.Cancel(); m_cancelSource.Cancel();
m_threadRunnig = false;
if(m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) }
m_finishedProcessingAfterStop.Close();
} }
finally finally
{ {
if(m_cancelSource != null)
m_cancelSource.Dispose(); m_cancelSource.Dispose();
} }
} }
@ -200,6 +190,18 @@ namespace OpenSim.Framework.Monitoring
/// </param> /// </param>
public bool QueueJob(Job job) public bool QueueJob(Job job)
{ {
lock(JobLock)
{
if(!IsRunning)
return false;
if(!m_threadRunnig)
{
WorkManager.RunInThreadPool(ProcessRequests, null, Name, false);
m_threadRunnig = true;
}
}
if (m_jobQueue.Count < m_jobQueue.BoundedCapacity) if (m_jobQueue.Count < m_jobQueue.BoundedCapacity)
{ {
m_jobQueue.Add(job); m_jobQueue.Add(job);
@ -219,59 +221,53 @@ namespace OpenSim.Framework.Monitoring
m_warnOverMaxQueue = false; m_warnOverMaxQueue = false;
} }
return false; return false;
} }
} }
private void ProcessRequests() private void ProcessRequests(Object o)
{ {
while(IsRunning || m_jobQueue.Count > 0) while(IsRunning)
{ {
try try
{ {
CurrentJob = m_jobQueue.Take(m_cancelSource.Token); if(!m_jobQueue.TryTake(out m_currentJob, m_timeout, m_cancelSource.Token))
}
catch(ObjectDisposedException e)
{ {
// If we see this whilst not running then it may be due to a race where this thread checks lock(JobLock)
// IsRunning after the stopping thread sets it to false and disposes of the cancellation source. m_threadRunnig = false;
if(IsRunning) break;
throw e; }
else }
catch(ObjectDisposedException)
{ {
m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue", m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue",
Name,m_jobQueue.Count); Name,m_jobQueue.Count);
break; break;
} }
}
catch(OperationCanceledException) catch(OperationCanceledException)
{ {
break; break;
} }
if(LogLevel >= 1) if(LogLevel >= 1)
m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,CurrentJob.Name); m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,m_currentJob.Name);
try try
{ {
CurrentJob.Action(); m_currentJob.Action();
} }
catch(Exception e) catch(Exception e)
{ {
m_log.Error( m_log.Error(
string.Format( string.Format(
"[{0}]: Job {1} failed, continuing. Exception ",LoggingName,CurrentJob.Name),e); "[{0}]: Job {1} failed, continuing. Exception ",LoggingName,m_currentJob.Name),e);
} }
if(LogLevel >= 1) if(LogLevel >= 1)
m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,CurrentJob.Name); m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,m_currentJob.Name);
CurrentJob = null; m_currentJob = null;
} }
Watchdog.RemoveThread(false);
m_finishedProcessingAfterStop.Set();
} }
public class Job public class Job

View File

@ -88,7 +88,7 @@ namespace OpenSim.Framework.Monitoring
IConfig cfg = source.Configs["Monitoring"]; IConfig cfg = source.Configs["Monitoring"];
if (cfg != null) if (cfg != null)
Enabled = cfg.GetBoolean("ServerStatsEnabled", true); Enabled = cfg.GetBoolean("ServerStatsEnabled", false);
if (Enabled) if (Enabled)
{ {
@ -98,12 +98,18 @@ namespace OpenSim.Framework.Monitoring
public void Start() public void Start()
{ {
if(!Enabled)
return;
if (RegisteredStats.Count == 0) if (RegisteredStats.Count == 0)
RegisterServerStats(); RegisterServerStats();
} }
public void Close() public void Close()
{ {
if(!Enabled)
return;
if (RegisteredStats.Count > 0) if (RegisteredStats.Count > 0)
{ {
foreach (Stat stat in RegisteredStats.Values) foreach (Stat stat in RegisteredStats.Values)

View File

@ -242,11 +242,7 @@ namespace OpenSim.Framework.Monitoring
public virtual OSDMap ToBriefOSDMap() public virtual OSDMap ToBriefOSDMap()
{ {
OSDMap ret = new OSDMap(); OSDMap ret = new OSDMap();
ret.Add("Value", OSD.FromReal(Value)); ret.Add("Value", OSD.FromReal(Value));
double lastChangeOverTime, averageChangeOverTime;
return ret; return ret;
} }

View File

@ -180,6 +180,33 @@ namespace OpenSim.Framework.Monitoring
m_watchdogTimer.Elapsed += WatchdogTimerElapsed; m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
} }
public static void Stop()
{
if(m_threads == null)
return;
lock(m_threads)
{
m_enabled = false;
if(m_watchdogTimer != null)
{
m_watchdogTimer.Dispose();
m_watchdogTimer = null;
}
foreach(ThreadWatchdogInfo twi in m_threads.Values)
{
Thread t = twi.Thread;
// m_log.DebugFormat(
// "[WATCHDOG]: Stop: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
if(t.IsAlive)
t.Abort();
}
m_threads.Clear();
}
}
/// <summary> /// <summary>
/// Add a thread to the watchdog tracker. /// Add a thread to the watchdog tracker.
/// </summary> /// </summary>
@ -230,14 +257,12 @@ namespace OpenSim.Framework.Monitoring
twi.Cleanup(); twi.Cleanup();
m_threads.Remove(threadID); m_threads.Remove(threadID);
return true; return true;
} }
else else
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID); "[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID);
return false; return false;
} }
} }
@ -317,6 +342,8 @@ namespace OpenSim.Framework.Monitoring
/// <param name="e"></param> /// <param name="e"></param>
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{ {
if(!m_enabled)
return;
int now = Environment.TickCount & Int32.MaxValue; int now = Environment.TickCount & Int32.MaxValue;
int msElapsed = now - LastWatchdogThreadTick; int msElapsed = now - LastWatchdogThreadTick;
@ -334,21 +361,26 @@ namespace OpenSim.Framework.Monitoring
List<ThreadWatchdogInfo> callbackInfos = null; List<ThreadWatchdogInfo> callbackInfos = null;
List<ThreadWatchdogInfo> threadsToRemove = null; List<ThreadWatchdogInfo> threadsToRemove = null;
const ThreadState thgone = ThreadState.Stopped;
lock (m_threads) lock (m_threads)
{ {
foreach(ThreadWatchdogInfo threadInfo in m_threads.Values) foreach(ThreadWatchdogInfo threadInfo in m_threads.Values)
{ {
if(threadInfo.Thread.ThreadState == ThreadState.Stopped) if(!m_enabled)
return;
if((threadInfo.Thread.ThreadState & thgone) != 0)
{ {
if(threadsToRemove == null) if(threadsToRemove == null)
threadsToRemove = new List<ThreadWatchdogInfo>(); threadsToRemove = new List<ThreadWatchdogInfo>();
threadsToRemove.Add(threadInfo); threadsToRemove.Add(threadInfo);
/*
if(callbackInfos == null) if(callbackInfos == null)
callbackInfos = new List<ThreadWatchdogInfo>(); callbackInfos = new List<ThreadWatchdogInfo>();
callbackInfos.Add(threadInfo); callbackInfos.Add(threadInfo);
*/
} }
else if(!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) else if(!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
{ {

View File

@ -57,7 +57,7 @@ namespace OpenSim.Framework.Monitoring
static WorkManager() static WorkManager()
{ {
JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE"); JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE", 30000);
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
@ -82,6 +82,12 @@ namespace OpenSim.Framework.Monitoring
HandleControlCommand); HandleControlCommand);
} }
public static void Stop()
{
JobEngine.Stop();
Watchdog.Stop();
}
/// <summary> /// <summary>
/// Start a new long-lived thread. /// Start a new long-lived thread.
/// </summary> /// </summary>
@ -131,7 +137,6 @@ namespace OpenSim.Framework.Monitoring
thread.Start(); thread.Start();
return thread; return thread;
} }
@ -177,9 +182,9 @@ namespace OpenSim.Framework.Monitoring
/// <param name="callback"></param> /// <param name="callback"></param>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <param name="name">The name of the job. This is used in monitoring and debugging.</param> /// <param name="name">The name of the job. This is used in monitoring and debugging.</param>
public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name) public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name, bool timeout = true)
{ {
Util.FireAndForget(callback, obj, name); Util.FireAndForget(callback, obj, name, timeout);
} }
/// <summary> /// <summary>
@ -226,10 +231,8 @@ namespace OpenSim.Framework.Monitoring
JobEngine.QueueJob(name, () => callback(obj)); JobEngine.QueueJob(name, () => callback(obj));
else if (canRunInThisThread) else if (canRunInThisThread)
callback(obj); callback(obj);
else if (mustNotTimeout)
RunInThread(callback, obj, name, log);
else else
Util.FireAndForget(callback, obj, name); Util.FireAndForget(callback, obj, name, !mustNotTimeout);
} }
private static void HandleControlCommand(string module, string[] args) private static void HandleControlCommand(string module, string[] args)

View File

@ -0,0 +1,41 @@
/*
* 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
{
public class MuteData
{
public UUID AgentID;
public UUID MuteID;
public string MuteName;
public int MuteType;
public int MuteFlags;
public int Stamp;
}
}

View File

@ -37,6 +37,8 @@ namespace OpenSim.Framework
public bool isSandbox; public bool isSandbox;
public bool HttpUsesSSL = false; public bool HttpUsesSSL = false;
public string HttpSSLCN = ""; public string HttpSSLCN = "";
public string HttpSSLCertPath = "";
public string HttpSSLCNCertPass = "";
public uint httpSSLPort = 9001; public uint httpSSLPort = 9001;
// "Out of band" managemnt https // "Out of band" managemnt https
@ -62,6 +64,8 @@ namespace OpenSim.Framework
(uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1)); (uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1));
HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false); HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false);
HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost"); HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost");
HttpSSLCertPath = config.Configs["Network"].GetString("http_listener_cert_path", HttpSSLCertPath);
HttpSSLCNCertPass = config.Configs["Network"].GetString("http_listener_cert_pass", HttpSSLCNCertPass);
// "Out of band management https" // "Out of band management https"
ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);

View File

@ -60,9 +60,57 @@ namespace OpenSim.Framework
str += "C"; str += "C";
if ((perms & (int)PermissionMask.Transfer) != 0) if ((perms & (int)PermissionMask.Transfer) != 0)
str += "T"; str += "T";
if ((perms & (int)PermissionMask.Export) != 0)
str += "X";
if (str == "") if (str == "")
str = "."; str = ".";
return str; return str;
} }
public static void ApplyFoldedPermissions(uint foldedSourcePerms, ref uint targetPerms)
{
uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask;
if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do
return;
folded <<= (int)PermissionMask.FoldingShift;
folded |= ~(uint)PermissionMask.UnfoldedMask;
uint tmp = targetPerms;
tmp &= folded;
targetPerms = tmp;
}
// do not touch MOD
public static void ApplyNoModFoldedPermissions(uint foldedSourcePerms, ref uint target)
{
uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask;
if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do
return;
folded <<= (int)PermissionMask.FoldingShift;
folded |= (~(uint)PermissionMask.UnfoldedMask | (uint)PermissionMask.Modify);
uint tmp = target;
tmp &= folded;
target = tmp;
}
public static uint FixAndFoldPermissions(uint perms)
{
uint tmp = perms;
// C & T rule
if((tmp & (uint)(PermissionMask.Copy | PermissionMask.Transfer)) == 0)
tmp |= (uint)PermissionMask.Transfer;
// unlock
tmp |= (uint)PermissionMask.Move;
tmp &= ~(uint)PermissionMask.FoldedMask;
tmp |= ((tmp >> (int)PermissionMask.FoldingShift) & (uint)PermissionMask.FoldedMask);
return tmp;
}
} }
} }

View File

@ -0,0 +1,261 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using System.Text;
using System.IO;
using System.Xml;
namespace OpenSim.Framework
{
public class PhysicsInertiaData
{
public float TotalMass; // the total mass of a linkset
public Vector3 CenterOfMass; // the center of mass position relative to root part position
public Vector3 Inertia; // (Ixx, Iyy, Izz) moment of inertia relative to center of mass and principal axis in local coords
public Vector4 InertiaRotation; // if principal axis don't match local axis, the principal axis rotation
// or the upper triangle of the inertia tensor
// Ixy (= Iyx), Ixz (= Izx), Iyz (= Izy))
public PhysicsInertiaData()
{
}
public PhysicsInertiaData(PhysicsInertiaData source)
{
TotalMass = source.TotalMass;
CenterOfMass = source.CenterOfMass;
Inertia = source.Inertia;
InertiaRotation = source.InertiaRotation;
}
private XmlTextWriter writer;
private void XWint(string name, int i)
{
writer.WriteElementString(name, i.ToString());
}
private void XWfloat(string name, float f)
{
writer.WriteElementString(name, f.ToString(Culture.FormatProvider));
}
private void XWVector(string name, Vector3 vec)
{
writer.WriteStartElement(name);
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
writer.WriteEndElement();
}
private void XWVector4(string name, Vector4 quat)
{
writer.WriteStartElement(name);
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
writer.WriteEndElement();
}
public void ToXml2(XmlTextWriter twriter)
{
writer = twriter;
writer.WriteStartElement("PhysicsInertia");
XWfloat("MASS", TotalMass);
XWVector("CM", CenterOfMass);
XWVector("INERTIA", Inertia);
XWVector4("IROT", InertiaRotation);
writer.WriteEndElement();
writer = null;
}
XmlReader reader;
private int XRint()
{
return reader.ReadElementContentAsInt();
}
private float XRfloat()
{
return reader.ReadElementContentAsFloat();
}
public Vector3 XRvector()
{
Vector3 vec;
reader.ReadStartElement();
vec.X = reader.ReadElementContentAsFloat();
vec.Y = reader.ReadElementContentAsFloat();
vec.Z = reader.ReadElementContentAsFloat();
reader.ReadEndElement();
return vec;
}
public Vector4 XRVector4()
{
Vector4 q;
reader.ReadStartElement();
q.X = reader.ReadElementContentAsFloat();
q.Y = reader.ReadElementContentAsFloat();
q.Z = reader.ReadElementContentAsFloat();
q.W = reader.ReadElementContentAsFloat();
reader.ReadEndElement();
return q;
}
public static bool EReadProcessors(
Dictionary<string, Action> processors,
XmlReader xtr)
{
bool errors = false;
string nodeName = string.Empty;
while (xtr.NodeType != XmlNodeType.EndElement)
{
nodeName = xtr.Name;
Action p = null;
if (processors.TryGetValue(xtr.Name, out p))
{
try
{
p();
}
catch
{
errors = true;
if (xtr.NodeType == XmlNodeType.EndElement)
xtr.Read();
}
}
else
{
xtr.ReadOuterXml(); // ignore
}
}
return errors;
}
public string ToXml2()
{
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter xwriter = new XmlTextWriter(sw))
{
ToXml2(xwriter);
}
return sw.ToString();
}
}
public static PhysicsInertiaData FromXml2(string text)
{
if (text == String.Empty)
return null;
bool error;
PhysicsInertiaData v;
UTF8Encoding enc = new UTF8Encoding();
using(MemoryStream ms = new MemoryStream(enc.GetBytes(text)))
using(XmlTextReader xreader = new XmlTextReader(ms))
{
v = new PhysicsInertiaData();
v.FromXml2(xreader, out error);
}
if (error)
return null;
return v;
}
public static PhysicsInertiaData FromXml2(XmlReader reader)
{
PhysicsInertiaData data = new PhysicsInertiaData();
bool errors = false;
data.FromXml2(reader, out errors);
if (errors)
return null;
return data;
}
private void FromXml2(XmlReader _reader, out bool errors)
{
errors = false;
reader = _reader;
Dictionary<string, Action> m_XmlProcessors = new Dictionary<string, Action>();
m_XmlProcessors.Add("MASS", ProcessXR_Mass);
m_XmlProcessors.Add("CM", ProcessXR_CM);
m_XmlProcessors.Add("INERTIA", ProcessXR_Inertia);
m_XmlProcessors.Add("IROT", ProcessXR_InertiaRotation);
reader.ReadStartElement("PhysicsInertia", String.Empty);
errors = EReadProcessors(
m_XmlProcessors,
reader);
reader.ReadEndElement();
reader = null;
}
private void ProcessXR_Mass()
{
TotalMass = XRfloat();
}
private void ProcessXR_CM()
{
CenterOfMass = XRvector();
}
private void ProcessXR_Inertia()
{
Inertia = XRvector();
}
private void ProcessXR_InertiaRotation()
{
InertiaRotation = XRVector4();
}
}
}

View File

@ -328,6 +328,72 @@ namespace OpenSim.Framework
return shape; return shape;
} }
public static PrimitiveBaseShape CreateMesh(int numberOfFaces, UUID meshAssetID)
{
PrimitiveBaseShape shape = new PrimitiveBaseShape();
shape._pathScaleX = 100;
shape._pathScaleY = 100;
if(numberOfFaces <= 0) // oops ?
numberOfFaces = 1;
switch(numberOfFaces)
{
case 1: // torus
shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Curve1;
shape._pathScaleY = 150;
break;
case 2: // torus with hollow (a sl viewer whould see 4 faces on a hollow sphere)
shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Curve1;
shape.ProfileHollow = 27500;
shape._pathScaleY = 150;
break;
case 3: // cylinder
shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
break;
case 4: // cylinder with hollow
shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
shape.ProfileHollow = 27500;
break;
case 5: // prism
shape.ProfileCurve = (byte)ProfileShape.EquilateralTriangle | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
break;
case 6: // box
shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
break;
case 7: // box with hollow
shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
shape.ProfileHollow = 27500;
break;
default: // 8 faces box with cut
shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
shape.ProfileBegin = 9375;
break;
}
shape.SculptEntry = true;
shape.SculptType = (byte)OpenMetaverse.SculptType.Mesh;
shape.SculptTexture = meshAssetID;
return shape;
}
public void SetScale(float side) public void SetScale(float side)
{ {
_scale = new Vector3(side, side, side); _scale = new Vector3(side, side, side);
@ -1516,10 +1582,14 @@ namespace OpenSim.Framework
{ {
MediaList ml = new MediaList(); MediaList ml = new MediaList();
ml.ReadXml(rawXml); ml.ReadXml(rawXml);
if(ml.Count == 0)
return null;
return ml; return ml;
} }
public void ReadXml(string rawXml) public void ReadXml(string rawXml)
{
try
{ {
using (StringReader sr = new StringReader(rawXml)) using (StringReader sr = new StringReader(rawXml))
{ {
@ -1534,18 +1604,27 @@ namespace OpenSim.Framework
return; return;
xtr.ReadStartElement("OSMedia"); xtr.ReadStartElement("OSMedia");
OSD osdp = OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
if(osdp == null || !(osdp is OSDArray))
return;
OSDArray osdMeArray = osdp as OSDArray;
if(osdMeArray.Count == 0)
return;
OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
foreach (OSD osdMe in osdMeArray) foreach (OSD osdMe in osdMeArray)
{ {
MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
Add(me); Add(me);
} }
xtr.ReadEndElement();
} }
} }
} }
catch
{
m_log.Debug("PrimitiveBaseShape] error decoding MOAP xml" );
}
}
public void ReadXml(XmlReader reader) public void ReadXml(XmlReader reader)
{ {

View File

@ -216,6 +216,27 @@ namespace OpenSim.Framework
return false; return false;
} }
public bool TryOrderedDequeue(out EntityUpdate value, out Int32 timeinqueue)
{
// If there is anything in imediate queues, return it first no
// matter what else. Breaks fairness. But very useful.
for (int iq = 0; iq < NumberOfQueues; iq++)
{
if (m_heaps[iq].Count > 0)
{
MinHeapItem item = m_heaps[iq].RemoveMin();
m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value;
return true;
}
}
timeinqueue = 0;
value = default(EntityUpdate);
return false;
}
/// <summary> /// <summary>
/// Reapply the prioritization function to each of the updates currently /// Reapply the prioritization function to each of the updates currently
/// stored in the priority queues. /// stored in the priority queues.

View File

@ -420,6 +420,7 @@ namespace OpenSim.Framework
set { m_remotingPort = value; } set { m_remotingPort = value; }
} }
/// <value> /// <value>
/// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
/// ///
@ -427,42 +428,7 @@ namespace OpenSim.Framework
/// </value> /// </value>
public IPEndPoint ExternalEndPoint public IPEndPoint ExternalEndPoint
{ {
get get { return Util.getEndPoint(m_externalHostName, m_internalEndPoint.Port); }
{
// Old one defaults to IPv6
//return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
IPAddress ia = null;
// If it is already an IP, don't resolve it - just return directly
if (IPAddress.TryParse(m_externalHostName, out ia))
return new IPEndPoint(ia, m_internalEndPoint.Port);
// Reset for next check
ia = null;
try
{
foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
{
if (ia == null)
ia = Adr;
if (Adr.AddressFamily == AddressFamily.InterNetwork)
{
ia = Adr;
break;
}
}
}
catch (SocketException e)
{
throw new Exception(
"Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
e + "' attached to this exception", e);
}
return new IPEndPoint(ia, m_internalEndPoint.Port);
}
set { m_externalHostName = value.ToString(); } set { m_externalHostName = value.ToString(); }
} }

View File

@ -428,13 +428,16 @@ namespace OpenSim.Framework
if (WebUtil.DebugLevel >= 5) if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src); WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src);
try
{
using (Stream dst = _request.GetRequestStream()) using (Stream dst = _request.GetRequestStream())
{ {
m_log.Debug("[REST]: GetRequestStream is ok"); // m_log.Debug("[REST]: GetRequestStream is ok");
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024); int length = src.Read(buf, 0, 1024);
m_log.Debug("[REST]: First Read is ok"); // m_log.Debug("[REST]: First Read is ok");
while (length > 0) while (length > 0)
{ {
dst.Write(buf, 0, length); dst.Write(buf, 0, length);
@ -442,8 +445,6 @@ namespace OpenSim.Framework
} }
} }
try
{
_response = (HttpWebResponse)_request.GetResponse(); _response = (HttpWebResponse)_request.GetResponse();
} }
catch (WebException e) catch (WebException e)

View File

@ -156,6 +156,7 @@ namespace OpenSim.Framework.Serialization.External
return xml; return xml;
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
doc.LoadXml(xml); doc.LoadXml(xml);
XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
@ -220,7 +221,7 @@ namespace OpenSim.Framework.Serialization.External
using (StringWriter sw = new StringWriter()) using (StringWriter sw = new StringWriter())
using (XmlTextWriter writer = new XmlTextWriter(sw)) using (XmlTextWriter writer = new XmlTextWriter(sw))
using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment}))
{ {
TransformXml(reader, writer, sceneName, homeURL, userService, scopeID); TransformXml(reader, writer, sceneName, homeURL, userService, scopeID);

View File

@ -33,6 +33,9 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using log4net; using log4net;
using log4net.Appender; using log4net.Appender;
using log4net.Core; using log4net.Core;
@ -86,6 +89,26 @@ namespace OpenSim.Framework.Servers
m_osSecret = UUID.Random().ToString(); m_osSecret = UUID.Random().ToString();
} }
private static bool m_NoVerifyCertChain = false;
private static bool m_NoVerifyCertHostname = false;
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (m_NoVerifyCertChain)
sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
if (m_NoVerifyCertHostname)
sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch;
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
return false;
}
/// <summary> /// <summary>
/// Must be overriden by child classes for their own server specific startup behaviour. /// Must be overriden by child classes for their own server specific startup behaviour.
/// </summary> /// </summary>
@ -96,6 +119,11 @@ namespace OpenSim.Framework.Servers
RegisterCommonComponents(Config); RegisterCommonComponents(Config);
IConfig startupConfig = Config.Configs["Startup"]; IConfig startupConfig = Config.Configs["Startup"];
m_NoVerifyCertChain = startupConfig.GetBoolean("NoVerifyCertChain", m_NoVerifyCertChain);
m_NoVerifyCertHostname = startupConfig.GetBoolean("NoVerifyCertHostname", m_NoVerifyCertHostname);
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000); int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000);
m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000; m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000;
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
@ -108,11 +136,19 @@ namespace OpenSim.Framework.Servers
protected override void ShutdownSpecific() protected override void ShutdownSpecific()
{ {
m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); Watchdog.Enabled = false;
base.ShutdownSpecific();
MainServer.Stop();
Thread.Sleep(5000);
Util.StopThreadPool();
WorkManager.Stop();
Thread.Sleep(1000);
RemovePIDFile(); RemovePIDFile();
base.ShutdownSpecific(); m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
if (!SuppressExit) if (!SuppressExit)
Environment.Exit(0); Environment.Exit(0);
@ -163,8 +199,7 @@ namespace OpenSim.Framework.Servers
} }
catch(Exception e) catch(Exception e)
{ {
m_log.FatalFormat("Fatal error: {0}", m_log.Fatal("Fatal error: " + e.ToString());
(e.Message == null || e.Message == String.Empty) ? "Unknown reason":e.Message );
Environment.Exit(1); Environment.Exit(1);
} }

View File

@ -32,6 +32,7 @@ using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Reflection; using System.Reflection;
using System.Globalization; using System.Globalization;
@ -43,10 +44,11 @@ using log4net;
using Nwc.XmlRpc; using Nwc.XmlRpc;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using CoolHTTPListener = HttpServer.HttpListener; using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener; using HttpListener = System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio; using LogPrio = HttpServer.LogPrio;
using OpenSim.Framework.Monitoring; using OpenSim.Framework.Monitoring;
using System.IO.Compression; using System.IO.Compression;
using System.Security.Cryptography;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {
@ -107,19 +109,26 @@ namespace OpenSim.Framework.Servers.HttpServer
new Dictionary<string, WebSocketRequestDelegate>(); new Dictionary<string, WebSocketRequestDelegate>();
protected uint m_port; protected uint m_port;
protected uint m_sslport;
protected bool m_ssl; protected bool m_ssl;
private X509Certificate2 m_cert; private X509Certificate2 m_cert;
protected bool m_firstcaps = true;
protected string m_SSLCommonName = ""; protected string m_SSLCommonName = "";
protected List<string> m_certNames = new List<string>();
protected List<string> m_certIPs = new List<string>();
protected string m_certCN= "";
protected RemoteCertificateValidationCallback m_certificateValidationCallback = null;
protected IPAddress m_listenIPAddress = IPAddress.Any; protected IPAddress m_listenIPAddress = IPAddress.Any;
public PollServiceRequestManager PollServiceRequestManager { get; private set; } public PollServiceRequestManager PollServiceRequestManager { get; private set; }
public string Protocol
{
get { return m_ssl ? "https://" : "http://"; }
}
public uint SSLPort public uint SSLPort
{ {
get { return m_sslport; } get { return m_port; }
} }
public string SSLCommonName public string SSLCommonName
@ -148,27 +157,166 @@ namespace OpenSim.Framework.Servers.HttpServer
m_port = port; m_port = port;
} }
public BaseHttpServer(uint port, bool ssl) : this (port) private void load_cert(string CPath, string CPass)
{ {
m_ssl = ssl; try
}
public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl)
{
if (m_ssl)
{
m_sslport = sslport;
}
}
public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl)
{
if (m_ssl)
{ {
m_cert = new X509Certificate2(CPath, CPass); m_cert = new X509Certificate2(CPath, CPass);
X509Extension ext = m_cert.Extensions["2.5.29.17"];
if(ext != null)
{
AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData);
string datastr = asndata.Format(true);
string[] lines = datastr.Split(new char[] {'\n','\r'});
foreach(string s in lines)
{
if(String.IsNullOrEmpty(s))
continue;
string[] parts = s.Split(new char[] {'='});
if(String.IsNullOrEmpty(parts[0]))
continue;
string entryName = parts[0].Replace(" ","");
if(entryName == "DNSName")
m_certNames.Add(parts[1]);
else if(entryName == "IPAddress")
m_certIPs.Add(parts[1]);
else if(entryName == "Unknown(135)") // stupid mono
{
try
{
if(parts[1].Length == 8)
{
long tmp = long.Parse(parts[1], NumberStyles.AllowHexSpecifier);
tmp = IPAddress.HostToNetworkOrder(tmp);
tmp = (long)((ulong) tmp >> 32);
IPAddress ia = new IPAddress(tmp);
m_certIPs.Add(ia.ToString());
}
}
catch {}
}
}
}
m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false);
}
catch
{
throw new Exception("SSL cert load error");
} }
} }
public BaseHttpServer(uint port, bool ssl, string CN, string CPath, string CPass)
{
m_port = port;
if (ssl)
{
if(string.IsNullOrEmpty(CPath))
throw new Exception("invalid main http server cert path");
if(Uri.CheckHostName(CN) == UriHostNameType.Unknown)
throw new Exception("invalid main http server CN (ExternalHostName)");
m_certNames.Clear();
m_certIPs.Clear();
m_certCN= "";
m_ssl = true;
load_cert(CPath, CPass);
if(!CheckSSLCertHost(CN))
throw new Exception("invalid main http server CN (ExternalHostName)");
m_SSLCommonName = CN;
if(m_cert.Issuer == m_cert.Subject )
m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true");
}
else
m_ssl = false;
}
public BaseHttpServer(uint port, bool ssl, string CPath, string CPass)
{
m_port = port;
if (ssl)
{
load_cert(CPath, CPass);
if(m_cert.Issuer == m_cert.Subject )
m_log.Warn("Self signed certificate. Http clients need to allow this");
m_ssl = true;
}
else
m_ssl = false;
}
static bool MatchDNS (string hostname, string dns)
{
int indx = dns.IndexOf ('*');
if (indx == -1)
return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0);
int dnslen = dns.Length;
dnslen--;
if(indx == dnslen)
return true; // just * ?
if(indx > dnslen - 2)
return false; // 2 short ?
if (dns[indx + 1] != '.')
return false;
int indx2 = dns.IndexOf ('*', indx + 1);
if (indx2 != -1)
return false; // there can only be one;
string end = dns.Substring(indx + 1);
int hostlen = hostname.Length;
int endlen = end.Length;
int length = hostlen - endlen;
if (length <= 0)
return false;
if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0)
return false;
if (indx == 0)
{
indx2 = hostname.IndexOf ('.');
return ((indx2 == -1) || (indx2 >= length));
}
string start = dns.Substring (0, indx);
return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
}
public bool CheckSSLCertHost(string hostname)
{
UriHostNameType htype = Uri.CheckHostName(hostname);
if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic)
return false;
if(htype == UriHostNameType.Dns)
{
foreach(string name in m_certNames)
{
if(MatchDNS(hostname, name))
return true;
}
if(MatchDNS(hostname, m_certCN))
return true;
}
else
{
foreach(string ip in m_certIPs)
{
if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) == 0)
return true;
}
}
return false;
}
/// <summary> /// <summary>
/// Add a stream handler to the http server. If the handler already exists, then nothing happens. /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
/// </summary> /// </summary>
@ -396,14 +544,10 @@ namespace OpenSim.Framework.Servers.HttpServer
if (psEvArgs.Request != null) if (psEvArgs.Request != null)
{ {
OSHttpRequest req = new OSHttpRequest(context, request); OSHttpRequest req = new OSHttpRequest(context, request);
string requestBody;
Stream requestStream = req.InputStream;
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding); using(StreamReader reader = new StreamReader(req.InputStream, encoding))
requestBody = reader.ReadToEnd();
string requestBody = reader.ReadToEnd();
reader.Close();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -461,8 +605,7 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
resp.ReuseContext = true;
// resp.ReuseContext = false;
HandleRequest(req, resp); HandleRequest(req, resp);
// !!!HACK ALERT!!! // !!!HACK ALERT!!!
@ -494,6 +637,8 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
try try
{ {
if(request.InputStream != null && request.InputStream.CanRead)
request.InputStream.Close();
byte[] buffer500 = SendHTML500(response); byte[] buffer500 = SendHTML500(response);
response.OutputStream.Write(buffer500, 0, buffer500.Length); response.OutputStream.Write(buffer500, 0, buffer500.Length);
response.Send(); response.Send();
@ -541,7 +686,6 @@ namespace OpenSim.Framework.Servers.HttpServer
// } // }
// } // }
//response.KeepAlive = true;
response.SendChunked = false; response.SendChunked = false;
string path = request.RawUrl; string path = request.RawUrl;
@ -565,15 +709,11 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
//m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler"); //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler");
IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler;
Stream requestStream = request.InputStream;
string requestBody;
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding); using(StreamReader reader = new StreamReader(request.InputStream, encoding))
requestBody = reader.ReadToEnd();
string requestBody = reader.ReadToEnd();
reader.Close();
//requestStream.Close();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -613,7 +753,6 @@ namespace OpenSim.Framework.Servers.HttpServer
else else
{ {
IStreamHandler streamHandler = (IStreamHandler)requestHandler; IStreamHandler streamHandler = (IStreamHandler)requestHandler;
using (MemoryStream memoryStream = new MemoryStream()) using (MemoryStream memoryStream = new MemoryStream())
{ {
streamHandler.Handle(path, request.InputStream, memoryStream, request, response); streamHandler.Handle(path, request.InputStream, memoryStream, request, response);
@ -690,7 +829,8 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
request.InputStream.Close(); if(request.InputStream != null && request.InputStream.CanRead)
request.InputStream.Dispose();
if (buffer != null) if (buffer != null)
{ {
@ -723,10 +863,6 @@ namespace OpenSim.Framework.Servers.HttpServer
requestEndTick = Environment.TickCount; requestEndTick = Environment.TickCount;
response.Send(); response.Send();
//response.OutputStream.Close();
//response.FreeContext();
} }
catch (SocketException e) catch (SocketException e)
{ {
@ -758,6 +894,9 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
finally finally
{ {
if(request.InputStream != null && request.InputStream.CanRead)
request.InputStream.Close();
// Every month or so this will wrap and give bad numbers, not really a problem // Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting // since its just for reporting
int tickdiff = requestEndTick - requestStartTick; int tickdiff = requestEndTick - requestStartTick;
@ -998,7 +1137,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
String requestBody; String requestBody;
Stream requestStream = request.InputStream; Stream requestStream = Util.Copy(request.InputStream);
Stream innerStream = null; Stream innerStream = null;
try try
{ {
@ -1009,14 +1148,14 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
requestBody = reader.ReadToEnd(); requestBody = reader.ReadToEnd();
}
} }
finally finally
{ {
if (innerStream != null) if (innerStream != null && innerStream.CanRead)
innerStream.Dispose(); innerStream.Dispose();
if (requestStream.CanRead)
requestStream.Dispose(); requestStream.Dispose();
} }
@ -1098,6 +1237,17 @@ namespace OpenSim.Framework.Servers.HttpServer
if (gridproxy) if (gridproxy)
xmlRprcRequest.Params.Add("gridproxy"); // Param[4] xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
// reserve this for
// ... by Fumi.Iseki for DTLNSLMoneyServer
// BUT make its presence possible to detect/parse
string rcn = request.IHttpClientContext.SSLCommonName;
if(!string.IsNullOrWhiteSpace(rcn))
{
rcn = "SSLCN:" + rcn;
xmlRprcRequest.Params.Add(rcn); // Param[4] or Param[5]
}
try try
{ {
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@ -1263,15 +1413,12 @@ namespace OpenSim.Framework.Servers.HttpServer
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
Stream requestStream = request.InputStream; Stream requestStream = request.InputStream;
string requestBody;
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding); using(StreamReader reader = new StreamReader(requestStream, encoding))
requestBody= reader.ReadToEnd();
string requestBody = reader.ReadToEnd();
reader.Close();
requestStream.Close();
//m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody);
response.KeepAlive = true;
OSD llsdRequest = null; OSD llsdRequest = null;
OSD llsdResponse = null; OSD llsdResponse = null;
@ -1592,15 +1739,10 @@ namespace OpenSim.Framework.Servers.HttpServer
byte[] buffer; byte[] buffer;
Stream requestStream = request.InputStream; Stream requestStream = request.InputStream;
string requestBody;
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(requestStream, encoding); using(StreamReader reader = new StreamReader(requestStream, encoding))
requestBody = reader.ReadToEnd();
string requestBody = reader.ReadToEnd();
// avoid warning for now
reader.ReadToEnd();
reader.Close();
requestStream.Close();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -1792,20 +1934,13 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
response.ProtocolVersion = (string)responsedata["http_protocol_version"]; response.ProtocolVersion = (string)responsedata["http_protocol_version"];
} }
/*
if (responsedata.ContainsKey("keepalive")) if (responsedata.ContainsKey("keepalive"))
{ {
bool keepalive = (bool)responsedata["keepalive"]; bool keepalive = (bool)responsedata["keepalive"];
response.KeepAlive = keepalive; response.KeepAlive = keepalive;
} }
if (responsedata.ContainsKey("reusecontext"))
response.ReuseContext = (bool) responsedata["reusecontext"];
*/
// disable this things
response.KeepAlive = false;
response.ReuseContext = false;
// Cross-Origin Resource Sharing with simple requests // Cross-Origin Resource Sharing with simple requests
if (responsedata.ContainsKey("access_control_allow_origin")) if (responsedata.ContainsKey("access_control_allow_origin"))
response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]); response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);
@ -1818,11 +1953,8 @@ namespace OpenSim.Framework.Servers.HttpServer
contentType = "text/html"; contentType = "text/html";
} }
// The client ignores anything but 200 here for web login, so ensure that this is 200 for that // The client ignores anything but 200 here for web login, so ensure that this is 200 for that
response.StatusCode = responsecode; response.StatusCode = responsecode;
if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
@ -1832,13 +1964,12 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
response.AddHeader("Content-Type", contentType); response.AddHeader("Content-Type", contentType);
if (responsedata.ContainsKey("headers")) if (responsedata.ContainsKey("headers"))
{ {
Hashtable headerdata = (Hashtable)responsedata["headers"]; Hashtable headerdata = (Hashtable)responsedata["headers"];
foreach (string header in headerdata.Keys) foreach (string header in headerdata.Keys)
response.AddHeader(header, (string)headerdata[header]); response.AddHeader(header, headerdata[header].ToString());
} }
byte[] buffer; byte[] buffer;
@ -1906,7 +2037,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Start() public void Start()
{ {
Start(true); Start(true,true);
} }
/// <summary> /// <summary>
@ -1916,7 +2047,7 @@ namespace OpenSim.Framework.Servers.HttpServer
/// If true then poll responses are performed asynchronsly. /// If true then poll responses are performed asynchronsly.
/// Option exists to allow regression tests to perform processing synchronously. /// Option exists to allow regression tests to perform processing synchronously.
/// </param> /// </param>
public void Start(bool performPollResponsesAsync) public void Start(bool performPollResponsesAsync, bool runPool)
{ {
m_log.InfoFormat( m_log.InfoFormat(
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
@ -1945,6 +2076,8 @@ namespace OpenSim.Framework.Servers.HttpServer
//m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
//m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); //m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert);
if(m_certificateValidationCallback != null)
m_httpListener2.CertificateValidationCallback = m_certificateValidationCallback;
m_httpListener2.ExceptionThrown += httpServerException; m_httpListener2.ExceptionThrown += httpServerException;
m_httpListener2.LogWriter = httpserverlog; m_httpListener2.LogWriter = httpserverlog;
} }
@ -1954,9 +2087,11 @@ namespace OpenSim.Framework.Servers.HttpServer
m_httpListener2.Start(64); m_httpListener2.Start(64);
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
if(runPool)
{
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000);
PollServiceRequestManager.Start(); PollServiceRequestManager.Start();
}
HTTPDRunning = true; HTTPDRunning = true;
@ -1970,7 +2105,7 @@ namespace OpenSim.Framework.Servers.HttpServer
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message); m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message);
m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + ", " + m_sslport + "?"); m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + "?");
// We want this exception to halt the entire server since in current configurations we aren't too // We want this exception to halt the entire server since in current configurations we aren't too
// useful without inbound HTTP. // useful without inbound HTTP.
@ -2028,6 +2163,7 @@ namespace OpenSim.Framework.Servers.HttpServer
try try
{ {
if(PollServiceRequestManager != null)
PollServiceRequestManager.Stop(); PollServiceRequestManager.Stop();
m_httpListener2.ExceptionThrown -= httpServerException; m_httpListener2.ExceptionThrown -= httpServerException;
@ -2135,10 +2271,9 @@ namespace OpenSim.Framework.Servers.HttpServer
string file = Path.Combine(".", "http_500.html"); string file = Path.Combine(".", "http_500.html");
if (!File.Exists(file)) if (!File.Exists(file))
return getDefaultHTTP500(); return getDefaultHTTP500();
string result;
StreamReader sr = File.OpenText(file); using(StreamReader sr = File.OpenText(file))
string result = sr.ReadToEnd(); result = sr.ReadToEnd();
sr.Close();
return result; return result;
} }

View File

@ -118,7 +118,7 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </summary> /// </summary>
string StatusDescription { get; set; } string StatusDescription { get; set; }
bool ReuseContext { get; set; } // bool ReuseContext { get; set; }
/// <summary> /// <summary>
/// Add a header field and content to the response. /// Add a header field and content to the response.

View File

@ -257,25 +257,6 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public bool ReuseContext
{
get
{
if (_httpClientContext != null)
{
return !_httpClientContext.EndWhenDone;
}
return true;
}
set
{
if (_httpClientContext != null)
{
_httpClientContext.EndWhenDone = !value;
}
}
}
protected IHttpResponse _httpResponse; protected IHttpResponse _httpResponse;
private IHttpClientContext _httpClientContext; private IHttpClientContext _httpClientContext;

View File

@ -37,6 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId);
public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId);
public delegate void DropMethod(UUID requestID, UUID pId);
public class PollServiceEventArgs : EventArgs public class PollServiceEventArgs : EventArgs
{ {
@ -44,13 +45,14 @@ namespace OpenSim.Framework.Servers.HttpServer
public GetEventsMethod GetEvents; public GetEventsMethod GetEvents;
public NoEventsMethod NoEvents; public NoEventsMethod NoEvents;
public RequestMethod Request; public RequestMethod Request;
public DropMethod Drop;
public UUID Id; public UUID Id;
public int TimeOutms; public int TimeOutms;
public EventType Type; public EventType Type;
public enum EventType : int public enum EventType : int
{ {
LongPoll = 0, Poll = 0,
LslHttp = 1, LslHttp = 1,
Inventory = 2, Inventory = 2,
Texture = 3, Texture = 3,
@ -73,16 +75,17 @@ namespace OpenSim.Framework.Servers.HttpServer
RequestMethod pRequest, RequestMethod pRequest,
string pUrl, string pUrl,
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
UUID pId, int pTimeOutms) DropMethod pDrop, UUID pId, int pTimeOutms)
{ {
Request = pRequest; Request = pRequest;
Url = pUrl; Url = pUrl;
HasEvents = pHasEvents; HasEvents = pHasEvents;
GetEvents = pGetEvents; GetEvents = pGetEvents;
NoEvents = pNoEvents; NoEvents = pNoEvents;
Drop = pDrop;
Id = pId; Id = pId;
TimeOutms = pTimeOutms; TimeOutms = pTimeOutms;
Type = EventType.LongPoll; Type = EventType.Poll;
} }
} }
} }

View File

@ -47,8 +47,10 @@ namespace OpenSim.Framework.Servers.HttpServer
public readonly UUID RequestID; public readonly UUID RequestID;
public int contextHash; public int contextHash;
/*
private void GenContextHash() private void GenContextHash()
{ {
Random rnd = new Random(); Random rnd = new Random();
contextHash = 0; contextHash = 0;
if (Request.Headers["remote_addr"] != null) if (Request.Headers["remote_addr"] != null)
@ -62,8 +64,9 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
else else
contextHash += rnd.Next() & 0xffff; contextHash += rnd.Next() & 0xffff;
}
}
*/
public PollServiceHttpRequest( public PollServiceHttpRequest(
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
{ {
@ -72,7 +75,8 @@ namespace OpenSim.Framework.Servers.HttpServer
Request = pRequest; Request = pRequest;
RequestTime = System.Environment.TickCount; RequestTime = System.Environment.TickCount;
RequestID = UUID.Random(); RequestID = UUID.Random();
GenContextHash(); // GenContextHash();
contextHash = HttpContext.contextID;
} }
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
@ -82,10 +86,12 @@ namespace OpenSim.Framework.Servers.HttpServer
byte[] buffer = server.DoHTTPGruntWork(responsedata, response); byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
if(Request.Body.CanRead)
Request.Body.Dispose();
response.SendChunked = false; response.SendChunked = false;
response.ContentLength64 = buffer.Length; response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8; response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
try try
{ {
@ -114,10 +120,12 @@ namespace OpenSim.Framework.Servers.HttpServer
OSHttpResponse response OSHttpResponse response
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
if(Request.Body.CanRead)
Request.Body.Dispose();
response.SendChunked = false; response.SendChunked = false;
response.ContentLength64 = 0; response.ContentLength64 = 0;
response.ContentEncoding = Encoding.UTF8; response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
response.KeepAlive = false; response.KeepAlive = false;
response.SendChunked = false; response.SendChunked = false;
response.StatusCode = 503; response.StatusCode = 503;
@ -127,7 +135,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.OutputStream.Flush(); response.OutputStream.Flush();
response.Send(); response.Send();
} }
catch (Exception e) catch
{ {
} }
} }

View File

@ -30,13 +30,10 @@ using System.Collections;
using System.Threading; using System.Threading;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
using HttpServer;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring; using OpenSim.Framework.Monitoring;
using Amib.Threading; using Amib.Threading;
using System.IO;
using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Concurrent;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {
@ -46,21 +43,18 @@ namespace OpenSim.Framework.Servers.HttpServer
private readonly BaseHttpServer m_server; private readonly BaseHttpServer m_server;
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext; private Dictionary<int, Queue<PollServiceHttpRequest>> m_bycontext;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); private BlockingCollection<PollServiceHttpRequest> m_requests = new BlockingCollection<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); private static ConcurrentQueue<PollServiceHttpRequest> m_retryRequests = new ConcurrentQueue<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
private uint m_WorkerThreadCount = 0; private uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads; private Thread[] m_workerThreads;
private Thread m_retrysThread; private Thread m_retrysThread;
private bool m_running = false; private bool m_running = false;
private int slowCount = 0;
private SmartThreadPool m_threadPool; private SmartThreadPool m_threadPool;
public PollServiceRequestManager( public PollServiceRequestManager(
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
{ {
@ -68,8 +62,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_WorkerThreadCount = pWorkerThreadCount; m_WorkerThreadCount = pWorkerThreadCount;
m_workerThreads = new Thread[m_WorkerThreadCount]; m_workerThreads = new Thread[m_WorkerThreadCount];
PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); m_bycontext = new Dictionary<int, Queue<PollServiceHttpRequest>>(256);
m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp);
STPStartInfo startInfo = new STPStartInfo(); STPStartInfo startInfo = new STPStartInfo();
startInfo.IdleTimeout = 30000; startInfo.IdleTimeout = 30000;
@ -80,7 +73,6 @@ namespace OpenSim.Framework.Servers.HttpServer
startInfo.ThreadPoolName = "PoolService"; startInfo.ThreadPoolName = "PoolService";
m_threadPool = new SmartThreadPool(startInfo); m_threadPool = new SmartThreadPool(startInfo);
} }
public void Start() public void Start()
@ -95,7 +87,7 @@ namespace OpenSim.Framework.Servers.HttpServer
PoolWorkerJob, PoolWorkerJob,
string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
ThreadPriority.Normal, ThreadPriority.Normal,
false, true,
false, false,
null, null,
int.MaxValue); int.MaxValue);
@ -105,36 +97,32 @@ namespace OpenSim.Framework.Servers.HttpServer
this.CheckRetries, this.CheckRetries,
string.Format("PollServiceWatcherThread:{0}", m_server.Port), string.Format("PollServiceWatcherThread:{0}", m_server.Port),
ThreadPriority.Normal, ThreadPriority.Normal,
false, true,
true, true,
null, null,
1000 * 60 * 10); 1000 * 60 * 10);
} }
private void ReQueueEvent(PollServiceHttpRequest req) private void ReQueueEvent(PollServiceHttpRequest req)
{ {
if (m_running) if (m_running)
{
lock (m_retryRequests)
m_retryRequests.Enqueue(req); m_retryRequests.Enqueue(req);
} }
}
public void Enqueue(PollServiceHttpRequest req) public void Enqueue(PollServiceHttpRequest req)
{ {
Queue<PollServiceHttpRequest> ctxQeueue;
int rhash = req.contextHash;
lock (m_bycontext) lock (m_bycontext)
{ {
Queue<PollServiceHttpRequest> ctxQeueue; if (m_bycontext.TryGetValue(rhash, out ctxQeueue))
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{ {
ctxQeueue.Enqueue(req); ctxQeueue.Enqueue(req);
} }
else else
{ {
ctxQeueue = new Queue<PollServiceHttpRequest>(); ctxQeueue = new Queue<PollServiceHttpRequest>();
m_bycontext[req] = ctxQeueue; m_bycontext[rhash] = ctxQeueue;
EnqueueInt(req); EnqueueInt(req);
} }
} }
@ -143,9 +131,10 @@ namespace OpenSim.Framework.Servers.HttpServer
public void byContextDequeue(PollServiceHttpRequest req) public void byContextDequeue(PollServiceHttpRequest req)
{ {
Queue<PollServiceHttpRequest> ctxQeueue; Queue<PollServiceHttpRequest> ctxQeueue;
int rhash = req.contextHash;
lock (m_bycontext) lock (m_bycontext)
{ {
if (m_bycontext.TryGetValue(req, out ctxQeueue)) if (m_bycontext.TryGetValue(rhash, out ctxQeueue))
{ {
if (ctxQeueue.Count > 0) if (ctxQeueue.Count > 0)
{ {
@ -154,51 +143,41 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
else else
{ {
m_bycontext.Remove(req); m_bycontext.Remove(rhash);
} }
} }
} }
} }
public void DropByContext(PollServiceHttpRequest req)
{
Queue<PollServiceHttpRequest> ctxQeueue;
int rhash = req.contextHash;
lock (m_bycontext)
{
if (m_bycontext.TryGetValue(rhash, out ctxQeueue))
{
ctxQeueue.Clear();
m_bycontext.Remove(rhash);
}
}
}
public void EnqueueInt(PollServiceHttpRequest req) public void EnqueueInt(PollServiceHttpRequest req)
{ {
if (m_running) if (m_running)
{ m_requests.Add(req);
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
{
m_requests.Enqueue(req);
}
else
{
lock (m_slowRequests)
m_slowRequests.Enqueue(req);
}
}
} }
private void CheckRetries() private void CheckRetries()
{ {
PollServiceHttpRequest preq;
while (m_running) while (m_running)
{ {
Thread.Sleep(100); // let the world move .. back to faster rate Thread.Sleep(100);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
lock (m_retryRequests) while (m_running && m_retryRequests.TryDequeue(out preq))
{ m_requests.Add(preq);
while (m_retryRequests.Count > 0 && m_running)
m_requests.Enqueue(m_retryRequests.Dequeue());
}
slowCount++;
if (slowCount >= 10)
{
slowCount = 0;
lock (m_slowRequests)
{
while (m_slowRequests.Count > 0 && m_running)
m_requests.Enqueue(m_slowRequests.Dequeue());
}
}
} }
} }
@ -206,81 +185,94 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
m_running = false; m_running = false;
Thread.Sleep(1000); // let the world move Thread.Sleep(100); // let the world move
foreach (Thread t in m_workerThreads) foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId); Watchdog.AbortThread(t.ManagedThreadId);
m_threadPool.Shutdown();
// any entry in m_bycontext should have a active request on the other queues // any entry in m_bycontext should have a active request on the other queues
// so just delete contents to easy GC // so just delete contents to easy GC
foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values) foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values)
qu.Clear(); qu.Clear();
m_bycontext.Clear(); m_bycontext.Clear();
PollServiceHttpRequest req;
try try
{ {
foreach (PollServiceHttpRequest req in m_retryRequests) while(m_retryRequests.TryDequeue(out req))
{
req.DoHTTPstop(m_server); req.DoHTTPstop(m_server);
} }
}
catch catch
{ {
} }
PollServiceHttpRequest wreq;
m_retryRequests.Clear();
lock (m_slowRequests)
{
while (m_slowRequests.Count > 0)
m_requests.Enqueue(m_slowRequests.Dequeue());
}
while (m_requests.Count() > 0)
{
try try
{ {
wreq = m_requests.Dequeue(0); while(m_requests.TryTake(out req, 0))
wreq.DoHTTPstop(m_server); req.DoHTTPstop(m_server);
} }
catch catch
{ {
} }
}
m_requests.Clear(); m_requests.Dispose();
} }
// work threads // work threads
private void PoolWorkerJob() private void PoolWorkerJob()
{ {
PollServiceHttpRequest req;
while (m_running) while (m_running)
{ {
PollServiceHttpRequest req = m_requests.Dequeue(5000); req = null;
if(!m_requests.TryTake(out req, 4500) || req == null)
{
Watchdog.UpdateThread();
continue;
}
Watchdog.UpdateThread(); Watchdog.UpdateThread();
if (req != null)
{
try try
{ {
if(!req.HttpContext.CanSend())
{
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
byContextDequeue(req);
continue;
}
if(req.HttpContext.IsSending())
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
byContextDequeue(req);
}
else
ReQueueEvent(req);
continue;
}
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
{ {
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); PollServiceHttpRequest nreq = req;
m_threadPool.QueueWorkItem(x => m_threadPool.QueueWorkItem(x =>
{ {
try try
{ {
req.DoHTTPGruntWork(m_server, responsedata); Hashtable responsedata = nreq.PollServiceArgs.GetEvents(nreq.RequestID, nreq.PollServiceArgs.Id);
byContextDequeue(req); nreq.DoHTTPGruntWork(m_server, responsedata);
} }
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream catch (ObjectDisposedException) { }
finally
{ {
// Ignore it, no need to reply byContextDequeue(nreq);
nreq = null;
} }
return null; return null;
}, null); }, null);
@ -289,17 +281,19 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{ {
PollServiceHttpRequest nreq = req;
m_threadPool.QueueWorkItem(x => m_threadPool.QueueWorkItem(x =>
{ {
try try
{ {
req.DoHTTPGruntWork(m_server, nreq.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id));
byContextDequeue(req);
} }
catch (ObjectDisposedException) catch (ObjectDisposedException) {}
finally
{ {
// Ignore it, no need to reply byContextDequeue(nreq);
nreq = null;
} }
return null; return null;
}, null); }, null);
@ -317,6 +311,4 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
} }
}
} }

View File

@ -50,11 +50,10 @@ namespace OpenSim.Framework.Servers.HttpServer
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
string requestBody;
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader streamReader = new StreamReader(request, encoding); using(StreamReader streamReader = new StreamReader(request,encoding))
requestBody = streamReader.ReadToEnd();
string requestBody = streamReader.ReadToEnd();
streamReader.Close();
string param = GetParam(path); string param = GetParam(path);
string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse); string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse);

View File

@ -42,6 +42,7 @@ namespace OpenSim.Framework.Servers
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static BaseHttpServer instance = null; private static BaseHttpServer instance = null;
private static BaseHttpServer unsecureinstance = null;
private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>(); private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
/// <summary> /// <summary>
@ -93,6 +94,21 @@ namespace OpenSim.Framework.Servers
} }
} }
public static BaseHttpServer UnSecureInstance
{
get { return unsecureinstance; }
set
{
lock (m_Servers)
if (!m_Servers.ContainsValue(value))
throw new Exception("HTTP server must already have been registered to be set as the main instance");
unsecureinstance = value;
}
}
/// <summary> /// <summary>
/// Get all the registered servers. /// Get all the registered servers.
/// </summary> /// </summary>
@ -353,5 +369,17 @@ namespace OpenSim.Framework.Servers
return m_Servers[port]; return m_Servers[port];
} }
} }
public static void Stop()
{
lock (m_Servers)
{
foreach (BaseHttpServer httpServer in m_Servers.Values)
{
httpServer.Stop();
}
}
}
} }
} }

View File

@ -274,18 +274,6 @@ namespace OpenSim.Framework.Servers
"Show thread status. Synonym for \"show threads\"", "Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport())); (string module, string[] args) => Notice(GetThreadsReport()));
m_console.Commands.AddCommand (
"Debug", false, "debug comms set",
"debug comms set serialosdreq true|false",
"Set comms parameters. For debug purposes.",
HandleDebugCommsSet);
m_console.Commands.AddCommand (
"Debug", false, "debug comms status",
"debug comms status",
"Show current debug comms parameters.",
HandleDebugCommsStatus);
m_console.Commands.AddCommand ( m_console.Commands.AddCommand (
"Debug", false, "debug threadpool set", "Debug", false, "debug threadpool set",
"debug threadpool set worker|iocp min|max <n>", "debug threadpool set worker|iocp min|max <n>",
@ -343,47 +331,13 @@ namespace OpenSim.Framework.Servers
public void RegisterCommonComponents(IConfigSource configSource) public void RegisterCommonComponents(IConfigSource configSource)
{ {
IConfig networkConfig = configSource.Configs["Network"]; // IConfig networkConfig = configSource.Configs["Network"];
if (networkConfig != null)
{
WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false);
}
m_serverStatsCollector = new ServerStatsCollector(); m_serverStatsCollector = new ServerStatsCollector();
m_serverStatsCollector.Initialise(configSource); m_serverStatsCollector.Initialise(configSource);
m_serverStatsCollector.Start(); m_serverStatsCollector.Start();
} }
private void HandleDebugCommsStatus(string module, string[] args)
{
Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint);
}
private void HandleDebugCommsSet(string module, string[] args)
{
if (args.Length != 5)
{
Notice("Usage: debug comms set serialosdreq true|false");
return;
}
if (args[3] != "serialosdreq")
{
Notice("Usage: debug comms set serialosdreq true|false");
return;
}
bool setSerializeOsdRequests;
if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests))
return;
WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests;
Notice("serialosdreq is now {0}", setSerializeOsdRequests);
}
private void HandleShowThreadpoolCallsActive(string module, string[] args) private void HandleShowThreadpoolCallsActive(string module, string[] args)
{ {
List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList(); List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList();
@ -928,16 +882,12 @@ namespace OpenSim.Framework.Servers
sb.Append("\n"); sb.Append("\n");
} }
sb.Append("\n"); sb.Append(GetThreadPoolReport());
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting sb.Append("\n");
// zero active threads.
int totalThreads = Process.GetCurrentProcess().Threads.Count; int totalThreads = Process.GetCurrentProcess().Threads.Count;
if (totalThreads > 0) if (totalThreads > 0)
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); sb.AppendFormat("Total process threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
sb.Append(GetThreadPoolReport());
return sb.ToString(); return sb.ToString();
} }
@ -948,15 +898,46 @@ namespace OpenSim.Framework.Servers
/// <returns></returns> /// <returns></returns>
public static string GetThreadPoolReport() public static string GetThreadPoolReport()
{ {
StringBuilder sb = new StringBuilder();
// framework pool is alwasy active
int maxWorkers;
int minWorkers;
int curWorkers;
int maxComp;
int minComp;
int curComp;
try
{
ThreadPool.GetMaxThreads(out maxWorkers, out maxComp);
ThreadPool.GetMinThreads(out minWorkers, out minComp);
ThreadPool.GetAvailableThreads(out curWorkers, out curComp);
curWorkers = maxWorkers - curWorkers;
curComp = maxComp - curComp;
sb.Append("\nFramework main threadpool \n");
sb.AppendFormat("workers: {0} ({1} / {2})\n", curWorkers, maxWorkers, minWorkers);
sb.AppendFormat("Completion: {0} ({1} / {2})\n", curComp, maxComp, minComp);
}
catch { }
if (
Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
|| Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
{
sb.AppendFormat("\nThread pool used: Framework main threadpool\n");
return sb.ToString();
}
string threadPoolUsed = null; string threadPoolUsed = null;
int maxThreads = 0; int maxThreads = 0;
int minThreads = 0; int minThreads = 0;
int allocatedThreads = 0; int allocatedThreads = 0;
int inUseThreads = 0; int inUseThreads = 0;
int waitingCallbacks = 0; int waitingCallbacks = 0;
int completionPortThreads = 0;
StringBuilder sb = new StringBuilder();
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
{ {
STPInfo stpi = Util.GetSmartThreadPoolInfo(); STPInfo stpi = Util.GetSmartThreadPoolInfo();
@ -972,22 +953,10 @@ namespace OpenSim.Framework.Servers
waitingCallbacks = stpi.WaitingCallbacks; waitingCallbacks = stpi.WaitingCallbacks;
} }
} }
else if (
Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
|| Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
{
threadPoolUsed = "BuiltInThreadPool";
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
int availableThreads;
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
inUseThreads = maxThreads - availableThreads;
allocatedThreads = -1;
waitingCallbacks = -1;
}
if (threadPoolUsed != null) if (threadPoolUsed != null)
{ {
sb.Append("\nThreadpool (excluding script engine pools)\n");
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
sb.AppendFormat("Max threads : {0}\n", maxThreads); sb.AppendFormat("Max threads : {0}\n", maxThreads);
sb.AppendFormat("Min threads : {0}\n", minThreads); sb.AppendFormat("Min threads : {0}\n", minThreads);

View File

@ -41,14 +41,5 @@ namespace OpenSim.Framework.Servers.Tests
{ {
Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.Version.Length," VersionInfo.Version string not " + VersionInfo.VERSIONINFO_VERSION_LENGTH + " chars."); Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.Version.Length," VersionInfo.Version string not " + VersionInfo.VERSIONINFO_VERSION_LENGTH + " chars.");
} }
[Test]
public void TestGetVersionStringLength()
{
foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour)))
{
Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", flavour).Length, "0.0.0/" + flavour + " failed");
}
}
} }
} }

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