Merge branch 'master' into 0.9.0-post-fixes

0.9.0-post-fixes
Diva Canto 2017-08-15 10:29:05 -07:00
commit 704c67527b
321 changed files with 30821 additions and 51372 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

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

@ -359,6 +359,42 @@ namespace OpenSim.ApplicationPlugins.RemoteController
notice = false; notice = false;
} }
if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false))
{
m_log.Info("[RADMIN]: Counting affected avatars");
int agents = 0;
if (restartAll)
{
foreach (Scene s in m_application.SceneManager.Scenes)
{
foreach (ScenePresence sp in s.GetScenePresences())
{
if (!sp.IsChildAgent && !sp.IsNPC)
agents++;
}
}
}
else
{
foreach (ScenePresence sp in rebootedScene.GetScenePresences())
{
if (!sp.IsChildAgent && !sp.IsNPC)
agents++;
}
}
m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents);
if (agents == 0)
{
m_log.Info("[RADMIN]: No avatars detected, shutting down without delay");
times.Clear();
times.Add(0);
}
}
List<Scene> restartList; List<Scene> restartList;
if (restartAll) if (restartAll)
@ -376,10 +412,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
} }
catch (Exception e) catch (Exception e)
{ {
// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
responseData["rebooting"] = false; responseData["rebooting"] = false;
throw e; throw;
} }
m_log.Info("[RADMIN]: Restart Region request complete"); m_log.Info("[RADMIN]: Restart Region request complete");
@ -3051,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

@ -362,8 +362,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 +402,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

@ -368,9 +368,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 +409,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

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

@ -157,6 +157,11 @@ 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, (object)i);
}
else else
{ {
field.SetValue(obj, enumerator.Value); field.SetValue(obj, enumerator.Value);

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

@ -36,7 +36,7 @@ using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL namespace OpenSim.Data.MySQL
{ {
/// <summary> /// <summary>
/// A database interface class to a user profile storage system /// Common code for a number of database modules
/// </summary> /// </summary>
public class MySqlFramework public class MySqlFramework
{ {
@ -44,14 +44,24 @@ namespace OpenSim.Data.MySQL
log4net.LogManager.GetLogger( log4net.LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString; protected string m_connectionString = String.Empty;
protected object m_dbLock = new object(); protected MySqlTransaction m_trans = null;
// Constructor using a connection string. Instances constructed
// this way will open a new connection for each call.
protected MySqlFramework(string connectionString) protected MySqlFramework(string connectionString)
{ {
m_connectionString = connectionString; m_connectionString = connectionString;
} }
// Constructor using a connection object. Instances constructed
// this way will use the connection object and never create
// new connections.
protected MySqlFramework(MySqlTransaction trans)
{
m_trans = trans;
}
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// //
// All non queries are funneled through one connection // All non queries are funneled through one connection
@ -59,23 +69,45 @@ namespace OpenSim.Data.MySQL
// //
protected int ExecuteNonQuery(MySqlCommand cmd) protected int ExecuteNonQuery(MySqlCommand cmd)
{ {
lock (m_dbLock) if (m_trans == null)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
int ret = ExecuteNonQueryWithConnection(cmd, dbcon);
dbcon.Close();
return ret;
}
}
else
{
return ExecuteNonQueryWithTransaction(cmd, m_trans);
}
}
private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
{
cmd.Transaction = trans;
return ExecuteNonQueryWithConnection(cmd, trans.Connection);
}
private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
{ {
try try
{ {
dbcon.Open();
cmd.Connection = dbcon; cmd.Connection = dbcon;
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;
} }
} }
@ -86,6 +118,4 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
}
} }

View File

@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; } get { return GetType().Assembly; }
} }
public MySQLGenericTableHandler(MySqlTransaction trans,
string realm, string storeName) : base(trans)
{
m_Realm = realm;
CommonConstruct(storeName);
}
public MySQLGenericTableHandler(string connectionString, public MySQLGenericTableHandler(string connectionString,
string realm, string storeName) : base(connectionString) string realm, string storeName) : base(connectionString)
{ {
m_Realm = realm; m_Realm = realm;
m_connectionString = connectionString;
CommonConstruct(storeName);
}
protected void CommonConstruct(string storeName)
{
if (storeName != String.Empty) if (storeName != String.Empty)
{ {
// We always use a new connection for any Migrations
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -110,6 +123,11 @@ namespace OpenSim.Data.MySQL
} }
public virtual T[] Get(string[] fields, string[] keys) public virtual T[] Get(string[] fields, string[] keys)
{
return Get(fields, keys, String.Empty);
}
public virtual T[] Get(string[] fields, string[] keys, string options)
{ {
if (fields.Length != keys.Length) if (fields.Length != keys.Length)
return new T[0]; return new T[0];
@ -126,8 +144,8 @@ namespace OpenSim.Data.MySQL
string where = String.Join(" and ", terms.ToArray()); string where = String.Join(" and ", terms.ToArray());
string query = String.Format("select * from {0} where {1}", string query = String.Format("select * from {0} where {1} {2}",
m_Realm, where); m_Realm, where, options);
cmd.CommandText = query; cmd.CommandText = query;
@ -137,11 +155,33 @@ namespace OpenSim.Data.MySQL
protected T[] DoQuery(MySqlCommand cmd) protected T[] DoQuery(MySqlCommand cmd)
{ {
List<T> result = new List<T>(); if (m_trans == null)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
T[] ret = DoQueryWithConnection(cmd, dbcon);
dbcon.Close();
return ret;
}
}
else
{
return DoQueryWithTransaction(cmd, m_trans);
}
}
protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
{
cmd.Transaction = trans;
return DoQueryWithConnection(cmd, trans.Connection);
}
protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
{
List<T> result = new List<T>();
cmd.Connection = dbcon; cmd.Connection = dbcon;
using (IDataReader reader = cmd.ExecuteReader()) using (IDataReader reader = cmd.ExecuteReader())
@ -204,8 +244,7 @@ namespace OpenSim.Data.MySQL
result.Add(row); result.Add(row);
} }
} }
} cmd.Connection = null;
return result.ToArray(); return result.ToArray();
} }
@ -356,15 +395,27 @@ namespace OpenSim.Data.MySQL
} }
public object DoQueryScalar(MySqlCommand cmd) public object DoQueryScalar(MySqlCommand cmd)
{
if (m_trans == null)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
cmd.Connection = dbcon; cmd.Connection = dbcon;
Object ret = cmd.ExecuteScalar();
cmd.Connection = null;
dbcon.Close();
return ret;
}
}
else
{
cmd.Connection = m_trans.Connection;
cmd.Transaction = m_trans;
return cmd.ExecuteScalar(); return cmd.ExecuteScalar();
} }
} }
} }
} }

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

