Merge branch 'master' into httptests
commit
ca4804b758
|
@ -114,7 +114,6 @@ namespace OpenSim.OfflineIM
|
||||||
scene.ForEachClient(delegate(IClientAPI client)
|
scene.ForEachClient(delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
||||||
client.OnMuteListRequest -= OnMuteListRequest;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +161,6 @@ namespace OpenSim.OfflineIM
|
||||||
private void OnNewClient(IClientAPI client)
|
private void OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
||||||
client.OnMuteListRequest += OnMuteListRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RetrieveInstantMessages(IClientAPI client)
|
private void RetrieveInstantMessages(IClientAPI client)
|
||||||
|
@ -194,20 +192,6 @@ namespace OpenSim.OfflineIM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apparently this is needed in order for the viewer to request the IMs.
|
|
||||||
private void OnMuteListRequest(IClientAPI client, uint crc)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
|
|
||||||
string filename = "mutes" + client.AgentId.ToString();
|
|
||||||
|
|
||||||
IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
|
|
||||||
if (xfer != null)
|
|
||||||
{
|
|
||||||
xfer.AddNewFile(filename, new Byte[0]);
|
|
||||||
client.SendMuteListUpdate(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UndeliveredMessage(GridInstantMessage im)
|
private void UndeliveredMessage(GridInstantMessage im)
|
||||||
{
|
{
|
||||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Npgsql;
|
||||||
|
using NpgsqlTypes;
|
||||||
|
|
||||||
|
namespace OpenSim.Data.PGSQL
|
||||||
|
{
|
||||||
|
public class PGSQLFSAssetData : IFSAssetDataPlugin
|
||||||
|
{
|
||||||
|
private const string _migrationStore = "FSAssetStore";
|
||||||
|
private static string m_Table = "fsassets";
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private long m_ticksToEpoch;
|
||||||
|
|
||||||
|
private PGSQLManager m_database;
|
||||||
|
private string m_connectionString;
|
||||||
|
|
||||||
|
public PGSQLFSAssetData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise(string connect, string realm, int UpdateAccessTime)
|
||||||
|
{
|
||||||
|
DaysBetweenAccessTimeUpdates = UpdateAccessTime;
|
||||||
|
|
||||||
|
m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
|
||||||
|
|
||||||
|
m_connectionString = connect;
|
||||||
|
m_database = new PGSQLManager(m_connectionString);
|
||||||
|
|
||||||
|
//New migration to check for DB changes
|
||||||
|
m_database.CheckMigration(_migrationStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of days that must pass before we update the access time on an asset when it has been fetched
|
||||||
|
/// Config option to change this is "DaysBetweenAccessTimeUpdates"
|
||||||
|
/// </summary>
|
||||||
|
private int DaysBetweenAccessTimeUpdates = 0;
|
||||||
|
|
||||||
|
protected virtual Assembly Assembly
|
||||||
|
{
|
||||||
|
get { return GetType().Assembly; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPlugin Members
|
||||||
|
|
||||||
|
public string Version { get { return "1.0.0.0"; } }
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "PGSQL FSAsset storage engine"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IFSAssetDataPlugin Members
|
||||||
|
|
||||||
|
public AssetMetadata Get(string id, out string hash)
|
||||||
|
{
|
||||||
|
hash = String.Empty;
|
||||||
|
AssetMetadata meta = null;
|
||||||
|
UUID uuid = new UUID(id);
|
||||||
|
|
||||||
|
string query = String.Format("select \"id\", \"type\", \"hash\", \"create_time\", \"access_time\", \"asset_flags\" from {0} where \"id\" = :id", m_Table);
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("id", uuid));
|
||||||
|
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
|
||||||
|
{
|
||||||
|
if (reader.Read())
|
||||||
|
{
|
||||||
|
meta = new AssetMetadata();
|
||||||
|
hash = reader["hash"].ToString();
|
||||||
|
meta.ID = id;
|
||||||
|
meta.FullID = uuid;
|
||||||
|
meta.Name = String.Empty;
|
||||||
|
meta.Description = String.Empty;
|
||||||
|
meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
|
||||||
|
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
|
||||||
|
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
|
||||||
|
meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
|
||||||
|
int atime = Convert.ToInt32(reader["access_time"]);
|
||||||
|
UpdateAccessTime(atime, uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateAccessTime(int AccessTime, UUID id)
|
||||||
|
{
|
||||||
|
// Reduce DB work by only updating access time if asset hasn't recently been accessed
|
||||||
|
// 0 By Default, Config option is "DaysBetweenAccessTimeUpdates"
|
||||||
|
if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("id", id));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Store(AssetMetadata meta, string hash)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
string oldhash;
|
||||||
|
AssetMetadata existingAsset = Get(meta.ID, out oldhash);
|
||||||
|
|
||||||
|
string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
|
||||||
|
if (existingAsset == null)
|
||||||
|
{
|
||||||
|
query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("hash", hash));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags)));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("create_time", now));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID);
|
||||||
|
m_log.Error(e.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the assets exist in the database.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uuids">The asset UUID's</param>
|
||||||
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
|
public bool[] AssetsExist(UUID[] uuids)
|
||||||
|
{
|
||||||
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
|
HashSet<UUID> exists = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string query = string.Format("select \"id\" from {1} where id in ({0})", ids, m_Table);
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UUID id = DBGuid.FromDB(reader["id"]);;
|
||||||
|
exists.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exists.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
string query = String.Format("select count(*) as count from {0}", m_Table);
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
IDataReader reader = cmd.ExecuteReader();
|
||||||
|
reader.Read();
|
||||||
|
count = Convert.ToInt32(reader["count"]);
|
||||||
|
reader.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string id)
|
||||||
|
{
|
||||||
|
string query = String.Format("delete from {0} where \"id\" = :id", m_Table);
|
||||||
|
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("id", new UUID(id)));
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
|
||||||
|
{
|
||||||
|
int imported = 0;
|
||||||
|
string limit = String.Empty;
|
||||||
|
if(count != -1)
|
||||||
|
{
|
||||||
|
limit = String.Format(" limit {0} offset {1}", start, count);
|
||||||
|
}
|
||||||
|
string query = String.Format("select * from {0}{1}", table, limit);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (NpgsqlConnection remote = new NpgsqlConnection(conn))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(query, remote))
|
||||||
|
{
|
||||||
|
remote.Open();
|
||||||
|
MainConsole.Instance.Output("Querying database");
|
||||||
|
MainConsole.Instance.Output("Reading data");
|
||||||
|
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
if ((imported % 100) == 0)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetBase asset = new AssetBase();
|
||||||
|
AssetMetadata meta = new AssetMetadata();
|
||||||
|
|
||||||
|
meta.ID = reader["id"].ToString();
|
||||||
|
meta.FullID = new UUID(meta.ID);
|
||||||
|
|
||||||
|
meta.Name = String.Empty;
|
||||||
|
meta.Description = String.Empty;
|
||||||
|
meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
|
||||||
|
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
|
||||||
|
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
|
||||||
|
|
||||||
|
asset.Metadata = meta;
|
||||||
|
asset.Data = (byte[])reader["data"];
|
||||||
|
|
||||||
|
store(asset, force);
|
||||||
|
|
||||||
|
imported++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[PGSQL FSASSETS]: Error importing assets: {0}",
|
||||||
|
e.Message.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
:VERSION 1
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
CREATE TABLE fsassets (
|
||||||
|
"id" uuid NOT NULL PRIMARY KEY,
|
||||||
|
"type" integer NOT NULL,
|
||||||
|
"hash" char(64) NOT NULL,
|
||||||
|
"create_time" integer NOT NULL DEFAULT '0',
|
||||||
|
"access_time" integer NOT NULL DEFAULT '0',
|
||||||
|
"asset_flags" integer NOT NULL DEFAULT '0'
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT;
|
|
@ -1209,10 +1209,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (group.GetInventoryItem(localID, itemID) != null)
|
if (group.GetInventoryItem(localID, itemID) != null)
|
||||||
{
|
{
|
||||||
if (item.Type == 10)
|
if (item.Type == (int)InventoryType.LSL)
|
||||||
{
|
{
|
||||||
part.RemoveScriptEvents(itemID);
|
part.RemoveScriptEvents(itemID);
|
||||||
EventManager.TriggerRemoveScript(localID, itemID);
|
part.ParentGroup.AddActiveScriptCount(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
group.RemoveInventoryItem(localID, itemID);
|
group.RemoveInventoryItem(localID, itemID);
|
||||||
|
@ -1317,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (taskItem.Type == (int)AssetType.LSLText)
|
if (taskItem.Type == (int)AssetType.LSLText)
|
||||||
{
|
{
|
||||||
part.RemoveScriptEvents(itemId);
|
part.RemoveScriptEvents(itemId);
|
||||||
EventManager.TriggerRemoveScript(part.LocalId, itemId);
|
part.ParentGroup.AddActiveScriptCount(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
part.Inventory.RemoveInventoryItem(itemId);
|
part.Inventory.RemoveInventoryItem(itemId);
|
||||||
|
|
|
@ -358,7 +358,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectPart part = parts[i];
|
SceneObjectPart part = parts[i];
|
||||||
|
|
||||||
if(m_DeepEffectivePermsInvalid)
|
if(m_DeepEffectivePermsInvalid)
|
||||||
part.AggregateInnerPerms();
|
part.AggregatedInnerPermsForGroup();
|
||||||
|
|
||||||
owner &= part.AggregatedInnerOwnerPerms;
|
owner &= part.AggregatedInnerOwnerPerms;
|
||||||
group &= part.AggregatedInnerGroupPerms;
|
group &= part.AggregatedInnerGroupPerms;
|
||||||
|
|
|
@ -2579,9 +2579,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AggregatedInnerOwnerPerms = owner & mask;
|
AggregatedInnerOwnerPerms = owner & mask;
|
||||||
AggregatedInnerGroupPerms = group & mask;
|
AggregatedInnerGroupPerms = group & mask;
|
||||||
AggregatedInnerEveryonePerms = everyone & mask;
|
AggregatedInnerEveryonePerms = everyone & mask;
|
||||||
|
}
|
||||||
if(ParentGroup != null)
|
if(ParentGroup != null)
|
||||||
ParentGroup.InvalidateEffectivePerms();
|
ParentGroup.InvalidateEffectivePerms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// same as above but called during group Effective Permission validation
|
||||||
|
public void AggregatedInnerPermsForGroup()
|
||||||
|
{
|
||||||
|
// assuming child prims permissions masks are irrelevant on a linkset
|
||||||
|
// root part is handle at SOG since its masks are the sog masks
|
||||||
|
const uint mask = (uint)PermissionMask.AllEffective;
|
||||||
|
|
||||||
|
uint owner = mask;
|
||||||
|
uint group = mask;
|
||||||
|
uint everyone = mask;
|
||||||
|
|
||||||
|
lock(InnerPermsLock) // do we really need this?
|
||||||
|
{
|
||||||
|
if(Inventory != null)
|
||||||
|
Inventory.AggregateInnerPerms(ref owner, ref group, ref everyone);
|
||||||
|
|
||||||
|
AggregatedInnerOwnerPerms = owner & mask;
|
||||||
|
AggregatedInnerGroupPerms = group & mask;
|
||||||
|
AggregatedInnerEveryonePerms = everyone & mask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 GetGeometricCenter()
|
public Vector3 GetGeometricCenter()
|
||||||
|
@ -3817,7 +3839,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Byte[] buf = Shape.Textures.GetBytes();
|
Byte[] buf = Shape.Textures.GetBytes();
|
||||||
Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
|
Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
|
||||||
Color4 texcolor;
|
Color4 texcolor;
|
||||||
if (face >= 0 && face < GetNumberOfSides())
|
int nsides = GetNumberOfSides();
|
||||||
|
if (face >= 0 && face < nsides)
|
||||||
{
|
{
|
||||||
texcolor = tex.CreateFace((uint)face).RGBA;
|
texcolor = tex.CreateFace((uint)face).RGBA;
|
||||||
texcolor.R = clippedColor.X;
|
texcolor.R = clippedColor.X;
|
||||||
|
@ -3833,7 +3856,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else if (face == ALL_SIDES)
|
else if (face == ALL_SIDES)
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < GetNumberOfSides(); i++)
|
for (uint i = 0; i < nsides; i++)
|
||||||
{
|
{
|
||||||
if (tex.FaceTextures[i] != null)
|
if (tex.FaceTextures[i] != null)
|
||||||
{
|
{
|
||||||
|
@ -5138,20 +5161,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
Changed changeFlags = 0;
|
Changed changeFlags = 0;
|
||||||
|
|
||||||
Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture;
|
Primitive.TextureEntryFace defaultNewFace = newTex.DefaultTexture;
|
||||||
Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture;
|
Primitive.TextureEntryFace defaultOldFace = oldTex.DefaultTexture;
|
||||||
|
|
||||||
// On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all
|
// On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all
|
||||||
// other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point.
|
// other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point.
|
||||||
if (fallbackNewFace == null)
|
if (defaultNewFace == null)
|
||||||
{
|
{
|
||||||
fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
|
defaultNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
|
||||||
newTex.DefaultTexture = fallbackNewFace;
|
newTex.DefaultTexture = defaultNewFace;
|
||||||
}
|
}
|
||||||
if (fallbackOldFace == null)
|
if (defaultOldFace == null)
|
||||||
{
|
{
|
||||||
fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
|
defaultOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
|
||||||
oldTex.DefaultTexture = fallbackOldFace;
|
oldTex.DefaultTexture = defaultOldFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Materials capable viewers can send a ObjectImage packet
|
// Materials capable viewers can send a ObjectImage packet
|
||||||
|
@ -5161,13 +5184,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// we should ignore any changes and not update Shape.TextureEntry
|
// we should ignore any changes and not update Shape.TextureEntry
|
||||||
|
|
||||||
bool otherFieldsChanged = false;
|
bool otherFieldsChanged = false;
|
||||||
|
int nsides = GetNumberOfSides();
|
||||||
for (int i = 0 ; i < GetNumberOfSides(); i++)
|
for (int i = 0 ; i < nsides; i++)
|
||||||
{
|
{
|
||||||
|
Primitive.TextureEntryFace newFace = defaultNewFace;
|
||||||
Primitive.TextureEntryFace newFace = newTex.DefaultTexture;
|
Primitive.TextureEntryFace oldFace = defaultOldFace;
|
||||||
Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture;
|
|
||||||
|
|
||||||
if (oldTex.FaceTextures[i] != null)
|
if (oldTex.FaceTextures[i] != null)
|
||||||
oldFace = oldTex.FaceTextures[i];
|
oldFace = oldTex.FaceTextures[i];
|
||||||
if (newTex.FaceTextures[i] != null)
|
if (newTex.FaceTextures[i] != null)
|
||||||
|
@ -5202,18 +5223,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true;
|
if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true;
|
||||||
if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true;
|
if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true;
|
||||||
if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true;
|
if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true;
|
||||||
|
if(otherFieldsChanged)
|
||||||
|
changeFlags |= Changed.TEXTURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeFlags != 0 || otherFieldsChanged)
|
if (changeFlags == 0)
|
||||||
{
|
return;
|
||||||
m_shape.TextureEntry = newTex.GetBytes();
|
m_shape.TextureEntry = newTex.GetBytes();
|
||||||
if (changeFlags != 0)
|
|
||||||
TriggerScriptChangedEvent(changeFlags);
|
TriggerScriptChangedEvent(changeFlags);
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
ScheduleFullUpdate();
|
ScheduleFullUpdate();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal void UpdatePhysicsSubscribedEvents()
|
internal void UpdatePhysicsSubscribedEvents()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
int type = m_items[itemID].InvType;
|
int type = m_items[itemID].InvType;
|
||||||
m_items.LockItemsForRead(false);
|
m_items.LockItemsForRead(false);
|
||||||
if (type == 10) // Script
|
if (type == (int)InventoryType.LSL) // Script
|
||||||
{
|
{
|
||||||
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
|
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1101,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_items.LockItemsForRead(true);
|
m_items.LockItemsForRead(true);
|
||||||
foreach (TaskInventoryItem item in m_items.Values)
|
foreach (TaskInventoryItem item in m_items.Values)
|
||||||
{
|
{
|
||||||
if (item.Type == 10)
|
if (item.Type == (int)InventoryType.LSL)
|
||||||
{
|
{
|
||||||
scriptcount++;
|
scriptcount++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -706,14 +706,16 @@
|
||||||
;; For standalones, this is the storage dll.
|
;; For standalones, this is the storage dll.
|
||||||
; StorageProvider = OpenSim.Data.MySQL.dll
|
; StorageProvider = OpenSim.Data.MySQL.dll
|
||||||
|
|
||||||
;# {MuteListModule} {OfflineMessageModule:OfflineMessageModule} {} {} None
|
; Mute list handler
|
||||||
;; Mute list handler (not yet implemented). MUST BE SET to allow offline
|
; the provided MuteListModule is just a Dummy
|
||||||
;; messages to work
|
; you will need a external module for proper suport.
|
||||||
|
; if you keep both 2 following settings comment, viewers will use mutes in their caches
|
||||||
|
; if you uncoment both (url is ignored) the mutes will be deleted at login.
|
||||||
|
|
||||||
|
;# {MuteListModule} {MuteListModule:MuteListModule} {} {} None
|
||||||
; MuteListModule = MuteListModule
|
; MuteListModule = MuteListModule
|
||||||
|
|
||||||
;# {MuteListURL} {OfflineMessageModule:OfflineMessageModule} {} {} http://yourserver/Mute.php
|
;# {MuteListURL} {MuteListModule:MuteListModule} {} {} http://yourserver/Mute.php
|
||||||
;; URL of the web service that serves mute lists. Not currently used, but
|
|
||||||
;; must be set to allow offline messaging to work.
|
|
||||||
; MuteListURL = http://yourserver/Mute.php
|
; MuteListURL = http://yourserver/Mute.php
|
||||||
|
|
||||||
;; Control whether group invites and notices are stored for offline users.
|
;; Control whether group invites and notices are stored for offline users.
|
||||||
|
|
Loading…
Reference in New Issue