@ -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))
{ {
@ -121,58 +122,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,6 +229,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -242,10 +244,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,6 +257,7 @@ 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)
@ -271,10 +271,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
{ {
@ -322,10 +320,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,6 +348,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -364,12 +361,8 @@ namespace OpenSim.Data.MySQL
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
{ {
@ -422,33 +415,33 @@ namespace OpenSim.Data.MySQL
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,6 +467,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -487,10 +481,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,6 +495,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -519,11 +511,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,6 +536,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -560,26 +549,25 @@ namespace OpenSim.Data.MySQL
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,6 +584,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -612,10 +601,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 +650,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,6 +706,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -733,15 +721,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,6 +742,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -775,15 +759,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
{ {
@ -817,18 +799,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 +828,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 +847,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(string.Format (queryB,"`userpicks`"), dbcon))
{ {
cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
@ -884,6 +865,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -897,11 +879,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 +903,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,6 +916,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -953,13 +931,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,6 +949,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -991,11 +966,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 +988,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,6 +1001,7 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)
@ -1049,14 +1016,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,6 +1032,7 @@ namespace OpenSim.Data.MySQL
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
dbcon.Close();
} }
} }
catch (Exception e) catch (Exception e)

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

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

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

@ -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,112 @@
: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 9
BEGIN TRANSACTION;
CREATE TABLE Tmp_estate_map
(
"RegionID" uuid NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'),
"EstateID" int NOT NULL
);
INSERT INTO Tmp_estate_map ("RegionID", "EstateID")
SELECT cast("RegionID" as uuid), "EstateID" FROM estate_map ;
DROP TABLE estate_map;
Alter table Tmp_estate_map
rename to estate_map;
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

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

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

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

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

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

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

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

@ -47,8 +47,9 @@ namespace OpenSim.Framework
/// Get an asset by its id. /// Get an asset by its id.
/// </summary> /// </summary>
/// <param name='id'></param> /// <param name='id'></param>
/// <returns>null if the asset does not exist.</returns> /// <param name='asset'>Will be set to null if no asset was found</param>
AssetBase Get(string id); /// <returns>False if the asset has been negative-cached</returns>
bool Get(string id, out AssetBase asset);
/// <summary> /// <summary>
/// Check whether an asset with the specified id exists in the cache. /// Check whether an asset with the specified id exists in the cache.

View File

@ -107,7 +107,7 @@ namespace OpenSim.Framework
public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); public delegate void GenericCall4(Packet packet, IClientAPI remoteClient);
public delegate void DeRezObject( public delegate void DeRezObject(
IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID); IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true);
public delegate void GenericCall5(IClientAPI remoteClient, bool status); public delegate void GenericCall5(IClientAPI remoteClient, bool status);
@ -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
@ -1112,7 +1113,7 @@ namespace OpenSim.Framework
/// <param name="localID"></param> /// <param name="localID"></param>
void SendKillObject(List<uint> localID); void SendKillObject(List<uint> localID);
void SendPartFullUpdate(ISceneEntity ent, uint? parentID); // void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
@ -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.

View File

@ -76,6 +76,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 +88,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);

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

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

@ -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.
@ -82,16 +83,15 @@ namespace OpenSim.Framework.Monitoring
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))
{
lock(JobLock)
m_threadRunnig = false;
break;
}
} }
catch(ObjectDisposedException e) catch(ObjectDisposedException e)
{
// If we see this whilst not running then it may be due to a race where this thread checks
// IsRunning after the stopping thread sets it to false and disposes of the cancellation source.
if(IsRunning)
throw e;
else
{ {
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

@ -47,6 +47,8 @@ namespace OpenSim.Framework.Monitoring
// Subcommand used to list other stats. // Subcommand used to list other stats.
public const string ListSubCommand = "list"; public const string ListSubCommand = "list";
public static string StatsPassword { get; set; }
// All subcommands // All subcommands
public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand }; public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand };
@ -302,6 +304,17 @@ namespace OpenSim.Framework.Monitoring
int response_code = 200; int response_code = 200;
string contenttype = "text/json"; string contenttype = "text/json";
if (StatsPassword != String.Empty && (!request.ContainsKey("pass") || request["pass"].ToString() != StatsPassword))
{
responsedata["int_response_code"] = response_code;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Access denied";
responsedata["access_control_allow_origin"] = "*";
return responsedata;
}
string pCategoryName = StatsManager.AllSubCommand; string pCategoryName = StatsManager.AllSubCommand;
string pContainerName = StatsManager.AllSubCommand; string pContainerName = StatsManager.AllSubCommand;
string pStatName = StatsManager.AllSubCommand; string pStatName = StatsManager.AllSubCommand;

View File

@ -180,6 +180,30 @@ 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;
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 +254,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 +339,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 +358,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

@ -212,7 +212,17 @@ namespace OpenSim.Framework
// Check that we are permitted to make calls to this endpoint. // Check that we are permitted to make calls to this endpoint.
bool foundIpv4Address = false; bool foundIpv4Address = false;
IPAddress[] addresses = Dns.GetHostAddresses(url.Host); IPAddress[] addresses = null;
try
{
addresses = Dns.GetHostAddresses(url.Host);
}
catch
{
// If there is a DNS error, we can't stop the script!
return true;
}
foreach (IPAddress addr in addresses) foreach (IPAddress addr in addresses)
{ {

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,262 @@
/*
* 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;
UTF8Encoding enc = new UTF8Encoding();
MemoryStream ms = new MemoryStream(enc.GetBytes(text));
XmlTextReader xreader = new XmlTextReader(ms);
PhysicsInertiaData v = new PhysicsInertiaData();
bool error;
v.FromXml2(xreader, out error);
xreader.Close();
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,70 @@ 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;
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 = 1;
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 = 1;
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 = 1;
break;
default: // 8 faces box with cut
shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle;
shape.PathCurve = (byte)Extrusion.Straight;
shape.ProfileBegin = 1;
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 +1580,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 +1602,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

@ -130,7 +130,7 @@ namespace OpenSim.Framework
private float m_physPrimMin = 0; private float m_physPrimMin = 0;
private int m_physPrimMax = 0; private int m_physPrimMax = 0;
private bool m_clampPrimSize = false; private bool m_clampPrimSize = false;
private int m_objectCapacity = 0; private int m_objectCapacity = 15000;
private int m_maxPrimsPerUser = -1; private int m_maxPrimsPerUser = -1;
private int m_linksetCapacity = 0; private int m_linksetCapacity = 0;
private string m_regionType = String.Empty; private string m_regionType = String.Empty;
@ -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(); }
} }
@ -753,7 +719,7 @@ namespace OpenSim.Framework
m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
allKeys.Remove("ClampPrimSize"); allKeys.Remove("ClampPrimSize");
m_objectCapacity = config.GetInt("MaxPrims", 15000); m_objectCapacity = config.GetInt("MaxPrims", m_objectCapacity);
allKeys.Remove("MaxPrims"); allKeys.Remove("MaxPrims");
m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1); m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1);

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

@ -108,11 +108,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 +171,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

@ -399,11 +399,10 @@ namespace OpenSim.Framework.Servers.HttpServer
Stream requestStream = req.InputStream; Stream requestStream = req.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();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -567,13 +566,10 @@ namespace OpenSim.Framework.Servers.HttpServer
IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler;
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();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -690,7 +686,8 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
request.InputStream.Close(); if(request.InputStream.CanRead)
request.InputStream.Dispose();
if (buffer != null) if (buffer != null)
{ {
@ -998,7 +995,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,9 +1006,8 @@ 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
{ {
@ -1263,12 +1259,10 @@ 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; response.KeepAlive = true;
@ -1592,15 +1586,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();
@ -1838,7 +1827,7 @@ namespace OpenSim.Framework.Servers.HttpServer
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;
@ -2028,6 +2017,7 @@ namespace OpenSim.Framework.Servers.HttpServer
try try
{ {
if(PollServiceRequestManager != null)
PollServiceRequestManager.Stop(); PollServiceRequestManager.Stop();
m_httpListener2.ExceptionThrown -= httpServerException; m_httpListener2.ExceptionThrown -= httpServerException;

View File

@ -50,7 +50,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public enum EventType : int public enum EventType : int
{ {
LongPoll = 0, Poll = 0,
LslHttp = 1, LslHttp = 1,
Inventory = 2, Inventory = 2,
Texture = 3, Texture = 3,
@ -82,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer
NoEvents = pNoEvents; NoEvents = pNoEvents;
Id = pId; Id = pId;
TimeOutms = pTimeOutms; TimeOutms = pTimeOutms;
Type = EventType.LongPoll; Type = EventType.Poll;
} }
} }
} }

View File

@ -82,6 +82,9 @@ 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;
@ -107,6 +110,9 @@ 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;

View File

@ -48,7 +48,6 @@ namespace OpenSim.Framework.Servers.HttpServer
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext; private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
private uint m_WorkerThreadCount = 0; private uint m_WorkerThreadCount = 0;
@ -56,11 +55,9 @@ namespace OpenSim.Framework.Servers.HttpServer
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)
{ {
@ -80,7 +77,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 +91,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,7 +101,7 @@ 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);
@ -163,18 +159,8 @@ namespace OpenSim.Framework.Servers.HttpServer
public void EnqueueInt(PollServiceHttpRequest req) public void EnqueueInt(PollServiceHttpRequest req)
{ {
if (m_running) if (m_running)
{
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
{
m_requests.Enqueue(req); m_requests.Enqueue(req);
} }
else
{
lock (m_slowRequests)
m_slowRequests.Enqueue(req);
}
}
}
private void CheckRetries() private void CheckRetries()
{ {
@ -188,17 +174,6 @@ namespace OpenSim.Framework.Servers.HttpServer
while (m_retryRequests.Count > 0 && m_running) while (m_retryRequests.Count > 0 && m_running)
m_requests.Enqueue(m_retryRequests.Dequeue()); 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,11 +181,13 @@ 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)
@ -229,22 +206,15 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
PollServiceHttpRequest wreq; PollServiceHttpRequest wreq;
m_retryRequests.Clear(); m_retryRequests.Clear();
lock (m_slowRequests)
{
while (m_slowRequests.Count > 0)
m_requests.Enqueue(m_slowRequests.Dequeue());
}
while (m_requests.Count() > 0) while (m_requests.Count() > 0)
{ {
try try
{ {
wreq = m_requests.Dequeue(0); wreq = m_requests.Dequeue(0);
wreq.DoHTTPstop(m_server); wreq.DoHTTPstop(m_server);
} }
catch catch
{ {
@ -260,8 +230,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
while (m_running) while (m_running)
{ {
PollServiceHttpRequest req = m_requests.Dequeue(5000); PollServiceHttpRequest req = m_requests.Dequeue(4500);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
if (req != null) if (req != null)
{ {
@ -276,11 +245,13 @@ namespace OpenSim.Framework.Servers.HttpServer
try try
{ {
req.DoHTTPGruntWork(m_server, responsedata); req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
} }
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream catch (ObjectDisposedException)
{ {
// Ignore it, no need to reply }
finally
{
byContextDequeue(req);
} }
return null; return null;
}, null); }, null);
@ -295,12 +266,15 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
req.DoHTTPGruntWork(m_server, req.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
byContextDequeue(req);
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
// Ignore it, no need to reply // Ignore it, no need to reply
} }
finally
{
byContextDequeue(req);
}
return null; return null;
}, null); }, null);
} }

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

@ -353,5 +353,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

@ -57,6 +57,7 @@ namespace OpenSim.Framework.Servers
protected OpenSimAppender m_consoleAppender; protected OpenSimAppender m_consoleAppender;
protected FileAppender m_logFileAppender; protected FileAppender m_logFileAppender;
protected FileAppender m_statsLogFileAppender;
protected DateTime m_startuptime; protected DateTime m_startuptime;
protected string m_startupDirectory = Environment.CurrentDirectory; protected string m_startupDirectory = Environment.CurrentDirectory;
@ -156,6 +157,10 @@ namespace OpenSim.Framework.Servers
{ {
m_logFileAppender = (FileAppender)appender; m_logFileAppender = (FileAppender)appender;
} }
else if (appender.Name == "StatsLogFileAppender")
{
m_statsLogFileAppender = (FileAppender)appender;
}
} }
if (null == m_consoleAppender) if (null == m_consoleAppender)
@ -185,6 +190,18 @@ namespace OpenSim.Framework.Servers
m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File); m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File);
} }
if (m_statsLogFileAppender != null && startupConfig != null)
{
string cfgStatsFileName = startupConfig.GetString("StatsLogFile", null);
if (cfgStatsFileName != null)
{
m_statsLogFileAppender.File = cfgStatsFileName;
m_statsLogFileAppender.ActivateOptions();
}
m_log.InfoFormat("[SERVER BASE]: Stats Logging started to file {0}", m_statsLogFileAppender.File);
}
} }
/// <summary> /// <summary>
@ -257,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>",
@ -326,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();
@ -911,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();
} }
@ -931,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();
@ -955,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

@ -63,22 +63,37 @@ namespace OpenSim.Framework
None = 0, None = 0,
// folded perms // folded perms
foldedTransfer = 1, FoldedTransfer = 1,
foldedModify = 1 << 1, FoldedModify = 1 << 1,
foldedCopy = 1 << 2, FoldedCopy = 1 << 2,
FoldedExport = 1 << 3,
foldedMask = 0x07, // DO NOT USE THIS FOR NEW WORK. IT IS DEPRECATED AND
// EXISTS ONLY TO REACT TO EXISTING OBJECTS HAVING IT.
// NEW CODE SHOULD NEVER SET THIS BIT!
// Use InventoryItemFlags.ObjectSlamPerm in the Flags field of
// this legacy slam bit. It comes from prior incomplete
// understanding of the code and the prohibition on
// reading viewer code that used to be in place.
Slam = (1 << 4),
// FoldedMask = 0x0f,
Transfer = 1 << 13,
Modify = 1 << 14, FoldingShift = 13 , // number of bit shifts from normal perm to folded or back (same as Transfer shift below)
Copy = 1 << 15, // when doing as a block
Export = 1 << 16,
Move = 1 << 19, Transfer = 1 << 13, // 0x02000
Damage = 1 << 20, Modify = 1 << 14, // 0x04000
Copy = 1 << 15, // 0x08000
Export = 1 << 16, // 0x10000
Move = 1 << 19, // 0x80000
Damage = 1 << 20, // 0x100000 does not seem to be in use
// All does not contain Export, which is special and must be // All does not contain Export, which is special and must be
// explicitly given // explicitly given
All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19) All = 0x8e000,
AllAndExport = 0x9e000,
AllEffective = 0x9e000,
UnfoldedMask = 0x1e000
} }
/// <summary> /// <summary>
@ -141,12 +156,14 @@ namespace OpenSim.Framework
public static readonly int MAX_THREADPOOL_LEVEL = 3; public static readonly int MAX_THREADPOOL_LEVEL = 3;
public static double TimeStampClockPeriodMS; public static double TimeStampClockPeriodMS;
public static double TimeStampClockPeriod;
static Util() static Util()
{ {
LogThreadPool = 0; LogThreadPool = 0;
LogOverloads = true; LogOverloads = true;
TimeStampClockPeriodMS = 1000.0D / (double)Stopwatch.Frequency; TimeStampClockPeriod = 1.0D/ (double)Stopwatch.Frequency;
TimeStampClockPeriodMS = 1e3 * TimeStampClockPeriod;
m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero)); m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero));
} }
@ -414,6 +431,7 @@ namespace OpenSim.Framework
return regionCoord << 8; return regionCoord << 8;
} }
public static bool checkServiceURI(string uristr, out string serviceURI) public static bool checkServiceURI(string uristr, out string serviceURI)
{ {
serviceURI = string.Empty; serviceURI = string.Empty;
@ -975,6 +993,8 @@ namespace OpenSim.Framework
return output.ToString(); return output.ToString();
} }
private static ExpiringCache<string,IPAddress> dnscache = new ExpiringCache<string, IPAddress>();
/// <summary> /// <summary>
/// Converts a URL to a IPAddress /// Converts a URL to a IPAddress
/// </summary> /// </summary>
@ -992,40 +1012,130 @@ namespace OpenSim.Framework
/// <returns>An IP address, or null</returns> /// <returns>An IP address, or null</returns>
public static IPAddress GetHostFromDNS(string dnsAddress) public static IPAddress GetHostFromDNS(string dnsAddress)
{ {
// Is it already a valid IP? No need to look it up. if(String.IsNullOrWhiteSpace(dnsAddress))
IPAddress ipa; return null;
if (IPAddress.TryParse(dnsAddress, out ipa))
return ipa;
IPAddress[] hosts = null; IPAddress ia = null;
if(dnscache.TryGetValue(dnsAddress, out ia) && ia != null)
{
dnscache.AddOrUpdate(dnsAddress, ia, 300);
return ia;
}
// Not an IP, lookup required ia = null;
// If it is already an IP, don't let GetHostEntry see it
if (IPAddress.TryParse(dnsAddress, out ia) && ia != null)
{
if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any))
return null;
dnscache.AddOrUpdate(dnsAddress, ia, 300);
return ia;
}
IPHostEntry IPH;
try try
{ {
hosts = Dns.GetHostEntry(dnsAddress).AddressList; IPH = Dns.GetHostEntry(dnsAddress);
} }
catch (Exception e) catch // (SocketException e)
{ {
m_log.WarnFormat("[UTIL]: An error occurred while resolving host name {0}, {1}", dnsAddress, e);
// Still going to throw the exception on for now, since this was what was happening in the first place
throw e;
}
foreach (IPAddress host in hosts)
{
if (host.AddressFamily == AddressFamily.InterNetwork)
{
return host;
}
}
if (hosts.Length > 0)
return hosts[0];
return null; return null;
} }
if(IPH == null || IPH.AddressList.Length == 0)
return null;
ia = null;
foreach (IPAddress Adr in IPH.AddressList)
{
if (ia == null)
ia = Adr;
if (Adr.AddressFamily == AddressFamily.InterNetwork)
{
ia = Adr;
break;
}
}
if(ia != null)
dnscache.AddOrUpdate(dnsAddress, ia, 300);
return ia;
}
public static IPEndPoint getEndPoint(IPAddress ia, int port)
{
if(ia == null)
return null;
IPEndPoint newEP = null;
try
{
newEP = new IPEndPoint(ia, port);
}
catch
{
newEP = null;
}
return newEP;
}
public static IPEndPoint getEndPoint(string hostname, int port)
{
if(String.IsNullOrWhiteSpace(hostname))
return null;
IPAddress ia = null;
if(dnscache.TryGetValue(hostname, out ia) && ia != null)
{
dnscache.AddOrUpdate(hostname, ia, 300);
return getEndPoint(ia, port);
}
ia = null;
// If it is already an IP, don't let GetHostEntry see it
if (IPAddress.TryParse(hostname, out ia) && ia != null)
{
if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any))
return null;
dnscache.AddOrUpdate(hostname, ia, 300);
return getEndPoint(ia, port);
}
IPHostEntry IPH;
try
{
IPH = Dns.GetHostEntry(hostname);
}
catch // (SocketException e)
{
return null;
}
if(IPH == null || IPH.AddressList.Length == 0)
return null;
ia = null;
foreach (IPAddress Adr in IPH.AddressList)
{
if (ia == null)
ia = Adr;
if (Adr.AddressFamily == AddressFamily.InterNetwork)
{
ia = Adr;
break;
}
}
if(ia != null)
dnscache.AddOrUpdate(hostname, ia, 300);
return getEndPoint(ia,port);
}
public static Uri GetURI(string protocol, string hostname, int port, string path) public static Uri GetURI(string protocol, string hostname, int port, string path)
{ {
return new UriBuilder(protocol, hostname, port, path).Uri; return new UriBuilder(protocol, hostname, port, path).Uri;
@ -1180,7 +1290,7 @@ namespace OpenSim.Framework
{ {
foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) foreach (IAppender appender in LogManager.GetRepository().GetAppenders())
{ {
if (appender is FileAppender) if (appender is FileAppender && appender.Name == "LogFileAppender")
{ {
return ((FileAppender)appender).File; return ((FileAppender)appender).File;
} }
@ -1189,6 +1299,19 @@ namespace OpenSim.Framework
return "./OpenSim.log"; return "./OpenSim.log";
} }
public static string statsLogFile()
{
foreach (IAppender appender in LogManager.GetRepository().GetAppenders())
{
if (appender is FileAppender && appender.Name == "StatsLogFileAppender")
{
return ((FileAppender)appender).File;
}
}
return "./OpenSimStats.log";
}
public static string logDir() public static string logDir()
{ {
return Path.GetDirectoryName(logFile()); return Path.GetDirectoryName(logFile());
@ -2100,9 +2223,9 @@ namespace OpenSim.Framework
// might have gotten an oversized array even after the string trim // might have gotten an oversized array even after the string trim
byte[] data = UTF8.GetBytes(str); byte[] data = UTF8.GetBytes(str);
if (data.Length > 256) if (data.Length > 255) //play safe
{ {
int cut = 255; int cut = 254;
if((data[cut] & 0x80 ) != 0 ) if((data[cut] & 0x80 ) != 0 )
{ {
while(cut > 0 && (data[cut] & 0xc0) != 0xc0) while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
@ -2204,7 +2327,7 @@ namespace OpenSim.Framework
if (data.Length > MaxLength) if (data.Length > MaxLength)
{ {
int cut = MaxLength -1 ; int cut = MaxLength - 1 ;
if((data[cut] & 0x80 ) != 0 ) if((data[cut] & 0x80 ) != 0 )
{ {
while(cut > 0 && (data[cut] & 0xc0) != 0xc0) while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
@ -2371,8 +2494,9 @@ namespace OpenSim.Framework
public bool Running { get; set; } public bool Running { get; set; }
public bool Aborted { get; set; } public bool Aborted { get; set; }
private int started; private int started;
public bool DoTimeout;
public ThreadInfo(long threadFuncNum, string context) public ThreadInfo(long threadFuncNum, string context, bool dotimeout = true)
{ {
ThreadFuncNum = threadFuncNum; ThreadFuncNum = threadFuncNum;
this.context = context; this.context = context;
@ -2380,6 +2504,7 @@ namespace OpenSim.Framework
Thread = null; Thread = null;
Running = false; Running = false;
Aborted = false; Aborted = false;
DoTimeout = dotimeout;
} }
public void Started() public void Started()
@ -2450,7 +2575,7 @@ namespace OpenSim.Framework
foreach (KeyValuePair<long, ThreadInfo> entry in activeThreads) foreach (KeyValuePair<long, ThreadInfo> entry in activeThreads)
{ {
ThreadInfo t = entry.Value; ThreadInfo t = entry.Value;
if (t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT)) if (t.DoTimeout && t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT))
{ {
m_log.WarnFormat("Timeout in threadfunc {0} ({1}) {2}", t.ThreadFuncNum, t.Thread.Name, t.GetStackTrace()); m_log.WarnFormat("Timeout in threadfunc {0} ({1}) {2}", t.ThreadFuncNum, t.Thread.Name, t.GetStackTrace());
t.Abort(); t.Abort();
@ -2491,10 +2616,10 @@ namespace OpenSim.Framework
FireAndForget(callback, obj, null); FireAndForget(callback, obj, null);
} }
public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context, bool dotimeout = true)
{ {
Interlocked.Increment(ref numTotalThreadFuncsCalled); Interlocked.Increment(ref numTotalThreadFuncsCalled);
/*
if (context != null) if (context != null)
{ {
if (!m_fireAndForgetCallsMade.ContainsKey(context)) if (!m_fireAndForgetCallsMade.ContainsKey(context))
@ -2507,13 +2632,13 @@ namespace OpenSim.Framework
else else
m_fireAndForgetCallsInProgress[context]++; m_fireAndForgetCallsInProgress[context]++;
} }
*/
WaitCallback realCallback; WaitCallback realCallback;
bool loggingEnabled = LogThreadPool > 0; bool loggingEnabled = LogThreadPool > 0;
long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum); long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum);
ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context); ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context, dotimeout);
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
{ {
@ -2524,8 +2649,8 @@ namespace OpenSim.Framework
Culture.SetCurrentCulture(); Culture.SetCurrentCulture();
callback(o); callback(o);
if (context != null) // if (context != null)
m_fireAndForgetCallsInProgress[context]--; // m_fireAndForgetCallsInProgress[context]--;
}; };
} }
else else
@ -2551,7 +2676,6 @@ namespace OpenSim.Framework
} }
catch (ThreadAbortException e) catch (ThreadAbortException e)
{ {
m_log.Error(string.Format("Aborted threadfunc {0} ", threadFuncNum), e);
} }
catch (Exception e) catch (Exception e)
{ {
@ -2566,8 +2690,8 @@ namespace OpenSim.Framework
if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed()));
if (context != null) // if (context != null)
m_fireAndForgetCallsInProgress[context]--; // m_fireAndForgetCallsInProgress[context]--;
} }
}; };
} }
@ -2824,6 +2948,16 @@ namespace OpenSim.Framework
return stpi; return stpi;
} }
public static void StopThreadPool()
{
if (m_ThreadPool == null)
return;
SmartThreadPool pool = m_ThreadPool;
m_ThreadPool = null;
try { pool.Shutdown(); } catch {}
}
#endregion FireAndForget Threading Pattern #endregion FireAndForget Threading Pattern
/// <summary> /// <summary>
@ -2837,6 +2971,7 @@ namespace OpenSim.Framework
{ {
return Environment.TickCount & EnvironmentTickCountMask; return Environment.TickCount & EnvironmentTickCountMask;
} }
const Int32 EnvironmentTickCountMask = 0x3fffffff; const Int32 EnvironmentTickCountMask = 0x3fffffff;
/// <summary> /// <summary>
@ -2883,6 +3018,11 @@ namespace OpenSim.Framework
// returns a timestamp in ms as double // returns a timestamp in ms as double
// using the time resolution avaiable to StopWatch // using the time resolution avaiable to StopWatch
public static double GetTimeStamp()
{
return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriod;
}
public static double GetTimeStampMS() public static double GetTimeStampMS()
{ {
return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS; return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS;

View File

@ -113,7 +113,8 @@ namespace OpenSim.Framework
{ {
if (dataCache.Check(item.TextureID.ToString())) if (dataCache.Check(item.TextureID.ToString()))
{ {
AssetBase assetItem = dataCache.Get(item.TextureID.ToString()); AssetBase assetItem;
dataCache.Get(item.TextureID.ToString(), out assetItem);
if (assetItem != null) if (assetItem != null)
{ {
itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data)); itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data));

View File

@ -71,11 +71,6 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public static int RequestNumber { get; set; } public static int RequestNumber { get; set; }
/// <summary>
/// Control where OSD requests should be serialized per endpoint.
/// </summary>
public static bool SerializeOSDRequestsPerEndpoint { get; set; }
/// <summary> /// <summary>
/// this is the header field used to communicate the local request id /// this is the header field used to communicate the local request id
/// used for performance and debugging /// used for performance and debugging
@ -98,31 +93,6 @@ namespace OpenSim.Framework
/// </remarks> /// </remarks>
public const int MaxRequestDiagLength = 200; public const int MaxRequestDiagLength = 200;
/// <summary>
/// Dictionary of end points
/// </summary>
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
private static object EndPointLock(string url)
{
System.Uri uri = new System.Uri(url);
string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port);
lock (m_endpointSerializer)
{
object eplock = null;
if (! m_endpointSerializer.TryGetValue(endpoint,out eplock))
{
eplock = new object();
m_endpointSerializer.Add(endpoint,eplock);
// m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
}
return eplock;
}
}
#region JSONRequest #region JSONRequest
/// <summary> /// <summary>
@ -154,21 +124,6 @@ namespace OpenSim.Framework
return ServiceOSDRequest(url, null, "GET", timeout, false, false); return ServiceOSDRequest(url, null, "GET", timeout, false, false);
} }
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc)
{
if (SerializeOSDRequestsPerEndpoint)
{
lock (EndPointLock(url))
{
return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc);
}
}
else
{
return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc);
}
}
public static void LogOutgoingDetail(Stream outputStream) public static void LogOutgoingDetail(Stream outputStream)
{ {
LogOutgoingDetail("", outputStream); LogOutgoingDetail("", outputStream);
@ -222,7 +177,7 @@ namespace OpenSim.Framework
LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input); LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input);
} }
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc)
{ {
int reqnum = RequestNumber++; int reqnum = RequestNumber++;
@ -421,14 +376,6 @@ namespace OpenSim.Framework
} }
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
{
lock (EndPointLock(url))
{
return ServiceFormRequestWorker(url,data,timeout);
}
}
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
{ {
int reqnum = RequestNumber++; int reqnum = RequestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
@ -1315,18 +1262,24 @@ namespace OpenSim.Framework
{ {
if (hwr.StatusCode == HttpStatusCode.NotFound) if (hwr.StatusCode == HttpStatusCode.NotFound)
return deserial; return deserial;
if (hwr.StatusCode == HttpStatusCode.Unauthorized) if (hwr.StatusCode == HttpStatusCode.Unauthorized)
{ {
m_log.Error(string.Format( m_log.ErrorFormat("[SynchronousRestObjectRequester]: Web request {0} requires authentication",
"[SynchronousRestObjectRequester]: Web request {0} requires authentication ", requestUrl);
requestUrl)); }
return deserial; else
{
m_log.WarnFormat("[SynchronousRestObjectRequester]: Web request {0} returned error: {1}",
requestUrl, hwr.StatusCode);
} }
} }
else else
m_log.Error(string.Format( m_log.ErrorFormat(
"[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ", "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} {3}",
verb, requestUrl, typeof(TResponse).ToString()), e); verb, requestUrl, typeof(TResponse).ToString(), e.Message);
return deserial;
} }
} }
catch (System.InvalidOperationException) catch (System.InvalidOperationException)

View File

@ -74,7 +74,15 @@ namespace OpenSim
AppDomain.CurrentDomain.UnhandledException += AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
if(Util.IsWindows())
ServicePointManager.DefaultConnectionLimit = 32;
else
{
ServicePointManager.DefaultConnectionLimit = 12; ServicePointManager.DefaultConnectionLimit = 12;
}
try { ServicePointManager.DnsRefreshTimeout = 300000; } catch { }
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = false; ServicePointManager.UseNagleAlgorithm = false;
// Add the arguments supplied when running the application to the configuration // Add the arguments supplied when running the application to the configuration

View File

@ -33,6 +33,7 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Timers; using System.Timers;
@ -124,8 +125,11 @@ namespace OpenSim
Util.InitThreadPool(stpMinThreads, stpMaxThreads); Util.InitThreadPool(stpMinThreads, stpMaxThreads);
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
m_log.InfoFormat("[OPENSIM MAIN] Running GC in {0} mode", GCSettings.IsServerGC ? "server":"workstation");
} }
#if (_MONO)
private static Mono.Unix.UnixSignal[] signals; private static Mono.Unix.UnixSignal[] signals;
@ -140,6 +144,7 @@ namespace OpenSim
MainConsole.Instance.RunCommand("shutdown"); MainConsole.Instance.RunCommand("shutdown");
} }
}); });
#endif
/// <summary> /// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk. /// Performs initialisation of the scene, such as loading configuration from disk.
@ -150,6 +155,7 @@ namespace OpenSim
m_log.Info("========================= STARTING OPENSIM ========================="); m_log.Info("========================= STARTING OPENSIM =========================");
m_log.Info("===================================================================="); m_log.Info("====================================================================");
#if (_MONO)
if(!Util.IsWindows()) if(!Util.IsWindows())
{ {
try try
@ -159,6 +165,7 @@ namespace OpenSim
{ {
new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM)
}; };
signal_thread.IsBackground = true;
signal_thread.Start(); signal_thread.Start();
} }
catch (Exception e) catch (Exception e)
@ -168,6 +175,7 @@ namespace OpenSim
m_log.Debug("Exception was: ", e); m_log.Debug("Exception was: ", e);
} }
} }
#endif
//m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
// http://msdn.microsoft.com/en-us/library/bb384202.aspx // http://msdn.microsoft.com/en-us/library/bb384202.aspx
//GCSettings.LatencyMode = GCLatencyMode.Batch; //GCSettings.LatencyMode = GCLatencyMode.Batch;
@ -211,6 +219,7 @@ namespace OpenSim
if (managedStatsURI != String.Empty) if (managedStatsURI != String.Empty)
{ {
string urlBase = String.Format("/{0}/", managedStatsURI); string urlBase = String.Format("/{0}/", managedStatsURI);
StatsManager.StatsPassword = managedStatsPassword;
MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest); MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest);
m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase); m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase);
} }
@ -477,6 +486,12 @@ namespace OpenSim
RunCommandScript(m_shutdownCommandsFile); RunCommandScript(m_shutdownCommandsFile);
} }
if (m_timedScript != "disabled")
{
m_scriptTimer.Dispose();
m_timedScript = "disabled";
}
base.ShutdownSpecific(); base.ShutdownSpecific();
} }
@ -496,7 +511,6 @@ namespace OpenSim
private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi) private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
{ {
int now = Environment.TickCount & Int32.MaxValue; int now = Environment.TickCount & Int32.MaxValue;
m_log.ErrorFormat( m_log.ErrorFormat(
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}", "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
twi.Thread.Name, twi.Thread.Name,

View File

@ -88,6 +88,7 @@ namespace OpenSim
public string userStatsURI = String.Empty; public string userStatsURI = String.Empty;
public string managedStatsURI = String.Empty; public string managedStatsURI = String.Empty;
public string managedStatsPassword = String.Empty;
protected bool m_autoCreateClientStack = true; protected bool m_autoCreateClientStack = true;
@ -236,9 +237,10 @@ namespace OpenSim
string permissionModules = Util.GetConfigVarFromSections<string>(Config, "permissionmodules", string permissionModules = Util.GetConfigVarFromSections<string>(Config, "permissionmodules",
new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
m_permsModules = new List<string>(permissionModules.Split(',')); m_permsModules = new List<string>(permissionModules.Split(',').Select(m => m.Trim()));
managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty); managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty);
managedStatsPassword = startupConfig.GetString("ManagedStatsRemoteFetchPassword", String.Empty);
} }
// Load the simulation data service // Load the simulation data service
@ -459,15 +461,14 @@ namespace OpenSim
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
SetUpEstateOwner(scene); SetUpEstateOwner(scene);
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
// Prims have to be loaded after module configuration since some modules may be invoked during the load // Prims have to be loaded after module configuration since some modules may be invoked during the load
scene.LoadPrimsFromStorage(regionInfo.originRegionID); scene.LoadPrimsFromStorage(regionInfo.originRegionID);
// TODO : Try setting resource for region xstats here on scene // TODO : Try setting resource for region xstats here on scene
MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo)); MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
scene.EventManager.TriggerParcelPrimCountUpdate();
if (scene.SnmpService != null) if (scene.SnmpService != null)
{ {
scene.SnmpService.BootInfo("Grid Registration in progress", scene); scene.SnmpService.BootInfo("Grid Registration in progress", scene);

View File

@ -946,17 +946,26 @@ namespace OpenSim.Region.ClientStack.Linden
continue; continue;
} }
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
PrimitiveBaseShape pbs = null;
if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
{
int meshindx = inner_instance_list["mesh"].AsInteger();
if (meshAssets.Count > meshindx)
pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]);
}
if(pbs == null) // fallback
pbs = PrimitiveBaseShape.CreateBox();
Primitive.TextureEntry textureEntry Primitive.TextureEntry textureEntry
= new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
for (uint face = 0; face < face_list.Count; face++) for (uint face = 0; face < face_list.Count; face++)
{ {
OSDMap faceMap = (OSDMap)face_list[(int)face]; OSDMap faceMap = (OSDMap)face_list[(int)face];
Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
Primitive.TextureEntryFace f = textureEntry.CreateFace(face); //clone the default
if (faceMap.ContainsKey("fullbright")) if (faceMap.ContainsKey("fullbright"))
f.Fullbright = faceMap["fullbright"].AsBoolean(); f.Fullbright = faceMap["fullbright"].AsBoolean();
if (faceMap.ContainsKey("diffuse_color")) if (faceMap.ContainsKey("diffuse_color"))
@ -986,51 +995,11 @@ namespace OpenSim.Region.ClientStack.Linden
if (textures.Count > textureNum) if (textures.Count > textureNum)
f.TextureID = textures[textureNum]; f.TextureID = textures[textureNum];
else
f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
textureEntry.FaceTextures[face] = f; textureEntry.FaceTextures[face] = f;
} }
pbs.TextureEntry = textureEntry.GetBytes(); pbs.TextureEntry = textureEntry.GetBytes();
if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
{
int meshindx = inner_instance_list["mesh"].AsInteger();
if (meshAssets.Count > meshindx)
{
pbs.SculptEntry = true;
pbs.SculptType = (byte)SculptType.Mesh;
pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
// data will be requested from asset on rez (i hope)
}
}
// faces number to pbs shape
switch(face_list.Count)
{
case 1:
case 2:
pbs.ProfileCurve = (byte)ProfileCurve.Circle;
pbs.PathCurve = (byte)PathCurve.Circle;
break;
case 3:
case 4:
pbs.ProfileCurve = (byte)ProfileCurve.Circle;
pbs.PathCurve = (byte)PathCurve.Line;
break;
case 5:
pbs.ProfileCurve = (byte)ProfileCurve.EqualTriangle;
pbs.PathCurve = (byte)PathCurve.Line;
break;
default:
pbs.ProfileCurve = (byte)ProfileCurve.Square;
pbs.PathCurve = (byte)PathCurve.Line;
break;
}
Vector3 position = inner_instance_list["position"].AsVector3(); Vector3 position = inner_instance_list["position"].AsVector3();
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
@ -1608,7 +1577,10 @@ namespace OpenSim.Region.ClientStack.Linden
break; break;
m_Scene.TryGetScenePresence(m_AgentID, out sp); m_Scene.TryGetScenePresence(m_AgentID, out sp);
if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) if(sp == null || sp.IsChildAgent || sp.IsDeleted)
break;
if(sp.IsInTransit && !sp.IsInLocalTransit)
break; break;
client = sp.ControllingClient; client = sp.ControllingClient;
@ -1730,7 +1702,10 @@ namespace OpenSim.Region.ClientStack.Linden
break; break;
m_Scene.TryGetScenePresence(m_AgentID, out sp); m_Scene.TryGetScenePresence(m_AgentID, out sp);
if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) if(sp == null || sp.IsChildAgent || sp.IsDeleted)
break;
if(sp.IsInTransit && !sp.IsInLocalTransit)
break; break;
client = sp.ControllingClient; client = sp.ControllingClient;
@ -1838,7 +1813,7 @@ namespace OpenSim.Region.ClientStack.Linden
if(sp == null || sp.IsDeleted) if(sp == null || sp.IsDeleted)
return ""; return "";
if(sp.IsInTransit) if(sp.IsInTransit && !sp.IsInLocalTransit)
{ {
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable;
httpResponse.AddHeader("Retry-After","30"); httpResponse.AddHeader("Retry-After","30");
@ -1848,7 +1823,6 @@ namespace OpenSim.Region.ClientStack.Linden
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string[] ids = query.GetValues("ids"); string[] ids = query.GetValues("ids");
Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids); Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids);
OSDMap osdReply = new OSDMap(); OSDMap osdReply = new OSDMap();
@ -1864,12 +1838,18 @@ namespace OpenSim.Region.ClientStack.Linden
string[] parts = kvp.Value.Split(new char[] {' '}); string[] parts = kvp.Value.Split(new char[] {' '});
OSDMap osdname = new OSDMap(); OSDMap osdname = new OSDMap();
// dont tell about unknown users, we can't send them back on Bad either
if(parts[0] == "Unknown")
continue;
/*
if(parts[0] == "Unknown") if(parts[0] == "Unknown")
{ {
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1)); osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2)); osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
} }
else else
*/
{ {
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));

View File

@ -500,13 +500,13 @@ namespace OpenSim.Region.ClientStack.Linden
responsedata["http_protocol_version"] = "HTTP/1.0"; responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata; return responsedata;
} }
/* this is not a event message
public void DisableSimulator(ulong handle, UUID avatarID) public void DisableSimulator(ulong handle, UUID avatarID)
{ {
OSD item = EventQueueHelper.DisableSimulator(handle); OSD item = EventQueueHelper.DisableSimulator(handle);
Enqueue(item, avatarID); Enqueue(item, avatarID);
} }
*/
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
{ {
if (DebugLevel > 0) if (DebugLevel > 0)

View File

@ -90,7 +90,7 @@ namespace OpenSim.Region.ClientStack.Linden
return BuildEvent("EnableSimulator", llsdBody); return BuildEvent("EnableSimulator", llsdBody);
} }
/*
public static OSD DisableSimulator(ulong handle) public static OSD DisableSimulator(ulong handle)
{ {
//OSDMap llsdSimInfo = new OSDMap(1); //OSDMap llsdSimInfo = new OSDMap(1);
@ -105,7 +105,7 @@ namespace OpenSim.Region.ClientStack.Linden
return BuildEvent("DisableSimulator", llsdBody); return BuildEvent("DisableSimulator", llsdBody);
} }
*/
public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
IPEndPoint newRegionExternalEndPoint, IPEndPoint newRegionExternalEndPoint,
string capsURL, UUID agentID, UUID sessionID, string capsURL, UUID agentID, UUID sessionID,

View File

@ -89,8 +89,8 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null; private static Thread[] m_workerThreads = null;
private static int m_NumberScenes = 0; private static int m_NumberScenes = 0;
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue = private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>(); new OpenSim.Framework.BlockingQueue<aPollRequest>();
private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
@ -171,7 +171,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests, m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests,
String.Format("GetMeshWorker{0}", i), String.Format("GetMeshWorker{0}", i),
ThreadPriority.Normal, ThreadPriority.Normal,
false, true,
false, false,
null, null,
int.MaxValue); int.MaxValue);
@ -204,8 +204,11 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
while(true) while(true)
{ {
aPollRequest poolreq = m_queue.Dequeue(); aPollRequest poolreq = m_queue.Dequeue(4500);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
if(m_NumberScenes <= 0)
return;
if(poolreq.reqID != UUID.Zero)
poolreq.thepoll.Process(poolreq); poolreq.thepoll.Process(poolreq);
} }
} }
@ -218,7 +221,7 @@ namespace OpenSim.Region.ClientStack.Linden
PollServiceMeshEventArgs args; PollServiceMeshEventArgs args;
if (m_pollservices.TryGetValue(user, out args)) if (m_pollservices.TryGetValue(user, out args))
{ {
args.UpdateThrottle(imagethrottle, p); args.UpdateThrottle(imagethrottle);
} }
} }
@ -235,14 +238,13 @@ namespace OpenSim.Region.ClientStack.Linden
base(null, uri, null, null, null, pId, int.MaxValue) base(null, uri, null, null, null, pId, int.MaxValue)
{ {
m_scene = scene; m_scene = scene;
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); m_throttler = new MeshCapsDataThrottler(100000);
// x is request id, y is userid // x is request id, y is userid
HasEvents = (x, y) => HasEvents = (x, y) =>
{ {
lock (responses) lock (responses)
{ {
bool ret = m_throttler.hasEvents(x, responses); bool ret = m_throttler.hasEvents(x, responses);
m_throttler.ProcessTime();
return ret; return ret;
} }
@ -257,8 +259,8 @@ namespace OpenSim.Region.ClientStack.Linden
} }
finally finally
{ {
m_throttler.ProcessTime();
responses.Remove(x); responses.Remove(x);
m_throttler.PassTime();
} }
} }
}; };
@ -271,6 +273,7 @@ namespace OpenSim.Region.ClientStack.Linden
reqinfo.request = y; reqinfo.request = y;
m_queue.Enqueue(reqinfo); m_queue.Enqueue(reqinfo);
m_throttler.PassTime();
}; };
// this should never happen except possible on shutdown // this should never happen except possible on shutdown
@ -332,12 +335,15 @@ namespace OpenSim.Region.ClientStack.Linden
}; };
} }
m_throttler.ProcessTime(); m_throttler.PassTime();
} }
internal void UpdateThrottle(int pimagethrottle, ScenePresence p) internal void UpdateThrottle(int pthrottle)
{ {
m_throttler.UpdateThrottle(pimagethrottle, p); int tmp = 2 * pthrottle;
if(tmp < 10000)
tmp = 10000;
m_throttler.ThrottleBytes = tmp;
} }
} }
@ -391,25 +397,15 @@ namespace OpenSim.Region.ClientStack.Linden
internal sealed class MeshCapsDataThrottler internal sealed class MeshCapsDataThrottler
{ {
private double lastTimeElapsed = 0;
private double BytesSent = 0;
private volatile int currenttime = 0; public MeshCapsDataThrottler(int pBytes)
private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0;
private int CapSetThrottle = 0;
private float CapThrottleDistributon = 0.30f;
private readonly Scene m_scene;
private ThrottleOutPacketType Throttle;
private readonly UUID User;
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser)
{ {
if(pBytes < 10000)
pBytes = 10000;
ThrottleBytes = pBytes; ThrottleBytes = pBytes;
if(ThrottleBytes < 10000) lastTimeElapsed = Util.GetTimeStampMS();
ThrottleBytes = 10000;
lastTimeElapsed = Util.EnvironmentTickCount();
Throttle = ThrottleOutPacketType.Asset;
m_scene = pScene;
User = puser;
} }
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses) public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
@ -439,46 +435,22 @@ namespace OpenSim.Region.ClientStack.Linden
return haskey; return haskey;
} }
public void ProcessTime() public void PassTime()
{ {
PassTime(); double currenttime = Util.GetTimeStampMS();
} double timeElapsed = currenttime - lastTimeElapsed;
if(timeElapsed < 50.0)
private void PassTime() return;
{ int add = (int)(ThrottleBytes * timeElapsed * 0.001);
currenttime = Util.EnvironmentTickCount(); if (add >= 1000)
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
if (timeElapsed >= 100)
{ {
lastTimeElapsed = currenttime; lastTimeElapsed = currenttime;
BytesSent -= (ThrottleBytes * timeElapsed / 1000); BytesSent -= add;
if (BytesSent < 0) BytesSent = 0; if (BytesSent < 0) BytesSent = 0;
} }
} }
private void AlterThrottle(int setting, ScenePresence p) public int ThrottleBytes;
{
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
}
public int ThrottleBytes
{
get { return CapSetThrottle; }
set
{
if (value > 10000)
CapSetThrottle = value;
else
CapSetThrottle = 10000;
}
}
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{
// Client set throttle !
CapSetThrottle = 2 * pimagethrottle;
ProcessTime();
}
} }
} }
} }

View File

@ -77,8 +77,8 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null; private static Thread[] m_workerThreads = null;
private static int m_NumberScenes = 0; private static int m_NumberScenes = 0;
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue = private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>(); new OpenSim.Framework.BlockingQueue<aPollRequest>();
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
@ -139,7 +139,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests, m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests,
String.Format("GetTextureWorker{0}", i), String.Format("GetTextureWorker{0}", i),
ThreadPriority.Normal, ThreadPriority.Normal,
false, true,
false, false,
null, null,
int.MaxValue); int.MaxValue);
@ -220,7 +220,7 @@ namespace OpenSim.Region.ClientStack.Linden
new Dictionary<UUID, aPollResponse>(); new Dictionary<UUID, aPollResponse>();
private Scene m_scene; private Scene m_scene;
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); private CapsDataThrottler m_throttler = new CapsDataThrottler(100000);
public PollServiceTextureEventArgs(UUID pId, Scene scene) : public PollServiceTextureEventArgs(UUID pId, Scene scene) :
base(null, "", null, null, null, pId, int.MaxValue) base(null, "", null, null, null, pId, int.MaxValue)
{ {
@ -231,7 +231,6 @@ namespace OpenSim.Region.ClientStack.Linden
lock (responses) lock (responses)
{ {
bool ret = m_throttler.hasEvents(x, responses); bool ret = m_throttler.hasEvents(x, responses);
m_throttler.ProcessTime();
return ret; return ret;
} }
@ -247,6 +246,7 @@ namespace OpenSim.Region.ClientStack.Linden
finally finally
{ {
responses.Remove(x); responses.Remove(x);
m_throttler.PassTime();
} }
} }
}; };
@ -263,7 +263,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
if (responses.Count > 0) if (responses.Count > 0)
{ {
if (m_queue.Count >= 4) if (m_queue.Count() >= 4)
{ {
// Never allow more than 4 fetches to wait // Never allow more than 4 fetches to wait
reqinfo.send503 = true; reqinfo.send503 = true;
@ -271,6 +271,7 @@ namespace OpenSim.Region.ClientStack.Linden
} }
} }
m_queue.Enqueue(reqinfo); m_queue.Enqueue(reqinfo);
m_throttler.PassTime();
}; };
// this should never happen except possible on shutdown // this should never happen except possible on shutdown
@ -351,14 +352,15 @@ namespace OpenSim.Region.ClientStack.Linden
}; };
} }
m_throttler.ProcessTime(); m_throttler.PassTime();
} }
internal void UpdateThrottle(int pimagethrottle) internal void UpdateThrottle(int pimagethrottle)
{ {
m_throttler.ThrottleBytes = 2 * pimagethrottle; int tmp = 2 * pimagethrottle;
if(m_throttler.ThrottleBytes < 10000) if(tmp < 10000)
m_throttler.ThrottleBytes = 10000; tmp = 10000;
m_throttler.ThrottleBytes = tmp;
} }
} }
@ -415,24 +417,25 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
while (true) while (true)
{ {
aPollRequest poolreq = m_queue.Dequeue(); aPollRequest poolreq = m_queue.Dequeue(4500);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
if(m_NumberScenes <= 0)
return;
if(poolreq.reqID != UUID.Zero)
poolreq.thepoll.Process(poolreq); poolreq.thepoll.Process(poolreq);
} }
} }
internal sealed class CapsDataThrottler internal sealed class CapsDataThrottler
{ {
private double lastTimeElapsed = 0;
private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0; private volatile int BytesSent = 0;
public CapsDataThrottler(int pBytes, int max, int min) public CapsDataThrottler(int pBytes)
{ {
if(pBytes < 10000)
pBytes = 10000;
ThrottleBytes = pBytes; ThrottleBytes = pBytes;
if(ThrottleBytes < 10000) lastTimeElapsed = Util.GetTimeStampMS();
ThrottleBytes = 10000;
lastTimeElapsed = Util.EnvironmentTickCount();
} }
public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses) public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
{ {
@ -465,20 +468,17 @@ namespace OpenSim.Region.ClientStack.Linden
return haskey; return haskey;
} }
public void ProcessTime() public void PassTime()
{ {
PassTime(); double currenttime = Util.GetTimeStampMS();
} double timeElapsed = currenttime - lastTimeElapsed;
if(timeElapsed < 50.0)
private void PassTime() return;
{ int add = (int)(ThrottleBytes * timeElapsed * 0.001);
currenttime = Util.EnvironmentTickCount(); if (add >= 1000)
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
//processTimeBasedActions(responses);
if (timeElapsed >= 100)
{ {
lastTimeElapsed = currenttime; lastTimeElapsed = currenttime;
BytesSent -= (ThrottleBytes * timeElapsed / 1000); BytesSent -= add;
if (BytesSent < 0) BytesSent = 0; if (BytesSent < 0) BytesSent = 0;
} }
} }

View File

@ -121,6 +121,9 @@ namespace OpenSim.Region.ClientStack.Linden
OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]); OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
if (r.Type != OSDType.Map) // not a proper req
return responsedata;
//UUID session_id = UUID.Zero; //UUID session_id = UUID.Zero;
bool bypass_raycast = false; bool bypass_raycast = false;
uint everyone_mask = 0; uint everyone_mask = 0;
@ -157,9 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden
int state = 0; int state = 0;
int lastattach = 0; int lastattach = 0;
if (r.Type != OSDType.Map) // not a proper req
return responsedata;
OSDMap rm = (OSDMap)r; OSDMap rm = (OSDMap)r;
if (rm.ContainsKey("ObjectData")) //v2 if (rm.ContainsKey("ObjectData")) //v2
@ -307,8 +307,6 @@ namespace OpenSim.Region.ClientStack.Linden
} }
} }
Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false); Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false);
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
@ -359,6 +357,8 @@ namespace OpenSim.Region.ClientStack.Linden
rootpart.NextOwnerMask = next_owner_mask; rootpart.NextOwnerMask = next_owner_mask;
rootpart.Material = (byte)material; rootpart.Material = (byte)material;
obj.InvalidateDeepEffectivePerms();
m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
responsedata["int_response_code"] = 200; //501; //410; //404; responsedata["int_response_code"] = 200; //501; //410; //404;

View File

@ -335,6 +335,7 @@ namespace OpenSim.Region.ClientStack.Linden
grp.AbsolutePosition = obj.Position; grp.AbsolutePosition = obj.Position;
prim.RotationOffset = obj.Rotation; prim.RotationOffset = obj.Rotation;
// Required for linking // Required for linking
grp.RootPart.ClearUpdateSchedule(); grp.RootPart.ClearUpdateSchedule();

View File

@ -185,8 +185,9 @@ namespace OpenSim.Region.ClientStack.Linden
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{ {
StreamReader reader = new StreamReader(request); string message;
string message = reader.ReadToEnd(); using(StreamReader reader = new StreamReader(request))
message = reader.ReadToEnd();
OSD osd = OSDParser.DeserializeLLSDXml(message); OSD osd = OSDParser.DeserializeLLSDXml(message);

View File

@ -63,9 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
private Scene m_scene; private Scene m_scene;
private bool m_persistBakedTextures;
private IBakedTextureModule m_BakedTextureModule;
private string m_URL; private string m_URL;
public void Initialise(IConfigSource source) public void Initialise(IConfigSource source)
@ -76,15 +74,12 @@ namespace OpenSim.Region.ClientStack.Linden
m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty); m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty);
IConfig appearanceConfig = source.Configs["Appearance"]; // IConfig appearanceConfig = source.Configs["Appearance"];
if (appearanceConfig != null)
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
} }
public void AddRegion(Scene s) public void AddRegion(Scene s)
{ {
m_scene = s; m_scene = s;
} }
public void RemoveRegion(Scene s) public void RemoveRegion(Scene s)
@ -92,7 +87,6 @@ namespace OpenSim.Region.ClientStack.Linden
s.EventManager.OnRegisterCaps -= RegisterCaps; s.EventManager.OnRegisterCaps -= RegisterCaps;
s.EventManager.OnNewPresence -= RegisterNewPresence; s.EventManager.OnNewPresence -= RegisterNewPresence;
s.EventManager.OnRemovePresence -= DeRegisterPresence; s.EventManager.OnRemovePresence -= DeRegisterPresence;
m_BakedTextureModule = null;
m_scene = null; m_scene = null;
} }
@ -101,7 +95,6 @@ namespace OpenSim.Region.ClientStack.Linden
m_scene.EventManager.OnRegisterCaps += RegisterCaps; m_scene.EventManager.OnRegisterCaps += RegisterCaps;
m_scene.EventManager.OnNewPresence += RegisterNewPresence; m_scene.EventManager.OnNewPresence += RegisterNewPresence;
m_scene.EventManager.OnRemovePresence += DeRegisterPresence; m_scene.EventManager.OnRemovePresence += DeRegisterPresence;
} }
private void DeRegisterPresence(UUID agentId) private void DeRegisterPresence(UUID agentId)
@ -110,156 +103,12 @@ namespace OpenSim.Region.ClientStack.Linden
private void RegisterNewPresence(ScenePresence presence) private void RegisterNewPresence(ScenePresence presence)
{ {
// presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
} }
/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache()
private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
{
// if cacheItems.Length > 0 viewer is giving us current textures information.
// baked ones should had been uploaded and in assets cache as local itens
if (cacheItems.Length == 0)
return; // no textures information, nothing to do
ScenePresence p = null;
if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
return; // what are we doing if there is no presence to cache for?
if (p.IsDeleted)
return; // does this really work?
int maxCacheitemsLoop = cacheItems.Length;
if (maxCacheitemsLoop > 20)
{
maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
}
m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
// some nice debug
m_log.Debug("[Cacheitems]: " + cacheItems.Length);
for (int iter = 0; iter < maxCacheitemsLoop; iter++)
{
m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
cacheItems[iter].TextureID);
}
// p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper
WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
if (existingitems == null)
{
if (m_BakedTextureModule != null)
{
WearableCacheItem[] savedcache = null;
try
{
if (p.Appearance.WearableCacheItemsDirty)
{
savedcache = m_BakedTextureModule.Get(p.UUID);
p.Appearance.WearableCacheItems = savedcache;
p.Appearance.WearableCacheItemsDirty = false;
}
}
catch (Exception)
{
// The service logs a sufficient error message.
}
if (savedcache != null)
existingitems = savedcache;
}
}
// Existing items null means it's a fully new appearance
if (existingitems == null)
{
for (int i = 0; i < maxCacheitemsLoop; i++)
{
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
{
Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
if (face == null)
{
textureEntry.CreateFace(cacheItems[i].TextureIndex);
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
AppearanceManager.DEFAULT_AVATAR_TEXTURE;
continue;
}
cacheItems[i].TextureID = face.TextureID;
if (m_scene.AssetService != null)
cacheItems[i].TextureAsset =
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
}
else
{
m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
}
}
}
else
{
for (int i = 0; i < maxCacheitemsLoop; i++)
{
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
{
Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
if (face == null)
{
textureEntry.CreateFace(cacheItems[i].TextureIndex);
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
AppearanceManager.DEFAULT_AVATAR_TEXTURE;
continue;
}
cacheItems[i].TextureID =
face.TextureID;
}
else
{
m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
}
}
for (int i = 0; i < maxCacheitemsLoop; i++)
{
if (cacheItems[i].TextureAsset == null)
{
cacheItems[i].TextureAsset =
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
}
}
}
p.Appearance.WearableCacheItems = cacheItems;
if (m_BakedTextureModule != null)
{
m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
p.Appearance.WearableCacheItemsDirty = true;
}
else
p.Appearance.WearableCacheItemsDirty = false;
for (int iter = 0; iter < maxCacheitemsLoop; iter++)
{
m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
cacheItems[iter].TextureID);
}
}
*/
public void PostInitialise() public void PostInitialise()
{ {
} }
public void Close() { } public void Close() { }
public string Name { get { return "UploadBakedTextureModule"; } } public string Name { get { return "UploadBakedTextureModule"; } }
@ -275,7 +124,7 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_URL == "localhost") if (m_URL == "localhost")
{ {
UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
caps, m_scene.AssetService, m_persistBakedTextures); caps, m_scene.AssetService);
caps.RegisterHandler( caps.RegisterHandler(
"UploadBakedTexture", "UploadBakedTexture",

View File

@ -207,7 +207,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests,
String.Format("InventoryWorkerThread{0}", i), String.Format("InventoryWorkerThread{0}", i),
ThreadPriority.Normal, ThreadPriority.Normal,
false, true,
true, true,
null, null,
int.MaxValue); int.MaxValue);
@ -443,10 +443,9 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
while (true) while (true)
{ {
aPollRequest poolreq = m_queue.Dequeue(4500);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
aPollRequest poolreq = m_queue.Dequeue(5000);
if (poolreq != null && poolreq.thepoll != null) if (poolreq != null && poolreq.thepoll != null)
{ {
try try
@ -456,7 +455,7 @@ namespace OpenSim.Region.ClientStack.Linden
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {3}", "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}",
poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e);
} }
} }

View File

@ -62,7 +62,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Handles new client connections /// Handles new client connections
/// Constructor takes a single Packet and authenticates everything /// Constructor takes a single Packet and authenticates everything
/// </summary> /// </summary>
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector, IClientIPEndpoint
{ {
/// <value> /// <value>
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details. /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
@ -325,6 +325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
public LLImageManager ImageManager { get; private set; } public LLImageManager ImageManager { get; private set; }
public JobEngine m_asyncPacketProcess;
private readonly LLUDPServer m_udpServer; private readonly LLUDPServer m_udpServer;
private readonly LLUDPClient m_udpClient; private readonly LLUDPClient m_udpClient;
private readonly UUID m_sessionId; private readonly UUID m_sessionId;
@ -378,7 +379,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected Scene m_scene; protected Scene m_scene;
protected string m_firstName; protected string m_firstName;
protected string m_lastName; protected string m_lastName;
protected Thread m_clientThread;
protected Vector3 m_startpos; protected Vector3 m_startpos;
protected UUID m_activeGroupID; protected UUID m_activeGroupID;
protected string m_activeGroupName = String.Empty; protected string m_activeGroupName = String.Empty;
@ -529,7 +529,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_prioritizer = new Prioritizer(m_scene); m_prioritizer = new Prioritizer(m_scene);
RegisterLocalPacketHandlers(); RegisterLocalPacketHandlers();
string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString());
m_asyncPacketProcess = new JobEngine(name, name, 10000);
IsActive = true; IsActive = true;
} }
@ -592,6 +593,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (OnConnectionClosed != null) if (OnConnectionClosed != null)
OnConnectionClosed(this); OnConnectionClosed(this);
m_asyncPacketProcess.Stop();
// Flush all of the packets out of the UDP server for this client // Flush all of the packets out of the UDP server for this client
if (m_udpServer != null) if (m_udpServer != null)
@ -703,29 +705,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </param> /// </param>
/// <returns>true if the handler was added. This is currently always the case.</returns> /// <returns>true if the handler was added. This is currently always the case.</returns>
public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
{
return AddLocalPacketHandler(packetType, handler, doAsync, false);
}
/// <summary>
/// Add a handler for the given packet type.
/// </summary>
/// <param name="packetType"></param>
/// <param name="handler"></param>
/// <param name="doAsync">
/// If true, when the packet is received handle it on a different thread. Whether this is given direct to
/// a threadpool thread or placed in a queue depends on the inEngine parameter.
/// </param>
/// <param name="inEngine">
/// If async is false then this parameter is ignored.
/// If async is true and inEngine is false, then the packet is sent directly to a
/// threadpool thread.
/// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine.
/// This may result in slower handling but reduces the risk of overloading the simulator when there are many
/// simultaneous async requests.
/// </param>
/// <returns>true if the handler was added. This is currently always the case.</returns>
public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine)
{ {
bool result = false; bool result = false;
lock (m_packetHandlers) lock (m_packetHandlers)
@ -733,7 +712,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!m_packetHandlers.ContainsKey(packetType)) if (!m_packetHandlers.ContainsKey(packetType))
{ {
m_packetHandlers.Add( m_packetHandlers.Add(
packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine }); packetType, new PacketProcessor() { method = handler, Async = doAsync});
result = true; result = true;
} }
} }
@ -768,30 +747,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
PacketProcessor pprocessor; PacketProcessor pprocessor;
if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor))
{ {
ClientInfo cinfo = UDPClient.GetClientInfo();
//there is a local handler for this packet type //there is a local handler for this packet type
if (pprocessor.Async) if (pprocessor.Async)
{ {
if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
cinfo.AsyncRequests[packet.Type.ToString()] = 0;
cinfo.AsyncRequests[packet.Type.ToString()]++;
object obj = new AsyncPacketProcess(this, pprocessor.method, packet); object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
m_asyncPacketProcess.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj));
if (pprocessor.InEngine)
m_udpServer.IpahEngine.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj));
else
Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString());
result = true; result = true;
} }
else else
{ {
if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
cinfo.SyncRequests[packet.Type.ToString()] = 0;
cinfo.SyncRequests[packet.Type.ToString()]++;
result = pprocessor.method(this, packet); result = pprocessor.method(this, packet);
} }
} }
@ -806,11 +771,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
if (found) if (found)
{ {
ClientInfo cinfo = UDPClient.GetClientInfo();
if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
cinfo.GenericRequests[packet.Type.ToString()] = 0;
cinfo.GenericRequests[packet.Type.ToString()]++;
result = method(this, packet); result = method(this, packet);
} }
} }
@ -841,6 +801,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public virtual void Start() public virtual void Start()
{ {
m_asyncPacketProcess.Start();
m_scene.AddNewAgent(this, PresenceType.User); m_scene.AddNewAgent(this, PresenceType.User);
// RefreshGroupMembership(); // RefreshGroupMembership();
@ -3111,10 +3072,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
{ {
float dwell = 0.0f;
IDwellModule dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
if (dwellModule != null)
dwell = dwellModule.GetDwell(land.GlobalID);
ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply);
reply.AgentData.AgentID = m_agentId; reply.AgentData.AgentID = m_agentId;
reply.Data.ParcelID = parcelID; reply.Data.ParcelID = parcelID;
@ -3141,7 +3098,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.Data.GlobalZ = pos.Z; reply.Data.GlobalZ = pos.Z;
reply.Data.SimName = Utils.StringToBytes(info.RegionName); reply.Data.SimName = Utils.StringToBytes(info.RegionName);
reply.Data.SnapshotID = land.SnapshotID; reply.Data.SnapshotID = land.SnapshotID;
reply.Data.Dwell = dwell; reply.Data.Dwell = land.Dwell;
reply.Data.SalePrice = land.SalePrice; reply.Data.SalePrice = land.SalePrice;
reply.Data.AuctionID = (int)land.AuctionID; reply.Data.AuctionID = (int)land.AuctionID;
@ -3950,24 +3907,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary> /// <summary>
/// Send an ObjectUpdate packet with information about an avatar /// Send an ObjectUpdate packet with information about an avatar
/// </summary> /// </summary>
public void SendAvatarDataImmediate(ISceneEntity avatar) public void SendEntityFullUpdateImmediate(ISceneEntity ent)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}",
// avatar.Name, avatar.UUID, Name, AgentId); // avatar.Name, avatar.UUID, Name, AgentId);
ScenePresence presence = avatar as ScenePresence; if (ent == null)
if (presence == null)
return; return;
ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
objupdate.Header.Zerocoded = true; objupdate.Header.Zerocoded = true;
objupdate.RegionData.RegionHandle = presence.RegionHandle;
// objupdate.RegionData.TimeDilation = ushort.MaxValue;
objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
if(ent is ScenePresence)
{
ScenePresence presence = ent as ScenePresence;
objupdate.RegionData.RegionHandle = presence.RegionHandle;
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
}
else if(ent is SceneObjectPart)
{
SceneObjectPart part = ent as SceneObjectPart;
objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent);
}
OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
// We need to record the avatar local id since the root prim of an attachment points to this.
// m_attachmentsSent.Add(avatar.LocalId);
}
public void SendEntityTerseUpdateImmediate(ISceneEntity ent)
{
// m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}",
// avatar.Name, avatar.UUID, Name, AgentId);
if (ent == null)
return;
ImprovedTerseObjectUpdatePacket objupdate =
(ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
objupdate.Header.Zerocoded = true;
objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
objupdate.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
if(ent is ScenePresence)
{
ScenePresence presence = ent as ScenePresence;
objupdate.RegionData.RegionHandle = presence.RegionHandle;
objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false);
}
else if(ent is SceneObjectPart)
{
SceneObjectPart part = ent as SceneObjectPart;
objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false);
}
OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
@ -4021,7 +4022,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Primitive Packet/Data Sending Methods #region Primitive Packet/Data Sending Methods
/// <summary> /// <summary>
/// Generate one of the object update packets based on PrimUpdateFlags /// Generate one of the object update packets based on PrimUpdateFlags
/// and broadcast the packet to clients /// and broadcast the packet to clients
@ -4044,10 +4044,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
*/ */
if (entity is SceneObjectPart) if (entity is SceneObjectPart)
{ {
SceneObjectPart e = (SceneObjectPart)entity; SceneObjectPart p = (SceneObjectPart)entity;
SceneObjectGroup g = e.ParentGroup; SceneObjectGroup g = p.ParentGroup;
if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId)
return; // Don't send updates for other people's HUDs return; // Don't send updates for other people's HUDs
if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0)
{
List<uint> partIDs = (new List<uint> {p.LocalId});
lock (m_entityProps.SyncRoot)
m_entityProps.Remove(partIDs);
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Remove(partIDs);
return;
}
} }
//double priority = m_prioritizer.GetUpdatePriority(this, entity); //double priority = m_prioritizer.GetUpdatePriority(this, entity);
@ -4126,20 +4136,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Vector3 mycamera = Vector3.Zero; // Vector3 mycamera = Vector3.Zero;
Vector3 mypos = Vector3.Zero; Vector3 mypos = Vector3.Zero;
ScenePresence mysp = (ScenePresence)SceneAgent; ScenePresence mysp = (ScenePresence)SceneAgent;
if(mysp != null && !mysp.IsDeleted)
bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
// we should have a presence
if(mysp == null)
return;
if(doCulling)
{ {
cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
// mycamera = mysp.CameraPosition; // mycamera = mysp.CameraPosition;
mypos = mysp.AbsolutePosition; mypos = mysp.AbsolutePosition;
} }
else
doCulling = false;
while (maxUpdatesBytes > 0) while (maxUpdatesBytes > 0)
{ {
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
{
if(orderedDequeue)
{
if (!m_entityUpdates.TryOrderedDequeue(out update, out timeinqueue))
break;
}
else
{
if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
break; break;
}
}
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
@ -4154,9 +4178,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
SceneObjectPart part = (SceneObjectPart)update.Entity; SceneObjectPart part = (SceneObjectPart)update.Entity;
SceneObjectGroup grp = part.ParentGroup; SceneObjectGroup grp = part.ParentGroup;
if (grp.inTransit) if (grp.inTransit && !update.Flags.HasFlag(PrimUpdateFlags.SendInTransit))
continue; continue;
/* debug
if (update.Flags.HasFlag(PrimUpdateFlags.SendInTransit))
{
}
*/
if (grp.IsDeleted) if (grp.IsDeleted)
{ {
// Don't send updates for objects that have been marked deleted. // Don't send updates for objects that have been marked deleted.
@ -4213,14 +4243,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
part.Shape.LightEntry = false; part.Shape.LightEntry = false;
} }
if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
{
// Ensure that mesh has at least 8 valid faces
part.Shape.ProfileBegin = 12500;
part.Shape.ProfileEnd = 0;
part.Shape.ProfileHollow = 27500;
}
} }
if(doCulling && !grp.IsAttachment) if(doCulling && !grp.IsAttachment)
@ -4248,14 +4270,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
continue; continue;
} }
} }
if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
{
// Ensure that mesh has at least 8 valid faces
part.Shape.ProfileBegin = 12500;
part.Shape.ProfileEnd = 0;
part.Shape.ProfileHollow = 27500;
}
} }
else if (update.Entity is ScenePresence) else if (update.Entity is ScenePresence)
{ {
@ -4330,7 +4344,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (update.Entity is ScenePresence) if (update.Entity is ScenePresence)
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
else else
ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp);
objectUpdateBlocks.Add(ablock); objectUpdateBlocks.Add(ablock);
objectUpdates.Value.Add(update); objectUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length; maxUpdatesBytes -= ablock.Length;
@ -4462,6 +4476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
// hack.. dont use // hack.. dont use
/*
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{ {
if (ent is SceneObjectPart) if (ent is SceneObjectPart)
@ -4472,7 +4487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId); ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp);
if (parentID.HasValue) if (parentID.HasValue)
{ {
blk.ParentID = parentID.Value; blk.ParentID = parentID.Value;
@ -4488,7 +4503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name); // updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
// //
} }
*/
public void ReprioritizeUpdates() public void ReprioritizeUpdates()
{ {
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
@ -4846,6 +4861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates = // OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); // new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
EntityUpdate iupdate; EntityUpdate iupdate;
Int32 timeinqueue; // this is just debugging code & can be dropped later Int32 timeinqueue; // this is just debugging code & can be dropped later
@ -4853,8 +4869,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
while (maxUpdateBytes > 0) while (maxUpdateBytes > 0)
{ {
lock (m_entityProps.SyncRoot) lock (m_entityProps.SyncRoot)
{
if(orderedDequeue)
{
if (!m_entityProps.TryOrderedDequeue(out iupdate, out timeinqueue))
break;
}
else
{
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
break; break;
}
}
ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
if (update.SendFamilyProps) if (update.SendFamilyProps)
@ -5522,6 +5548,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion #endregion
#region Helper Methods #region Helper Methods
private void ClampVectorForUint(ref Vector3 v, float max)
{
float a,b;
a = Math.Abs(v.X);
b = Math.Abs(v.Y);
if(b > a)
a = b;
b= Math.Abs(v.Z);
if(b > a)
a = b;
if (a > max)
{
a = max / a;
v.X *= a;
v.Y *= a;
v.Z *= a;
}
}
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
{ {
@ -5612,11 +5658,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
pos += 12; pos += 12;
// Velocity // Velocity
ClampVectorForUint(ref velocity, 128f);
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
// Acceleration // Acceleration
ClampVectorForUint(ref acceleration, 64f);
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
@ -5628,6 +5676,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
// Angular Velocity // Angular Velocity
ClampVectorForUint(ref angularVelocity, 64f);
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
@ -5726,29 +5775,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return update; return update;
} }
protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp)
{ {
byte[] objectData = new byte[60]; byte[] objectData = new byte[60];
data.RelativePosition.ToBytes(objectData, 0); part.RelativePosition.ToBytes(objectData, 0);
data.Velocity.ToBytes(objectData, 12); part.Velocity.ToBytes(objectData, 12);
data.Acceleration.ToBytes(objectData, 24); part.Acceleration.ToBytes(objectData, 24);
Quaternion rotation = data.RotationOffset; Quaternion rotation = part.RotationOffset;
rotation.Normalize(); rotation.Normalize();
rotation.ToBytes(objectData, 36); rotation.ToBytes(objectData, 36);
data.AngularVelocity.ToBytes(objectData, 48); part.AngularVelocity.ToBytes(objectData, 48);
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
update.ClickAction = (byte)data.ClickAction; update.ClickAction = (byte)part.ClickAction;
update.CRC = 0; update.CRC = 0;
update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; update.ExtraParams = part.Shape.ExtraParams ?? Utils.EmptyBytes;
update.FullID = data.UUID; update.FullID = part.UUID;
update.ID = data.LocalId; update.ID = part.LocalId;
//update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
//update.JointPivot = Vector3.Zero; //update.JointPivot = Vector3.Zero;
//update.JointType = 0; //update.JointType = 0;
update.Material = data.Material; update.Material = part.Material;
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
/* /*
if (data.ParentGroup.IsAttachment) if (data.ParentGroup.IsAttachment)
{ {
@ -5776,68 +5825,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
*/ */
if (data.ParentGroup.IsAttachment) if (part.ParentGroup.IsAttachment)
{ {
if (data.IsRoot) if (part.IsRoot)
{ {
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID);
} }
else else
update.NameValue = Utils.EmptyBytes; update.NameValue = Utils.EmptyBytes;
int st = (int)data.ParentGroup.AttachmentPoint; int st = (int)part.ParentGroup.AttachmentPoint;
update.State = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; update.State = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ;
} }
else else
{ {
update.NameValue = Utils.EmptyBytes; update.NameValue = Utils.EmptyBytes;
update.State = data.Shape.State; // not sure about this update.State = part.Shape.State; // not sure about this
} }
update.ObjectData = objectData; update.ObjectData = objectData;
update.ParentID = data.ParentID; update.ParentID = part.ParentID;
update.PathBegin = data.Shape.PathBegin; update.PathBegin = part.Shape.PathBegin;
update.PathCurve = data.Shape.PathCurve; update.PathCurve = part.Shape.PathCurve;
update.PathEnd = data.Shape.PathEnd; update.PathEnd = part.Shape.PathEnd;
update.PathRadiusOffset = data.Shape.PathRadiusOffset; update.PathRadiusOffset = part.Shape.PathRadiusOffset;
update.PathRevolutions = data.Shape.PathRevolutions; update.PathRevolutions = part.Shape.PathRevolutions;
update.PathScaleX = data.Shape.PathScaleX; update.PathScaleX = part.Shape.PathScaleX;
update.PathScaleY = data.Shape.PathScaleY; update.PathScaleY = part.Shape.PathScaleY;
update.PathShearX = data.Shape.PathShearX; update.PathShearX = part.Shape.PathShearX;
update.PathShearY = data.Shape.PathShearY; update.PathShearY = part.Shape.PathShearY;
update.PathSkew = data.Shape.PathSkew; update.PathSkew = part.Shape.PathSkew;
update.PathTaperX = data.Shape.PathTaperX; update.PathTaperX = part.Shape.PathTaperX;
update.PathTaperY = data.Shape.PathTaperY; update.PathTaperY = part.Shape.PathTaperY;
update.PathTwist = data.Shape.PathTwist; update.PathTwist = part.Shape.PathTwist;
update.PathTwistBegin = data.Shape.PathTwistBegin; update.PathTwistBegin = part.Shape.PathTwistBegin;
update.PCode = data.Shape.PCode; update.PCode = part.Shape.PCode;
update.ProfileBegin = data.Shape.ProfileBegin; update.ProfileBegin = part.Shape.ProfileBegin;
update.ProfileCurve = data.Shape.ProfileCurve; update.ProfileCurve = part.Shape.ProfileCurve;
update.ProfileEnd = data.Shape.ProfileEnd;
update.ProfileHollow = data.Shape.ProfileHollow; if(part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack
update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; update.ProfileCurve = (byte)(part.Shape.ProfileCurve & 0x0f);
update.TextColor = data.GetTextColor().GetBytes(false); else
update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; update.ProfileCurve = part.Shape.ProfileCurve;
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
update.Scale = data.Shape.Scale; update.ProfileEnd = part.Shape.ProfileEnd;
update.Text = Util.StringToBytes256(data.Text); update.ProfileHollow = part.Shape.ProfileHollow;
update.MediaURL = Util.StringToBytes256(data.MediaUrl); update.PSBlock = part.ParticleSystem ?? Utils.EmptyBytes;
update.TextColor = part.GetTextColor().GetBytes(false);
update.TextureAnim = part.TextureAnimation ?? Utils.EmptyBytes;
update.TextureEntry = part.Shape.TextureEntry ?? Utils.EmptyBytes;
update.Scale = part.Shape.Scale;
update.Text = Util.StringToBytes(part.Text, 255);
update.MediaURL = Util.StringToBytes(part.MediaUrl, 255);
#region PrimFlags #region PrimFlags
PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp);
// Don't send the CreateSelected flag to everyone // Don't send the CreateSelected flag to everyone
flags &= ~PrimFlags.CreateSelected; flags &= ~PrimFlags.CreateSelected;
if (recipientID == data.OwnerID) if (sp.UUID == part.OwnerID)
{ {
if (data.CreateSelected) if (part.CreateSelected)
{ {
// Only send this flag once, then unset it // Only send this flag once, then unset it
flags |= PrimFlags.CreateSelected; flags |= PrimFlags.CreateSelected;
data.CreateSelected = false; part.CreateSelected = false;
} }
} }
@ -5849,21 +5904,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion PrimFlags #endregion PrimFlags
if (data.Sound != UUID.Zero) if (part.Sound != UUID.Zero)
{ {
update.Sound = data.Sound; update.Sound = part.Sound;
update.OwnerID = data.OwnerID; update.OwnerID = part.OwnerID;
update.Gain = (float)data.SoundGain; update.Gain = (float)part.SoundGain;
update.Radius = (float)data.SoundRadius; update.Radius = (float)part.SoundRadius;
update.Flags = data.SoundFlags; update.Flags = part.SoundFlags;
} }
switch ((PCode)data.Shape.PCode) switch ((PCode)part.Shape.PCode)
{ {
case PCode.Grass: case PCode.Grass:
case PCode.Tree: case PCode.Tree:
case PCode.NewTree: case PCode.NewTree:
update.Data = new byte[] { data.Shape.State }; update.Data = new byte[] { part.Shape.State };
break; break;
default: default:
update.Data = Utils.EmptyBytes; update.Data = Utils.EmptyBytes;
@ -5941,10 +5996,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true); AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true); AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true); AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
@ -6131,8 +6186,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete);
AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete);
AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate);
AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true); AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate);
AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true); AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate);
AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights);
AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery);
AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry);
@ -6223,20 +6278,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param> /// <param name='x'></param>
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{ {
float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); if(Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA ||
if((vdelta > VDELTA)) Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA ||
return true; Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA ||
vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA ||
if((vdelta > VDELTA)) Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA ||
return true; // Math.Abs(x.CameraAtAxis.Z - m_thisAgentUpdateArgs.CameraAtAxis.Z) > VDELTA ||
vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); Math.Abs(x.CameraLeftAxis.X - m_thisAgentUpdateArgs.CameraLeftAxis.X) > VDELTA ||
if((vdelta > VDELTA)) Math.Abs(x.CameraLeftAxis.Y - m_thisAgentUpdateArgs.CameraLeftAxis.Y) > VDELTA ||
return true; // Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA ||
if((vdelta > VDELTA)) Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA
// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
)
return true; return true;
return false; return false;
@ -6342,6 +6399,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = ParcelGodMarkAsContentPacket ParcelGodMarkAsContent =
(ParcelGodMarkAsContentPacket)Packet; (ParcelGodMarkAsContentPacket)Packet;
if(SessionId != ParcelGodMarkAsContent.AgentData.SessionID || AgentId != ParcelGodMarkAsContent.AgentData.AgentID)
return false;
ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark;
if (ParcelGodMarkAsContentHandler != null) if (ParcelGodMarkAsContentHandler != null)
{ {
@ -6357,6 +6417,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet;
if(SessionId != FreezeUser.AgentData.SessionID || AgentId != FreezeUser.AgentData.AgentID)
return false;
FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser;
if (FreezeUserHandler != null) if (FreezeUserHandler != null)
{ {
@ -6374,6 +6437,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
EjectUserPacket EjectUser = EjectUserPacket EjectUser =
(EjectUserPacket)Packet; (EjectUserPacket)Packet;
if(SessionId != EjectUser.AgentData.SessionID || AgentId != EjectUser.AgentData.AgentID)
return false;
EjectUserUpdate EjectUserHandler = OnParcelEjectUser; EjectUserUpdate EjectUserHandler = OnParcelEjectUser;
if (EjectUserHandler != null) if (EjectUserHandler != null)
{ {
@ -6391,6 +6457,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ParcelBuyPassPacket ParcelBuyPass = ParcelBuyPassPacket ParcelBuyPass =
(ParcelBuyPassPacket)Packet; (ParcelBuyPassPacket)Packet;
if(SessionId != ParcelBuyPass.AgentData.SessionID || AgentId != ParcelBuyPass.AgentData.AgentID)
return false;
ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass;
if (ParcelBuyPassHandler != null) if (ParcelBuyPassHandler != null)
{ {
@ -6423,8 +6492,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack)
{ {
UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; ScenePresence sp = (ScenePresence)SceneAgent;
if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit))
return true;
UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack;
for (int i = 0; i < upack.UUIDNameBlock.Length; i++) for (int i = 0; i < upack.UUIDNameBlock.Length; i++)
{ {
@ -7443,7 +7515,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendUserInfoReply(false, true, ""); SendUserInfoReply(false, true, "");
} }
return true; return true;
} }
private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack) private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack)
@ -7753,10 +7824,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ObjectDuplicate handlerObjectDuplicate = null; ObjectDuplicate handlerObjectDuplicate = null;
for (int i = 0; i < dupe.ObjectData.Length; i++)
{
handlerObjectDuplicate = OnObjectDuplicate; handlerObjectDuplicate = OnObjectDuplicate;
if (handlerObjectDuplicate != null) if (handlerObjectDuplicate != null)
{
for (int i = 0; i < dupe.ObjectData.Length; i++)
{ {
UUID rezGroupID = dupe.AgentData.GroupID; UUID rezGroupID = dupe.AgentData.GroupID;
if(!IsGroupMember(rezGroupID)) if(!IsGroupMember(rezGroupID))
@ -7978,19 +8049,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
Dictionary<uint, uint> objImageSeqs = null;
double lastobjImageSeqsMS = 0.0;
private bool HandleObjectImage(IClientAPI sender, Packet Pack) private bool HandleObjectImage(IClientAPI sender, Packet Pack)
{ {
ObjectImagePacket imagePack = (ObjectImagePacket)Pack; ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
UpdatePrimTexture handlerUpdatePrimTexture = null; UpdatePrimTexture handlerUpdatePrimTexture = OnUpdatePrimTexture;
if (handlerUpdatePrimTexture == null)
return true;
double now = Util.GetTimeStampMS();
if(objImageSeqs == null || ( now - lastobjImageSeqsMS > 30000.0))
{
objImageSeqs = null; // yeah i know superstition...
objImageSeqs = new Dictionary<uint, uint>(16);
}
lastobjImageSeqsMS = now;
uint seq = Pack.Header.Sequence;
uint id;
uint lastseq;
ObjectImagePacket.ObjectDataBlock o;
for (int i = 0; i < imagePack.ObjectData.Length; i++) for (int i = 0; i < imagePack.ObjectData.Length; i++)
{ {
handlerUpdatePrimTexture = OnUpdatePrimTexture; o = imagePack.ObjectData[i];
if (handlerUpdatePrimTexture != null) id = o.ObjectLocalID;
if(objImageSeqs.TryGetValue(id, out lastseq))
{ {
handlerUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, if(seq <= lastseq)
imagePack.ObjectData[i].TextureEntry, this); continue;
} }
objImageSeqs[id] = seq;
handlerUpdatePrimTexture(id, o.TextureEntry, this);
} }
return true; return true;
} }
@ -9598,6 +9691,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack) private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack)
{ {
ScenePresence sp = (ScenePresence)SceneAgent;
if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit))
return true;
UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack;
foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
@ -12515,11 +12612,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
int maxWearablesLoop = cachedtex.WearableData.Length; int maxWearablesLoop = cachedtex.WearableData.Length;
if (maxWearablesLoop > cacheItems.Length)
maxWearablesLoop = cacheItems.Length;
if (cacheItems != null) if (cacheItems != null)
{ {
if (maxWearablesLoop > cacheItems.Length)
maxWearablesLoop = cacheItems.Length;
for (int i = 0; i < maxWearablesLoop; i++) for (int i = 0; i < maxWearablesLoop; i++)
{ {
int idx = cachedtex.WearableData[i].TextureIndex; int idx = cachedtex.WearableData[i].TextureIndex;
@ -13354,7 +13451,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendAssetNotFound(req); SendAssetNotFound(req);
return; return;
} }
} }
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
@ -13431,11 +13527,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
public bool Async { get; set; } public bool Async { get; set; }
/// <summary>
/// If async is true, should this packet be handled in the async engine or given directly to a threadpool
/// thread?
/// </summary>
public bool InEngine { get; set; }
} }
public class AsyncPacketProcess public class AsyncPacketProcess

View File

@ -312,9 +312,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// stack. Use zero to leave this value as the default</summary> /// stack. Use zero to leave this value as the default</summary>
protected int m_recvBufferSize; protected int m_recvBufferSize;
/// <summary>Flag to process packets asynchronously or synchronously</summary>
protected bool m_asyncPacketHandling;
/// <summary>Tracks whether or not a packet was sent each round so we know /// <summary>Tracks whether or not a packet was sent each round so we know
/// whether or not to sleep</summary> /// whether or not to sleep</summary>
protected bool m_packetSent; protected bool m_packetSent;
@ -417,7 +414,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Queue some low priority but potentially high volume async requests so that they don't overwhelm available /// Queue some low priority but potentially high volume async requests so that they don't overwhelm available
/// threadpool threads. /// threadpool threads.
/// </summary> /// </summary>
public JobEngine IpahEngine { get; protected set; } // public JobEngine IpahEngine { get; protected set; }
/// <summary> /// <summary>
/// Run queue empty processing within a single persistent thread. /// Run queue empty processing within a single persistent thread.
@ -473,7 +470,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
IConfig config = configSource.Configs["ClientStack.LindenUDP"]; IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null) if (config != null)
{ {
m_asyncPacketHandling = config.GetBoolean("async_packet_handling", true);
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
@ -531,7 +527,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
StartInbound(); StartInbound();
StartOutbound(); StartOutbound();
IpahEngine.Start(); // IpahEngine.Start();
OqrEngine.Start(); OqrEngine.Start();
m_elapsedMSSinceLastStatReport = Environment.TickCount; m_elapsedMSSinceLastStatReport = Environment.TickCount;
@ -540,10 +536,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void StartInbound() public void StartInbound()
{ {
m_log.InfoFormat( m_log.InfoFormat(
"[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server");
m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); base.StartInbound(m_recvBufferSize);
// This thread will process the packets received that are placed on the packetInbox // This thread will process the packets received that are placed on the packetInbox
WorkManager.StartThread( WorkManager.StartThread(
@ -577,7 +572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name); m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
base.StopOutbound(); base.StopOutbound();
base.StopInbound(); base.StopInbound();
IpahEngine.Stop(); // IpahEngine.Stop();
OqrEngine.Stop(); OqrEngine.Stop();
} }
@ -696,12 +691,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Scene = (Scene)scene; Scene = (Scene)scene;
m_location = new Location(Scene.RegionInfo.RegionHandle); m_location = new Location(Scene.RegionInfo.RegionHandle);
/*
IpahEngine IpahEngine
= new JobEngine( = new JobEngine(
string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
"INCOMING PACKET ASYNC HANDLING ENGINE"); "INCOMING PACKET ASYNC HANDLING ENGINE");
*/
OqrEngine OqrEngine
= new JobEngine( = new JobEngine(
string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
@ -786,7 +781,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MeasuresOfInterest.AverageChangeOverTime, MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = GetTotalQueuedOutgoingPackets(), stat => stat.Value = GetTotalQueuedOutgoingPackets(),
StatVerbosity.Info)); StatVerbosity.Info));
/*
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
"IncomingPacketAsyncRequestsWaiting", "IncomingPacketAsyncRequestsWaiting",
@ -799,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MeasuresOfInterest.None, MeasuresOfInterest.None,
stat => stat.Value = IpahEngine.JobsWaiting, stat => stat.Value = IpahEngine.JobsWaiting,
StatVerbosity.Debug)); StatVerbosity.Debug));
*/
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
"OQRERequestsWaiting", "OQRERequestsWaiting",
@ -1227,7 +1222,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name); outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name);
// Put the UDP payload on the wire // Put the UDP payload on the wire
AsyncBeginSend(buffer); // AsyncBeginSend(buffer);
SyncSend(buffer);
// Keep track of when this packet was sent out (right now) // Keep track of when this packet was sent out (right now)
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
@ -1912,7 +1908,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
AsyncBeginSend(buffer); // AsyncBeginSend(buffer);
SyncSend(buffer);
} }
protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)

View File

@ -57,9 +57,6 @@ namespace OpenMetaverse
/// <summary>UDP socket, used in either client or server mode</summary> /// <summary>UDP socket, used in either client or server mode</summary>
private Socket m_udpSocket; private Socket m_udpSocket;
/// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling;
/// <summary> /// <summary>
/// Are we to use object pool(s) to reduce memory churn when receiving data? /// Are we to use object pool(s) to reduce memory churn when receiving data?
/// </summary> /// </summary>
@ -205,10 +202,8 @@ namespace OpenMetaverse
/// manner (not throwing an exception when the remote side resets the /// manner (not throwing an exception when the remote side resets the
/// connection). This call is ignored on Mono where the flag is not /// connection). This call is ignored on Mono where the flag is not
/// necessary</remarks> /// necessary</remarks>
public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling) public virtual void StartInbound(int recvBufferSize)
{ {
m_asyncPacketHandling = asyncPacketHandling;
if (!IsRunningInbound) if (!IsRunningInbound)
{ {
m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop"); m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop");
@ -408,11 +403,6 @@ namespace OpenMetaverse
{ {
UdpReceives++; UdpReceives++;
// Asynchronous mode will start another receive before the
// callback for this packet is even fired. Very parallel :-)
if (m_asyncPacketHandling)
AsyncBeginReceive();
try try
{ {
// get the buffer that was created in AsyncBeginReceive // get the buffer that was created in AsyncBeginReceive
@ -469,9 +459,6 @@ namespace OpenMetaverse
// if (UsePools) // if (UsePools)
// Pool.ReturnObject(buffer); // Pool.ReturnObject(buffer);
// Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet
if (!m_asyncPacketHandling)
AsyncBeginReceive(); AsyncBeginReceive();
} }
} }
@ -500,7 +487,7 @@ namespace OpenMetaverse
} }
catch (SocketException) { } catch (SocketException) { }
catch (ObjectDisposedException) { } catch (ObjectDisposedException) { }
// } // }
} }
void AsyncEndSend(IAsyncResult result) void AsyncEndSend(IAsyncResult result)
@ -515,5 +502,25 @@ namespace OpenMetaverse
catch (SocketException) { } catch (SocketException) { }
catch (ObjectDisposedException) { } catch (ObjectDisposedException) { }
} }
public void SyncSend(UDPPacketBuffer buf)
{
try
{
m_udpSocket.SendTo(
buf.Data,
0,
buf.DataLength,
SocketFlags.None,
buf.RemoteEndPoint
);
UdpSends++;
}
catch (SocketException e)
{
m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message);
}
catch (ObjectDisposedException) { }
}
} }
} }

View File

@ -91,6 +91,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
/// <summary> /// <summary>
/// Test adding a client to the stack /// Test adding a client to the stack
/// </summary> /// </summary>
/*
[Test] [Test]
public void TestAddClient() public void TestAddClient()
{ {
@ -165,7 +166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
Assert.That(spAfterAckTimeout, Is.Null); Assert.That(spAfterAckTimeout, Is.Null);
} }
*/
// /// <summary> // /// <summary>
// /// Test removing a client from the stack // /// Test removing a client from the stack
// /// </summary> // /// </summary>

View File

@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{ {
m_uploadState = UploadState.Complete; m_uploadState = UploadState.Complete;
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); bool sucess = true;
if (m_createItem) if (m_createItem)
{ {
CompleteCreateItem(m_createItemCallback); sucess = CompleteCreateItem(m_createItemCallback);
} }
else if (m_updateItem) else if (m_updateItem)
{ {
CompleteItemUpdate(m_updateItemData); sucess = CompleteItemUpdate(m_updateItemData);
} }
else if (m_updateTaskItem) else if (m_updateTaskItem)
{ {
CompleteTaskItemUpdate(m_updateTaskItemData); sucess = CompleteTaskItemUpdate(m_updateTaskItemData);
} }
else if (m_asset.Local) else if (m_asset.Local)
{ {
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
} }
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID);
} }
m_log.DebugFormat( m_log.DebugFormat(
@ -411,46 +411,70 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// Store the asset for the given item when it has been uploaded. /// Store the asset for the given item when it has been uploaded.
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
private void CompleteItemUpdate(InventoryItemBase item) private bool CompleteItemUpdate(InventoryItemBase item)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
// m_asset.FullID, item.Name, ourClient.Name); // m_asset.FullID, item.Name, ourClient.Name);
ValidateAssets(); uint perms = ValidateAssets();
if(perms == 0)
{
string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', update failed", item.Name);
ourClient.SendAlertMessage(error);
m_transactions.RemoveXferUploader(m_transactionID);
ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache
}
else
{
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
if (m_asset.FullID != UUID.Zero) if (m_asset.FullID != UUID.Zero)
{ {
item.AssetID = m_asset.FullID; item.AssetID = m_asset.FullID;
m_Scene.InventoryService.UpdateItem(item); m_Scene.InventoryService.UpdateItem(item);
} }
ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0); ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0); m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
} }
return perms != 0;
}
/// <summary> /// <summary>
/// Store the asset for the given task item when it has been uploaded. /// Store the asset for the given task item when it has been uploaded.
/// </summary> /// </summary>
/// <param name="taskItem"></param> /// <param name="taskItem"></param>
private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
// m_asset.FullID, taskItem.Name, ourClient.Name); // m_asset.FullID, taskItem.Name, ourClient.Name);
ValidateAssets(); if(ValidateAssets() == 0)
m_Scene.AssetService.Store(m_asset); {
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
string error = string.Format("Not enough permissions on asset(s) referenced by task item '{0}', update failed", taskItem.Name);
ourClient.SendAlertMessage(error);
// force old asset to viewers ??
return false;
} }
private void CompleteCreateItem(uint callbackID) m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID);
return true;
}
private bool CompleteCreateItem(uint callbackID)
{ {
ValidateAssets(); if(ValidateAssets() == 0)
{
m_transactions.RemoveXferUploader(m_transactionID);
string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', creation failed", m_name);
ourClient.SendAlertMessage(error);
return false;
}
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
InventoryItemBase item = new InventoryItemBase(); InventoryItemBase item = new InventoryItemBase();
@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
ourClient.SendAlertMessage("Unable to create inventory item"); ourClient.SendAlertMessage("Unable to create inventory item");
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
return true;
} }
private uint ValidateAssets()
private void ValidateAssets()
{ {
uint retPerms = 0x7fffffff;
// if(m_Scene.Permissions.BypassPermissions())
// return retPerms;
if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet) if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
{ {
AnimationSet animSet = new AnimationSet(m_asset.Data); AnimationSet animSet = new AnimationSet(m_asset.Data);
bool allOk = animSet.Validate(x => { retPerms &= animSet.Validate(x => {
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x); const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy);
int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
// currrent yes/no rule
if ((perms & required) != required) if ((perms & required) != required)
return false; return 0;
return true; return perms;
}); });
if (!allOk) return retPerms;
m_asset.Data = animSet.ToBytes();
} }
if (m_asset.Type == (sbyte)AssetType.Clothing || if (m_asset.Type == (sbyte)AssetType.Clothing ||
m_asset.Type == (sbyte)AssetType.Bodypart) m_asset.Type == (sbyte)AssetType.Bodypart)
{ {
const uint texturesfullPermMask = (uint)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
string[] lines = content.Split(new char[] {'\n'}); string[] lines = content.Split(new char[] {'\n'});
List<string> validated = new List<string>(); // on current requiriment of full rigths assume old assets where accepted
Dictionary<int, UUID> allowed = ExtractTexturesFromOldData(); Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
int textures = 0; int textures = 0;
@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
try try
{ {
if (line.StartsWith("textures ")) if (line.StartsWith("textures "))
{
textures = Convert.ToInt32(line.Substring(9)); textures = Convert.ToInt32(line.Substring(9));
validated.Add(line);
}
else if (textures > 0) else if (textures > 0)
{ {
string[] parts = line.Split(new char[] {' '}); string[] parts = line.Split(new char[] {' '});
@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
if (defaultIDs.Contains(tx) || tx == UUID.Zero || if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
(allowed.ContainsKey(id) && allowed[id] == tx)) (allowed.ContainsKey(id) && allowed[id] == tx))
{ {
validated.Add(parts[0] + " " + tx.ToString()); continue;
} }
else else
{ {
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
if ((perms & full) != full) if ((perms & texturesfullPermMask) != texturesfullPermMask)
{ {
m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
validated.Add(parts[0] + " " + UUID.Zero.ToString()); return 0;
} }
else else
{ {
validated.Add(line); retPerms &= perms;
} }
} }
textures--; textures--;
} }
else
{
validated.Add(line);
}
} }
catch catch
{ {
// If it's malformed, skip it // If it's malformed, skip it
} }
} }
string final = String.Join("\n", validated.ToArray());
m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
} }
return retPerms;
} }
/* not in use
/// <summary> /// <summary>
/// Get the asset data uploaded in this transfer. /// Get the asset data uploaded in this transfer.
/// </summary> /// </summary>
@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
return null; return null;
} }
*/
public void SetOldData(byte[] d) public void SetOldData(byte[] d)
{ {
m_oldData = d; m_oldData = d;

View File

@ -53,9 +53,9 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan
if (bans.Count > 0) if (bans.Count > 0)
{ {
IClientIPEndpoint ipEndpoint; IClientIPEndpoint ipEndpoint;
if (client.TryGet(out ipEndpoint)) if (client.TryGet(out ipEndpoint) && ipEndpoint.RemoteEndPoint != null)
{ {
IPAddress end = ipEndpoint.EndPoint; IPAddress end = ipEndpoint.RemoteEndPoint.Address;
try try
{ {

View File

@ -369,7 +369,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
else if (Cache != null) else if (Cache != null)
{ {
string assetName = "j2kCache_" + AssetId.ToString(); string assetName = "j2kCache_" + AssetId.ToString();
AssetBase layerDecodeAsset = Cache.Get(assetName); AssetBase layerDecodeAsset;
Cache.Get(assetName, out layerDecodeAsset);
if (layerDecodeAsset != null) if (layerDecodeAsset != null)
{ {

View File

@ -260,10 +260,9 @@ namespace OpenSim.Region.CoreModules.Asset
/// Cache doesn't guarantee in any situation that asset is stored to it. /// Cache doesn't guarantee in any situation that asset is stored to it.
/// </para> /// </para>
/// </remarks> /// </remarks>
public AssetBase Get(string id) public bool Get(string id, out AssetBase assetBase)
{ {
m_getCount++; m_getCount++;
AssetBase assetBase;
if (m_cache.TryGetValue(id, out assetBase)) if (m_cache.TryGetValue(id, out assetBase))
m_hitCount++; m_hitCount++;
@ -284,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Asset
// if (null == assetBase) // if (null == assetBase)
// m_log.DebugFormat("[CENOME ASSET CACHE]: Asset {0} not in cache", id); // m_log.DebugFormat("[CENOME ASSET CACHE]: Asset {0} not in cache", id);
return assetBase; return true;
} }
#endregion #endregion

View File

@ -115,7 +115,10 @@ namespace OpenSim.Region.CoreModules.Asset
public bool Check(string id) public bool Check(string id)
{ {
// XXX This is probably not an efficient implementation. // XXX This is probably not an efficient implementation.
return Get(id) != null; AssetBase asset;
if (!Get(id, out asset))
return false;
return asset != null;
} }
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
@ -129,9 +132,10 @@ namespace OpenSim.Region.CoreModules.Asset
// We don't do negative caching // We don't do negative caching
} }
public AssetBase Get(string id) public bool Get(string id, out AssetBase asset)
{ {
return (AssetBase)m_Cache.Get(id); asset = (AssetBase)m_Cache.Get(id);
return true;
} }
public void Expire(string id) public void Expire(string id)

View File

@ -474,6 +474,8 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{ {
if (stream.Length == 0) // Empty file will trigger exception below
return null;
BinaryFormatter bformatter = new BinaryFormatter(); BinaryFormatter bformatter = new BinaryFormatter();
asset = (AssetBase)bformatter.Deserialize(stream); asset = (AssetBase)bformatter.Deserialize(stream);
@ -531,15 +533,26 @@ namespace OpenSim.Region.CoreModules.Asset
return found; return found;
} }
// For IAssetService
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
AssetBase asset;
Get(id, out asset);
return asset;
}
public bool Get(string id, out AssetBase asset)
{
asset = null;
m_Requests++; m_Requests++;
object dummy; object dummy;
if (m_negativeCache.TryGetValue(id, out dummy)) if (m_negativeCache.TryGetValue(id, out dummy))
return null; {
return false;
}
AssetBase asset = null;
asset = GetFromWeakReference(id); asset = GetFromWeakReference(id);
if (asset != null && m_updateFileTimeOnCacheHit) if (asset != null && m_updateFileTimeOnCacheHit)
{ {
@ -578,13 +591,7 @@ namespace OpenSim.Region.CoreModules.Asset
GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l));
} }
if(asset == null) return true;
{
}
return asset;
} }
public bool Check(string id) public bool Check(string id)
@ -599,7 +606,9 @@ namespace OpenSim.Region.CoreModules.Asset
public AssetBase GetCached(string id) public AssetBase GetCached(string id)
{ {
return Get(id); AssetBase asset;
Get(id, out asset);
return asset;
} }
public void Expire(string id) public void Expire(string id)
@ -637,7 +646,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_LogLevel >= 2) if (m_LogLevel >= 2)
m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing caches."); m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing caches.");
if (m_FileCacheEnabled) if (m_FileCacheEnabled && Directory.Exists(m_CacheDirectory))
{ {
foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
{ {
@ -672,9 +681,9 @@ namespace OpenSim.Region.CoreModules.Asset
// before cleaning up expired files we must scan the objects in the scene to make sure that we retain // before cleaning up expired files we must scan the objects in the scene to make sure that we retain
// such local assets if they have not been recently accessed. // such local assets if they have not been recently accessed.
TouchAllSceneAssets(false); TouchAllSceneAssets(false);
if(Directory.Exists(m_CacheDirectory))
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
{ {
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
CleanExpiredFiles(dir, purgeLine); CleanExpiredFiles(dir, purgeLine);
} }
@ -697,6 +706,9 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
try try
{ {
if(!Directory.Exists(dir))
return;
foreach (string file in Directory.GetFiles(dir)) foreach (string file in Directory.GetFiles(dir))
{ {
if (File.GetLastAccessTime(file) < purgeLine) if (File.GetLastAccessTime(file) < purgeLine)
@ -797,6 +809,9 @@ namespace OpenSim.Region.CoreModules.Asset
return; return;
} }
catch (UnauthorizedAccessException e)
{
}
finally finally
{ {
if (stream != null) if (stream != null)
@ -857,6 +872,9 @@ namespace OpenSim.Region.CoreModules.Asset
/// <returns></returns> /// <returns></returns>
private int GetFileCacheCount(string dir) private int GetFileCacheCount(string dir)
{ {
if(!Directory.Exists(dir))
return 0;
int count = Directory.GetFiles(dir).Length; int count = Directory.GetFiles(dir).Length;
foreach (string subdir in Directory.GetDirectories(dir)) foreach (string subdir in Directory.GetDirectories(dir))
@ -975,6 +993,9 @@ namespace OpenSim.Region.CoreModules.Asset
/// </summary> /// </summary>
private void ClearFileCache() private void ClearFileCache()
{ {
if(!Directory.Exists(m_CacheDirectory))
return;
foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
{ {
try try
@ -1147,7 +1168,7 @@ namespace OpenSim.Region.CoreModules.Asset
con.Output("FloatSam Ensuring assets are cached for all scenes."); con.Output("FloatSam Ensuring assets are cached for all scenes.");
WorkManager.RunInThread(delegate WorkManager.RunInThreadPool(delegate
{ {
bool wasRunning= false; bool wasRunning= false;
lock(timerLock) lock(timerLock)
@ -1227,19 +1248,23 @@ namespace OpenSim.Region.CoreModules.Asset
public AssetMetadata GetMetadata(string id) public AssetMetadata GetMetadata(string id)
{ {
AssetBase asset = Get(id); AssetBase asset;
Get(id, out asset);
return asset.Metadata; return asset.Metadata;
} }
public byte[] GetData(string id) public byte[] GetData(string id)
{ {
AssetBase asset = Get(id); AssetBase asset;
Get(id, out asset);
return asset.Data; return asset.Data;
} }
public bool Get(string id, object sender, AssetRetrieved handler) public bool Get(string id, object sender, AssetRetrieved handler)
{ {
AssetBase asset = Get(id); AssetBase asset;
if (!Get(id, out asset))
return false;
handler(id, sender, asset); handler(id, sender, asset);
return true; return true;
} }
@ -1270,7 +1295,9 @@ namespace OpenSim.Region.CoreModules.Asset
public bool UpdateContent(string id, byte[] data) public bool UpdateContent(string id, byte[] data)
{ {
AssetBase asset = Get(id); AssetBase asset;
if (!Get(id, out asset))
return false;
asset.Data = data; asset.Data = data;
Cache(asset); Cache(asset);
return true; return true;

View File

@ -131,14 +131,15 @@ namespace OpenSim.Region.CoreModules.Asset
// We don't do negative caching // We don't do negative caching
} }
public AssetBase Get(string id) public bool Get(string id, out AssetBase asset)
{ {
Object asset = null; Object a = null;
m_Cache.TryGet(id, out asset); m_Cache.TryGet(id, out a);
Debug(asset); Debug(a);
return (AssetBase)asset; asset = (AssetBase)a;
return true;
} }
public void Expire(string id) public void Expire(string id)

View File

@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using PermissionMask = OpenSim.Framework.PermissionMask;
namespace OpenSim.Region.CoreModules.Avatar.Attachments namespace OpenSim.Region.CoreModules.Avatar.Attachments
{ {
@ -481,14 +482,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
// group.Name, group.LocalId, sp.Name, attachmentPt, silent); // group.Name, group.LocalId, sp.Name, attachmentPt, silent);
if (sp.GetAttachments().Contains(group))
{
// m_log.WarnFormat(
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
// group.Name, group.LocalId, sp.Name, AttachmentPt);
return false;
}
if (group.GetSittingAvatarsCount() != 0) if (group.GetSittingAvatarsCount() != 0)
{ {
@ -500,6 +493,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return false; return false;
} }
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
if (attachments.Contains(group))
{
// if (DebugLevel > 0)
// m_log.WarnFormat(
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
// group.Name, group.LocalId, sp.Name, attachmentPt);
return false;
}
Vector3 attachPos = group.AbsolutePosition; Vector3 attachPos = group.AbsolutePosition;
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
@ -533,7 +537,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{ {
attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint; attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint;
attachPos = group.RootPart.AttachedPos; attachPos = group.RootPart.AttachedPos;
group.HasGroupChanged = true;
} }
// if we still didn't find a suitable attachment point....... // if we still didn't find a suitable attachment point.......
@ -544,18 +547,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
attachPos = Vector3.Zero; attachPos = Vector3.Zero;
} }
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
if (attachments.Contains(group))
{
if (DebugLevel > 0)
m_log.WarnFormat(
"[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
group.Name, group.LocalId, sp.Name, attachmentPt);
return false;
}
// If we already have 5, remove the oldest until only 4 are left. Skip over temp ones // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
while (attachments.Count >= 5) while (attachments.Count >= 5)
{ {
@ -579,7 +570,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
lock (sp.AttachmentsSyncLock) lock (sp.AttachmentsSyncLock)
{ {
group.AttachmentPoint = attachmentPt; group.AttachmentPoint = attachmentPt;
group.AbsolutePosition = attachPos; group.RootPart.AttachedPos = attachPos;
if (addToInventory && sp.PresenceType != PresenceType.Npc) if (addToInventory && sp.PresenceType != PresenceType.Npc)
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
@ -906,6 +897,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (item != null) if (item != null)
{ {
// attach is rez, need to update permissions
item.Flags &= ~(uint)(InventoryItemFlags.ObjectSlamPerm | InventoryItemFlags.ObjectOverwriteBase |
InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup |
InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner);
uint permsBase = (uint)(PermissionMask.Copy | PermissionMask.Transfer |
PermissionMask.Modify | PermissionMask.Move |
PermissionMask.Export | PermissionMask.FoldedMask);
permsBase &= grp.CurrentAndFoldedNextPermissions();
permsBase |= (uint)PermissionMask.Move;
item.BasePermissions = permsBase;
item.CurrentPermissions = permsBase;
item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask | (uint)PermissionMask.Move;
item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask;
item.GroupPermissions = permsBase & grp.RootPart.GroupMask;
item.CurrentPermissions &=
((uint)PermissionMask.Copy |
(uint)PermissionMask.Transfer |
(uint)PermissionMask.Modify |
(uint)PermissionMask.Move |
(uint)PermissionMask.Export |
(uint)PermissionMask.FoldedMask); // Preserve folded permissions ??
AssetBase asset = m_scene.CreateAsset( AssetBase asset = m_scene.CreateAsset(
grp.GetPartName(grp.LocalId), grp.GetPartName(grp.LocalId),
grp.GetPartDescription(grp.LocalId), grp.GetPartDescription(grp.LocalId),
@ -956,7 +971,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.DeleteFromStorage(so.UUID); m_scene.DeleteFromStorage(so.UUID);
m_scene.EventManager.TriggerParcelPrimCountTainted(); m_scene.EventManager.TriggerParcelPrimCountTainted();
so.AttachedAvatar = sp.UUID;
foreach (SceneObjectPart part in so.Parts) foreach (SceneObjectPart part in so.Parts)
{ {
@ -969,11 +983,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
} }
so.AbsolutePosition = attachOffset;
so.RootPart.AttachedPos = attachOffset;
so.IsAttachment = true;
so.RootPart.SetParentLocalId(sp.LocalId); so.RootPart.SetParentLocalId(sp.LocalId);
so.AttachedAvatar = sp.UUID;
so.AttachmentPoint = attachmentpoint; so.AttachmentPoint = attachmentpoint;
so.RootPart.AttachedPos = attachOffset;
so.AbsolutePosition = attachOffset;
so.IsAttachment = true;
sp.AddAttachment(so); sp.AddAttachment(so);
@ -1322,7 +1337,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (part == null) if (part == null)
return; return;
if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) SceneObjectGroup group = part.ParentGroup;
if (!m_scene.Permissions.CanTakeObject(group, sp))
{ {
remoteClient.SendAgentAlertMessage( remoteClient.SendAgentAlertMessage(
"You don't have sufficient permissions to attach this object", false); "You don't have sufficient permissions to attach this object", false);
@ -1334,7 +1351,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
AttachmentPt &= 0x7f; AttachmentPt &= 0x7f;
// Calls attach with a Zero position // Calls attach with a Zero position
SceneObjectGroup group = part.ParentGroup;
if (AttachObject(sp, group , AttachmentPt, false, true, append)) if (AttachObject(sp, group , AttachmentPt, false, true, append))
{ {
if (DebugLevel > 0) if (DebugLevel > 0)

View File

@ -299,7 +299,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (bakedTextureFace == null) if (bakedTextureFace == null)
continue; continue;
AssetBase asset = cache.Get(bakedTextureFace.TextureID.ToString()); AssetBase asset;
cache.Get(bakedTextureFace.TextureID.ToString(), out asset);
if (asset != null && asset.Local) if (asset != null && asset.Local)
{ {
@ -368,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return true; return true;
// uploaded baked textures will be in assets local cache // uploaded baked textures will be in assets local cache
IAssetService cache = m_scene.AssetService; IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>();
IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
int validDirtyBakes = 0; int validDirtyBakes = 0;
@ -384,7 +385,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
List<UUID> missing = new List<UUID>(); List<UUID> missing = new List<UUID>();
bool haveSkirt = (wearableCache[19].TextureAsset != null); bool haveSkirt = (wearableCache[19].TextureID != UUID.Zero);
bool haveNewSkirt = false; bool haveNewSkirt = false;
// Process received baked textures // Process received baked textures
@ -435,7 +436,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
*/ */
wearableCache[idx].TextureAsset = null; wearableCache[idx].TextureAsset = null;
if (cache != null) if (cache != null)
wearableCache[idx].TextureAsset = cache.GetCached(face.TextureID.ToString()); {
AssetBase asb = null;
cache.Get(face.TextureID.ToString(), out asb);
wearableCache[idx].TextureAsset = asb;
}
if (wearableCache[idx].TextureAsset != null) if (wearableCache[idx].TextureAsset != null)
{ {
@ -480,25 +485,26 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// if we got a full set of baked textures save all in BakedTextureModule // if we got a full set of baked textures save all in BakedTextureModule
if (m_BakedTextureModule != null) if (m_BakedTextureModule != null)
{ {
m_log.Debug("[UpdateBakedCache] start async uploading to bakedModule cache"); m_log.DebugFormat("[UpdateBakedCache] Uploading to Bakes Server: cache hits: {0} changed entries: {1} rebakes {2}",
hits.ToString(), validDirtyBakes.ToString(), missing.Count);
m_BakedTextureModule.Store(sp.UUID, wearableCache); m_BakedTextureModule.Store(sp.UUID, wearableCache);
} }
} }
else
m_log.DebugFormat("[UpdateBakedCache] cache hits: {0} changed entries: {1} rebakes {2}",
hits.ToString(), validDirtyBakes.ToString(), missing.Count);
// debug
m_log.Debug("[UpdateBakedCache] cache hits: " + hits.ToString() + " changed entries: " + validDirtyBakes.ToString() + " rebakes " + missing.Count);
/*
for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
{ {
int j = AvatarAppearance.BAKE_INDICES[iter]; int j = AvatarAppearance.BAKE_INDICES[iter];
m_log.Debug("[UpdateBCache] {" + iter + "/" + sp.Appearance.WearableCacheItems[j].TextureAsset = null;
sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + // m_log.Debug("[UpdateBCache] {" + iter + "/" +
sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + // sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" +
sp.Appearance.WearableCacheItems[j].TextureID); // sp.Appearance.WearableCacheItems[j].CacheId + ", t-" +
// sp.Appearance.WearableCacheItems[j].TextureID);
} }
*/
return (hits == cacheItems.Length); return (hits == cacheItems.Length);
} }
@ -512,7 +518,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
lock (m_setAppearanceLock) lock (m_setAppearanceLock)
{ {
IAssetService cache = m_scene.AssetService; IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>();
IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
WearableCacheItem[] bakedModuleCache = null; WearableCacheItem[] bakedModuleCache = null;
@ -552,6 +558,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
} }
} }
*/ */
bool wearableCacheValid = false; bool wearableCacheValid = false;
if (wearableCache == null) if (wearableCache == null)
{ {
@ -576,10 +583,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
hits++; hits++;
wearableCache[idx].TextureAsset.Temporary = true; wearableCache[idx].TextureAsset.Temporary = true;
wearableCache[idx].TextureAsset.Local = true; wearableCache[idx].TextureAsset.Local = true;
cache.Store(wearableCache[idx].TextureAsset); cache.Cache(wearableCache[idx].TextureAsset);
wearableCache[idx].TextureAsset = null;
continue; continue;
} }
if (cache.GetCached((wearableCache[idx].TextureID).ToString()) != null)
if (cache.Check((wearableCache[idx].TextureID).ToString()))
{ {
hits++; hits++;
continue; continue;
@ -644,7 +653,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset; wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
bakedModuleCache[i].TextureAsset.Temporary = true; bakedModuleCache[i].TextureAsset.Temporary = true;
bakedModuleCache[i].TextureAsset.Local = true; bakedModuleCache[i].TextureAsset.Local = true;
cache.Store(bakedModuleCache[i].TextureAsset); cache.Cache(bakedModuleCache[i].TextureAsset);
} }
} }
gotbacked = true; gotbacked = true;
@ -676,6 +685,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
face.TextureID = wearableCache[idx].TextureID; face.TextureID = wearableCache[idx].TextureID;
hits++; hits++;
wearableCache[idx].TextureAsset = null;
} }
} }
} }
@ -705,7 +715,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return 0; return 0;
int texturesRebaked = 0; int texturesRebaked = 0;
// IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>();
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
@ -721,18 +731,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (missingTexturesOnly) if (missingTexturesOnly)
{ {
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) if (cache != null && cache.Check(face.TextureID.ToString()))
{ {
continue; continue;
} }
else else
{ {
// On inter-simulator teleports, this occurs if baked textures are not being stored by the
// grid asset service (which means that they are not available to the new region and so have
// to be re-requested from the client).
//
// The only available core OpenSimulator behaviour right now
// is not to store these textures, temporarily or otherwise.
m_log.DebugFormat( m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name); face.TextureID, idx, sp.Name);

View File

@ -216,6 +216,8 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
rc.Request(reqStream, m_Auth); rc.Request(reqStream, m_Auth);
m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", numberWears, agentId); m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", numberWears, agentId);
} }
if(reqStream != null)
reqStream.Dispose();
}, null, "XBakesModule.Store" }, null, "XBakesModule.Store"
); );
} }

View File

@ -247,11 +247,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
FriendInfo[] friends = GetFriendsFromCache(principalID); FriendInfo[] friends = GetFriendsFromCache(principalID);
FriendInfo finfo = GetFriend(friends, friendID); FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null) if (finfo != null && finfo.TheirFlags != -1)
{ {
return finfo.TheirFlags; return finfo.TheirFlags;
} }
return 0; return 0;
} }
@ -512,7 +511,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1)) if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi); friendList.Add(fi);
} }
if(friendList.Count > 0)
{
Util.FireAndForget( Util.FireAndForget(
delegate delegate
{ {
@ -526,6 +526,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
); );
} }
} }
}
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{ {
@ -552,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// We do this regrouping so that we can efficiently send a single request rather than one for each // We do this regrouping so that we can efficiently send a single request rather than one for each
// friend in what may be a very large friends list. // friend in what may be a very large friends list.
PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray()); PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray());
if(friendSessions == null)
return;
foreach (PresenceInfo friendSession in friendSessions) foreach (PresenceInfo friendSession in friendSessions)
{ {
@ -752,7 +755,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (friend == null) if (friend == null)
return; return;
if((friend.TheirFlags & (int)FriendRights.CanSeeOnMap) == 0) if(friend.TheirFlags == -1 || (friend.TheirFlags & (int)FriendRights.CanSeeOnMap) == 0)
return; return;
Scene hunterScene = (Scene)remoteClient.Scene; Scene hunterScene = (Scene)remoteClient.Scene;

View File

@ -65,9 +65,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override byte[] ProcessRequest( protected override byte[] ProcessRequest(
string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) string path, Stream requestData, 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

@ -214,7 +214,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
FriendInfo[] friends = GetFriendsFromCache(client.AgentId); FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
foreach (FriendInfo f in friends) foreach (FriendInfo f in friends)
{ {
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); int rights = f.TheirFlags;
if(rights != -1 )
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, rights);
} }
} }
} }

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