Merge branch 'master' into varregion

Add new region crossing code to varregion

Conflicts:
	OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
	OpenSim/Region/Framework/Scenes/ScenePresence.cs
varregion
Robert Adams 2013-12-17 06:18:13 -08:00
commit 6937eec258
51 changed files with 2775 additions and 1280 deletions

View File

@ -48,6 +48,8 @@ namespace OpenSim.Data
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result); bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
bool UpdateAvatarInterests(UserProfileProperties up, ref string result); bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result); bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
bool GetUserPreferences(ref UserPreferences pref, ref string result);
bool GetUserAppData(ref UserAppData props, ref string result); bool GetUserAppData(ref UserAppData props, ref string result);
bool SetUserAppData(UserAppData props, ref string result); bool SetUserAppData(UserAppData props, ref string result);
OSDArray GetUserImageAssets(UUID avatarId); OSDArray GetUserImageAssets(UUID avatarId);

View File

@ -546,6 +546,10 @@ namespace OpenSim.Data.MySQL
reader.Read(); reader.Read();
notes.Notes = OSD.FromString((string)reader["notes"]); notes.Notes = OSD.FromString((string)reader["notes"]);
} }
else
{
notes.Notes = OSD.FromString("");
}
} }
} }
} }
@ -895,7 +899,7 @@ namespace OpenSim.Data.MySQL
} }
#region User Preferences #region User Preferences
public OSDArray GetUserPreferences(UUID avatarId) public bool GetUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; string query = string.Empty;
@ -912,31 +916,32 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString());
using (MySqlDataReader reader = cmd.ExecuteReader()) using (MySqlDataReader reader = cmd.ExecuteReader())
{ {
if(reader.HasRows) if(reader.HasRows)
{ {
reader.Read(); reader.Read();
OSDMap record = new OSDMap(); bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
record.Add("imviaemail",OSD.FromString((string)reader["imviaemail"])); pref.EMail = (string)reader["email"];
record.Add("visible",OSD.FromString((string)reader["visible"]));
record.Add("email",OSD.FromString((string)reader["email"]));
data.Add(record);
} }
else else
{ {
dbcon.Close();
dbcon.Open();
query = "INSERT INTO usersettings VALUES ";
query += "(?uuid,'false','false', ?Email)";
using (MySqlCommand put = new MySqlCommand(query, dbcon)) using (MySqlCommand put = new MySqlCommand(query, dbcon))
{ {
query = "INSERT INTO usersettings VALUES ";
query += "(?Id,'false','false', '')";
lock(Lock) put.Parameters.AddWithValue("?Email", pref.EMail);
{ put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
put.ExecuteNonQuery();
} put.ExecuteNonQuery();
} }
} }
} }
@ -947,17 +952,19 @@ namespace OpenSim.Data.MySQL
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message); ": Get preferences exception {0}", e.Message);
result = e.Message;
return false;
} }
return data; return true;
} }
public bool UpdateUserPreferences(bool emailIm, bool visible, UUID avatarId ) public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; string query = string.Empty;
query += "UPDATE userpsettings SET "; query += "UPDATE usersettings SET ";
query += "imviaemail=?ImViaEmail, "; query += "imviaemail=?ImViaEmail, ";
query += "visible=?Visible,"; query += "visible=?Visible ";
query += "WHERE useruuid=?uuid"; query += "WHERE useruuid=?uuid";
try try
@ -967,14 +974,11 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("?ImViaEmail", emailIm.ToString().ToLower ()); cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail);
cmd.Parameters.AddWithValue("?WantText", visible.ToString().ToLower ()); cmd.Parameters.AddWithValue("?Visible", pref.Visible);
cmd.Parameters.AddWithValue("?uuid", avatarId.ToString()); cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
lock(Lock) cmd.ExecuteNonQuery();
{
cmd.ExecuteNonQuery();
}
} }
} }
} }
@ -982,6 +986,7 @@ namespace OpenSim.Data.MySQL
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message); ": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false; return false;
} }
return true; return true;

View File

@ -81,3 +81,13 @@ CREATE TABLE IF NOT EXISTS `userdata` (
commit; commit;
:VERSION 3 # -------------------------------
begin;
CREATE TABLE IF NOT EXISTS `usersettings` (
`useruuid` varchar(36) NOT NULL,
`imviaemail` enum('true','false') NOT NULL,
`visible` enum('true','false') NOT NULL,
`email` varchar(254) NOT NULL,
PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
commit;

View File

@ -874,7 +874,7 @@ namespace OpenSim.Data.PGSQL
} }
#region User Preferences #region User Preferences
public OSDArray GetUserPreferences(UUID avatarId) public bool GetUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; string query = string.Empty;
@ -891,19 +891,16 @@ namespace OpenSim.Data.PGSQL
dbcon.Open(); dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("Id", avatarId.ToString()); cmd.Parameters.AddWithValue("Id", pref.UserId.ToString());
using (NpgsqlDataReader reader = cmd.ExecuteReader()) using (NpgsqlDataReader reader = cmd.ExecuteReader())
{ {
if(reader.HasRows) if(reader.HasRows)
{ {
reader.Read(); reader.Read();
OSDMap record = new OSDMap(); bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
record.Add("imviaemail",OSD.FromString((string)reader["imviaemail"])); pref.EMail = (string)reader["email"];
record.Add("visible",OSD.FromString((string)reader["visible"]));
record.Add("email",OSD.FromString((string)reader["email"]));
data.Add(record);
} }
else else
{ {
@ -926,15 +923,16 @@ namespace OpenSim.Data.PGSQL
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message); ": Get preferences exception {0}", e.Message);
result = e.Message;
} }
return data; return true;
} }
public bool UpdateUserPreferences(bool emailIm, bool visible, UUID avatarId ) public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; string query = string.Empty;
query += "UPDATE userpsettings SET "; query += "UPDATE usersettings SET ";
query += "imviaemail=:ImViaEmail, "; query += "imviaemail=:ImViaEmail, ";
query += "visible=:Visible,"; query += "visible=:Visible,";
query += "WHERE useruuid=:uuid"; query += "WHERE useruuid=:uuid";
@ -946,9 +944,9 @@ namespace OpenSim.Data.PGSQL
dbcon.Open(); dbcon.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
{ {
cmd.Parameters.AddWithValue("ImViaEmail", emailIm.ToString().ToLower ()); cmd.Parameters.AddWithValue("ImViaEmail", pref.IMViaEmail.ToString().ToLower ());
cmd.Parameters.AddWithValue("WantText", visible.ToString().ToLower ()); cmd.Parameters.AddWithValue("Visible", pref.Visible.ToString().ToLower ());
cmd.Parameters.AddWithValue("uuid", avatarId.ToString()); cmd.Parameters.AddWithValue("uuid", pref.UserId.ToString());
lock(Lock) lock(Lock)
{ {
@ -961,6 +959,7 @@ namespace OpenSim.Data.PGSQL
{ {
m_log.DebugFormat("[PROFILES_DATA]" + m_log.DebugFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message); ": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false; return false;
} }
return true; return true;

View File

@ -81,3 +81,12 @@ CREATE TABLE userdata (
commit; commit;
:VERSION 3 # -------------------------------
begin;
CREATE TABLE usersettings (
"useruuid" char(36) NOT NULL,
"imviaemail" bytea NOT NULL,
"visible" bytea NOT NULL,
PRIMARY KEY ("useruuid")
);
commit;

View File

@ -88,3 +88,15 @@ CREATE TABLE IF NOT EXISTS userdata (
commit; commit;
:VERSION 3 # -------------------------------
begin;
CREATE TABLE IF NOT EXISTS usersettings (
useruuid char(36) NOT NULL,
imviaemail binary(1) NOT NULL,
visible binary(1) NOT NULL,
email varchar(254) NOT NULL,
PRIMARY KEY (useruuid)
)
commit;

View File

@ -747,6 +747,90 @@ namespace OpenSim.Data.SQLite
} }
return true; return true;
} }
public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
{
string query = string.Empty;
query += "UPDATE usersettings SET ";
query += "imviaemail=:ImViaEmail, ";
query += "visible=:Visible ";
query += "WHERE useruuid=:uuid";
try
{
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = query;
cmd.Parameters.AddWithValue(":ImViaEmail", pref.IMViaEmail);
cmd.Parameters.AddWithValue(":Visible", pref.Visible);
cmd.Parameters.AddWithValue(":uuid", pref.UserId.ToString());
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": AgentInterestsUpdate exception {0}", e.Message);
result = e.Message;
return false;
}
return true;
}
public bool GetUserPreferences(ref UserPreferences pref, ref string result)
{
IDataReader reader = null;
string query = string.Empty;
query += "SELECT imviaemail,visible,email FROM ";
query += "usersettings WHERE ";
query += "useruuid = :Id";
OSDArray data = new OSDArray();
try
{
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = query;
cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString());
using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if(reader.Read())
{
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
bool.TryParse((string)reader["visible"], out pref.Visible);
pref.EMail = (string)reader["email"];
}
else
{
query = "INSERT INTO usersettings VALUES ";
query += "(:Id,'false','false', :Email)";
using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand())
{
put.Parameters.AddWithValue(":Id", pref.UserId.ToString());
put.Parameters.AddWithValue(":Email", pref.EMail);
put.ExecuteNonQuery();
}
}
}
}
}
catch (Exception e)
{
m_log.DebugFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message);
result = e.Message;
return false;
}
return true;
}
public bool GetUserAppData(ref UserAppData props, ref string result) public bool GetUserAppData(ref UserAppData props, ref string result)
{ {
IDataReader reader = null; IDataReader reader = null;

View File

@ -40,8 +40,17 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public class AvatarAppearance public class AvatarAppearance
{ {
// SL box diferent to size
const float AVBOXAJUST = 0.2f;
// constrains for ubitode physics
const float AVBOXMINX = 0.2f;
const float AVBOXMINY = 0.3f;
const float AVBOXMINZ = 1.2f;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// this is viewer capabilities and weared things dependent
// should be only used as initial default value ( V1 viewers )
public readonly static int VISUALPARAM_COUNT = 218; public readonly static int VISUALPARAM_COUNT = 218;
public readonly static int TEXTURE_COUNT = 21; public readonly static int TEXTURE_COUNT = 21;
@ -53,7 +62,12 @@ namespace OpenSim.Framework
protected AvatarWearable[] m_wearables; protected AvatarWearable[] m_wearables;
protected Dictionary<int, List<AvatarAttachment>> m_attachments; protected Dictionary<int, List<AvatarAttachment>> m_attachments;
protected float m_avatarHeight = 0; protected float m_avatarHeight = 0;
protected UUID[] m_texturehashes; protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value
protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
protected float m_avatarFeetOffset = 0;
protected float m_avatarAnimOffset = 0;
protected WearableCacheItem[] m_cacheitems;
protected bool m_cacheItemsDirty = true;
public virtual int Serial public virtual int Serial
{ {
@ -67,6 +81,21 @@ namespace OpenSim.Framework
set { m_visualparams = value; } set { m_visualparams = value; }
} }
public virtual Vector3 AvatarSize
{
get { return m_avatarSize; }
}
public virtual Vector3 AvatarBoxSize
{
get { return m_avatarBoxSize; }
}
public virtual float AvatarFeetOffset
{
get { return m_avatarFeetOffset + m_avatarAnimOffset; }
}
public virtual Primitive.TextureEntry Texture public virtual Primitive.TextureEntry Texture
{ {
get { return m_texture; } get { return m_texture; }
@ -89,6 +118,18 @@ namespace OpenSim.Framework
set { m_avatarHeight = value; } set { m_avatarHeight = value; }
} }
public virtual WearableCacheItem[] WearableCacheItems
{
get { return m_cacheitems; }
set { m_cacheitems = value; }
}
public virtual bool WearableCacheItemsDirty
{
get { return m_cacheItemsDirty; }
set { m_cacheItemsDirty = value; }
}
public AvatarAppearance() public AvatarAppearance()
{ {
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance"); // m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
@ -97,10 +138,9 @@ namespace OpenSim.Framework
SetDefaultWearables(); SetDefaultWearables();
SetDefaultTexture(); SetDefaultTexture();
SetDefaultParams(); SetDefaultParams();
SetHeight(); // SetHeight();
SetSize(new Vector3(0.45f,0.6f,1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
ResetTextureHashes();
} }
public AvatarAppearance(OSDMap map) public AvatarAppearance(OSDMap map)
@ -108,7 +148,35 @@ namespace OpenSim.Framework
// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap"); // m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap");
Unpack(map); Unpack(map);
SetHeight(); // SetHeight(); done in Unpack
}
public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
{
// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
m_serial = 0;
if (wearables != null)
m_wearables = wearables;
else
SetDefaultWearables();
if (textureEntry != null)
m_texture = textureEntry;
else
SetDefaultTexture();
if (visualParams != null)
m_visualparams = visualParams;
else
SetDefaultParams();
// SetHeight();
if(m_avatarHeight == 0)
SetSize(new Vector3(0.45f,0.6f,1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
} }
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
@ -125,11 +193,10 @@ namespace OpenSim.Framework
SetDefaultWearables(); SetDefaultWearables();
SetDefaultTexture(); SetDefaultTexture();
SetDefaultParams(); SetDefaultParams();
SetHeight(); // SetHeight();
SetSize(new Vector3(0.45f, 0.6f, 1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
ResetTextureHashes();
return; return;
} }
@ -145,10 +212,6 @@ namespace OpenSim.Framework
SetWearable(i,appearance.Wearables[i]); SetWearable(i,appearance.Wearables[i]);
} }
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
m_texturehashes[i] = new UUID(appearance.m_texturehashes[i]);
m_texture = null; m_texture = null;
if (appearance.Texture != null) if (appearance.Texture != null)
{ {
@ -160,7 +223,8 @@ namespace OpenSim.Framework
if (appearance.VisualParams != null) if (appearance.VisualParams != null)
m_visualparams = (byte[])appearance.VisualParams.Clone(); m_visualparams = (byte[])appearance.VisualParams.Clone();
m_avatarHeight = appearance.m_avatarHeight; // m_avatarHeight = appearance.m_avatarHeight;
SetSize(appearance.AvatarSize);
// Copy the attachment, force append mode since that ensures consistency // Copy the attachment, force append mode since that ensures consistency
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
@ -183,37 +247,6 @@ namespace OpenSim.Framework
} }
} }
public void ResetTextureHashes()
{
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
m_texturehashes[i] = UUID.Zero;
}
public UUID GetTextureHash(int textureIndex)
{
return m_texturehashes[NormalizeBakedTextureIndex(textureIndex)];
}
public void SetTextureHash(int textureIndex, UUID textureHash)
{
m_texturehashes[NormalizeBakedTextureIndex(textureIndex)] = new UUID(textureHash);
}
/// <summary>
/// Normalizes the texture index to the actual bake index, this is done to
/// accommodate older viewers that send the BAKE_INDICES index rather than
/// the actual texture index
/// </summary>
private int NormalizeBakedTextureIndex(int textureIndex)
{
// Earlier viewer send the index into the baked index array, just trying to be careful here
if (textureIndex < BAKE_INDICES.Length)
return BAKE_INDICES[textureIndex];
return textureIndex;
}
public void ClearWearables() public void ClearWearables()
{ {
m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
@ -237,7 +270,12 @@ namespace OpenSim.Framework
m_serial = 0; m_serial = 0;
SetDefaultTexture(); SetDefaultTexture();
ResetTextureHashes();
//for (int i = 0; i < BAKE_INDICES.Length; i++)
// {
// int idx = BAKE_INDICES[i];
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
// }
} }
protected virtual void SetDefaultParams() protected virtual void SetDefaultParams()
@ -249,6 +287,21 @@ namespace OpenSim.Framework
// } // }
} }
/// <summary>
/// Invalidate all of the baked textures in the appearance, useful
/// if you know that none are valid
/// </summary>
public virtual void ResetBakedTextures()
{
SetDefaultTexture();
//for (int i = 0; i < BAKE_INDICES.Length; i++)
// {
// int idx = BAKE_INDICES[i];
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
// }
}
protected virtual void SetDefaultTexture() protected virtual void SetDefaultTexture()
{ {
m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
@ -313,22 +366,33 @@ namespace OpenSim.Framework
// made. We determine if any of the visual parameters actually // made. We determine if any of the visual parameters actually
// changed to know if the appearance should be saved later // changed to know if the appearance should be saved later
bool changed = false; bool changed = false;
for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
int newsize = visualParams.Length;
if (newsize != m_visualparams.Length)
{ {
if (visualParams[i] != m_visualparams[i]) changed = true;
m_visualparams = (byte[])visualParams.Clone();
}
else
{
for (int i = 0; i < newsize; i++)
{ {
// DEBUG ON if (visualParams[i] != m_visualparams[i])
// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", {
// i,m_visualparams[i],visualParams[i]); // DEBUG ON
// DEBUG OFF // m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
m_visualparams[i] = visualParams[i]; // i,m_visualparams[i],visualParams[i]);
changed = true; // DEBUG OFF
m_visualparams[i] = visualParams[i];
changed = true;
}
} }
} }
// Reset the height if the visual parameters actually changed // Reset the height if the visual parameters actually changed
if (changed) // if (changed)
SetHeight(); // SetHeight();
return changed; return changed;
} }
@ -344,6 +408,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public virtual void SetHeight() public virtual void SetHeight()
{ {
/*
// Start with shortest possible female avatar height // Start with shortest possible female avatar height
m_avatarHeight = 1.14597f; m_avatarHeight = 1.14597f;
// Add offset for male avatars // Add offset for male avatars
@ -356,6 +421,35 @@ namespace OpenSim.Framework
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f;
*/
}
public void SetSize(Vector3 avSize)
{
if (avSize.X > 32f)
avSize.X = 32f;
else if (avSize.X < 0.1f)
avSize.X = 0.1f;
if (avSize.Y > 32f)
avSize.Y = 32f;
else if (avSize.Y < 0.1f)
avSize.Y = 0.1f;
if (avSize.Z > 32f)
avSize.Z = 32f;
else if (avSize.Z < 0.1f)
avSize.Z = 0.1f;
m_avatarSize = avSize;
m_avatarBoxSize = avSize;
m_avatarBoxSize.Z += AVBOXAJUST;
if (m_avatarBoxSize.X < AVBOXMINX)
m_avatarBoxSize.X = AVBOXMINX;
if (m_avatarBoxSize.Y < AVBOXMINY)
m_avatarBoxSize.Y = AVBOXMINY;
if (m_avatarBoxSize.Z < AVBOXMINZ)
m_avatarBoxSize.Z = AVBOXMINZ;
m_avatarHeight = m_avatarSize.Z;
} }
public virtual void SetWearable(int wearableId, AvatarWearable wearable) public virtual void SetWearable(int wearableId, AvatarWearable wearable)
@ -386,7 +480,8 @@ namespace OpenSim.Framework
} }
s += "Visual Params: "; s += "Visual Params: ";
for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++) // for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
for (uint j = 0; j < m_visualparams.Length; j++)
s += String.Format("{0},",m_visualparams[j]); s += String.Format("{0},",m_visualparams[j]);
s += "\n"; s += "\n";
@ -402,18 +497,16 @@ namespace OpenSim.Framework
/// </remarks> /// </remarks>
public List<AvatarAttachment> GetAttachments() public List<AvatarAttachment> GetAttachments()
{ {
List<AvatarAttachment> alist = new List<AvatarAttachment>();
lock (m_attachments) lock (m_attachments)
{ {
List<AvatarAttachment> alist = new List<AvatarAttachment>();
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{ {
foreach (AvatarAttachment attach in kvp.Value) foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach)); alist.Add(new AvatarAttachment(attach));
} }
} return alist;
}
return alist;
} }
internal void AppendAttachment(AvatarAttachment attach) internal void AppendAttachment(AvatarAttachment attach)
@ -557,7 +650,6 @@ namespace OpenSim.Framework
return kvp.Key; return kvp.Key;
} }
} }
return 0; return 0;
} }
@ -607,12 +699,6 @@ namespace OpenSim.Framework
data["serial"] = OSD.FromInteger(m_serial); data["serial"] = OSD.FromInteger(m_serial);
data["height"] = OSD.FromReal(m_avatarHeight); data["height"] = OSD.FromReal(m_avatarHeight);
// Hashes
OSDArray hashes = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
hashes.Add(OSD.FromUUID(m_texturehashes[i]));
data["hashes"] = hashes;
// Wearables // Wearables
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES); OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
@ -634,12 +720,14 @@ namespace OpenSim.Framework
OSDBinary visualparams = new OSDBinary(m_visualparams); OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams; data["visualparams"] = visualparams;
// Attachments lock (m_attachments)
List<AvatarAttachment> attachments = GetAttachments(); {
OSDArray attachs = new OSDArray(attachments.Count); // Attachments
foreach (AvatarAttachment attach in GetAttachments()) OSDArray attachs = new OSDArray(m_attachments.Count);
attachs.Add(attach.Pack()); foreach (AvatarAttachment attach in GetAttachments())
data["attachments"] = attachs; attachs.Add(attach.Pack());
data["attachments"] = attachs;
}
return data; return data;
} }
@ -653,29 +741,11 @@ namespace OpenSim.Framework
if ((data != null) && (data["serial"] != null)) if ((data != null) && (data["serial"] != null))
m_serial = data["serial"].AsInteger(); m_serial = data["serial"].AsInteger();
if ((data != null) && (data["height"] != null)) if ((data != null) && (data["height"] != null))
m_avatarHeight = (float)data["height"].AsReal(); // m_avatarHeight = (float)data["height"].AsReal();
SetSize(new Vector3(0.45f,0.6f, (float)data["height"].AsReal()));
try try
{ {
// Hashes
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
if ((data != null) && (data["hashes"] != null) && (data["hashes"]).Type == OSDType.Array)
{
OSDArray hashes = (OSDArray)(data["hashes"]);
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
{
UUID hashID = UUID.Zero;
if (i < hashes.Count && hashes[i] != null)
hashID = hashes[i].AsUUID();
m_texturehashes[i] = hashID;
}
}
else
{
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
m_texturehashes[i] = UUID.Zero;
}
// Wearables // Wearables
SetDefaultWearables(); SetDefaultWearables();
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
@ -1505,7 +1575,58 @@ namespace OpenSim.Framework
SHAPE_EYELID_INNER_CORNER_UP = 214, SHAPE_EYELID_INNER_CORNER_UP = 214,
SKIRT_SKIRT_RED = 215, SKIRT_SKIRT_RED = 215,
SKIRT_SKIRT_GREEN = 216, SKIRT_SKIRT_GREEN = 216,
SKIRT_SKIRT_BLUE = 217 SKIRT_SKIRT_BLUE = 217,
/// <summary>
/// Avatar Physics section. These are 0 type visual params which get transmitted.
/// </summary>
/// <summary>
/// Breast Part 1
/// </summary>
BREAST_PHYSICS_MASS = 218,
BREAST_PHYSICS_GRAVITY = 219,
BREAST_PHYSICS_DRAG = 220,
BREAST_PHYSICS_UPDOWN_MAX_EFFECT = 221,
BREAST_PHYSICS_UPDOWN_SPRING = 222,
BREAST_PHYSICS_UPDOWN_GAIN = 223,
BREAST_PHYSICS_UPDOWN_DAMPING = 224,
BREAST_PHYSICS_INOUT_MAX_EFFECT = 225,
BREAST_PHYSICS_INOUT_SPRING = 226,
BREAST_PHYSICS_INOUT_GAIN = 227,
BREAST_PHYSICS_INOUT_DAMPING = 228,
/// <summary>
/// Belly
/// </summary>
BELLY_PHYISCS_MASS = 229,
BELLY_PHYSICS_GRAVITY = 230,
BELLY_PHYSICS_DRAG = 231,
BELLY_PHYISCS_UPDOWN_MAX_EFFECT = 232,
BELLY_PHYSICS_UPDOWN_SPRING = 233,
BELLY_PHYSICS_UPDOWN_GAIN = 234,
BELLY_PHYSICS_UPDOWN_DAMPING = 235,
/// <summary>
/// Butt
/// </summary>
BUTT_PHYSICS_MASS = 236,
BUTT_PHYSICS_GRAVITY = 237,
BUTT_PHYSICS_DRAG = 238,
BUTT_PHYSICS_UPDOWN_MAX_EFFECT = 239,
BUTT_PHYSICS_UPDOWN_SPRING = 240,
BUTT_PHYSICS_UPDOWN_GAIN = 241,
BUTT_PHYSICS_UPDOWN_DAMPING = 242,
BUTT_PHYSICS_LEFTRIGHT_MAX_EFFECT = 243,
BUTT_PHYSICS_LEFTRIGHT_SPRING = 244,
BUTT_PHYSICS_LEFTRIGHT_GAIN = 245,
BUTT_PHYSICS_LEFTRIGHT_DAMPING = 246,
/// <summary>
/// Breast Part 2
/// </summary>
BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250
} }
#endregion #endregion
} }

View File

@ -230,12 +230,14 @@ namespace OpenSim.Framework
public class ControllerData public class ControllerData
{ {
public UUID ObjectID;
public UUID ItemID; public UUID ItemID;
public uint IgnoreControls; public uint IgnoreControls;
public uint EventControls; public uint EventControls;
public ControllerData(UUID item, uint ignore, uint ev) public ControllerData(UUID obj, UUID item, uint ignore, uint ev)
{ {
ObjectID = obj;
ItemID = item; ItemID = item;
IgnoreControls = ignore; IgnoreControls = ignore;
EventControls = ev; EventControls = ev;
@ -249,6 +251,7 @@ namespace OpenSim.Framework
public OSDMap PackUpdateMessage() public OSDMap PackUpdateMessage()
{ {
OSDMap controldata = new OSDMap(); OSDMap controldata = new OSDMap();
controldata["object"] = OSD.FromUUID(ObjectID);
controldata["item"] = OSD.FromUUID(ItemID); controldata["item"] = OSD.FromUUID(ItemID);
controldata["ignore"] = OSD.FromInteger(IgnoreControls); controldata["ignore"] = OSD.FromInteger(IgnoreControls);
controldata["event"] = OSD.FromInteger(EventControls); controldata["event"] = OSD.FromInteger(EventControls);
@ -259,6 +262,8 @@ namespace OpenSim.Framework
public void UnpackUpdateMessage(OSDMap args) public void UnpackUpdateMessage(OSDMap args)
{ {
if (args["object"] != null)
ObjectID = args["object"].AsUUID();
if (args["item"] != null) if (args["item"] != null)
ItemID = args["item"].AsUUID(); ItemID = args["item"].AsUUID();
if (args["ignore"] != null) if (args["ignore"] != null)
@ -317,6 +322,8 @@ namespace OpenSim.Framework
public Animation AnimState = null; public Animation AnimState = null;
public UUID GranterID; public UUID GranterID;
public UUID ParentPart;
public Vector3 SitOffset;
// Appearance // Appearance
public AvatarAppearance Appearance; public AvatarAppearance Appearance;
@ -488,6 +495,10 @@ namespace OpenSim.Framework
} }
args["attach_objects"] = attObjs; args["attach_objects"] = attObjs;
} }
args["parent_part"] = OSD.FromUUID(ParentPart);
args["sit_offset"] = OSD.FromString(SitOffset.ToString());
return args; return args;
} }
@ -719,6 +730,11 @@ namespace OpenSim.Framework
} }
} }
} }
if (args["parent_part"] != null)
ParentPart = args["parent_part"].AsUUID();
if (args["sit_offset"] != null)
Vector3.TryParse(args["sit_offset"].AsString(), out SitOffset);
} }
public AgentData() public AgentData()

View File

@ -66,7 +66,7 @@ namespace OpenSim.Framework
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest); public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> cachedTextureData); public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems);
public delegate void StartAnim(IClientAPI remoteClient, UUID animID); public delegate void StartAnim(IClientAPI remoteClient, UUID animID);

View File

@ -33,6 +33,7 @@ namespace OpenSim.Framework
{ {
void Cache(AssetBase asset); void Cache(AssetBase asset);
AssetBase Get(string id); AssetBase Get(string id);
bool Check(string id);
void Expire(string id); void Expire(string id);
void Clear(); void Clear();
} }

View File

@ -70,6 +70,7 @@ namespace OpenSim.Framework
void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
bool IsEitherBannedOrRestricted(UUID avatar); bool IsEitherBannedOrRestricted(UUID avatar);
bool IsBannedFromLand(UUID avatar); bool IsBannedFromLand(UUID avatar);
bool CanBeOnThisLand(UUID avatar, float posHeight);
bool IsRestrictedFromLand(UUID avatar); bool IsRestrictedFromLand(UUID avatar);
bool IsInLandAccessList(UUID avatar); bool IsInLandAccessList(UUID avatar);
void SendLandUpdateToClient(IClientAPI remote_client); void SendLandUpdateToClient(IClientAPI remote_client);

View File

@ -247,12 +247,18 @@ namespace OpenSim.Framework
/// <returns></returns> /// <returns></returns>
public static List<string> ParseNotecardToList(string rawInput) public static List<string> ParseNotecardToList(string rawInput)
{ {
string[] input = rawInput.Replace("\r", "").Split('\n'); string[] input;
int idx = 0; int idx = 0;
int level = 0; int level = 0;
List<string> output = new List<string>(); List<string> output = new List<string>();
string[] words; string[] words;
//The Linden format always ends with a } after the input data.
//Strip off trailing } so there is nothing after the input data.
int i = rawInput.LastIndexOf("}");
rawInput = rawInput.Remove(i, rawInput.Length-i);
input = rawInput.Replace("\r", "").Split('\n');
while (idx < input.Length) while (idx < input.Length)
{ {
if (input[idx] == "{") if (input[idx] == "{")
@ -287,24 +293,18 @@ namespace OpenSim.Framework
break; break;
if (words[0] == "Text") if (words[0] == "Text")
{ {
int len = int.Parse(words[2]); idx++; //Now points to first line of notecard text
idx++;
int count = -1; //Number of lines in notecard.
int lines = input.Length - idx;
int line = 0;
while (count < len && idx < input.Length) while (line < lines)
{ {
// int l = input[idx].Length; // m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", input[idx]);
string ln = input[idx]; output.Add(input[idx]);
int need = len-count-1;
if (ln.Length > need)
ln = ln.Substring(0, need);
// m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", ln);
output.Add(ln);
count += ln.Length + 1;
idx++; idx++;
line++;
} }
return output; return output;

View File

@ -135,8 +135,8 @@ namespace OpenSim.Framework.Servers
TimeSpan timeTaken = DateTime.Now - m_startuptime; TimeSpan timeTaken = DateTime.Now - m_startuptime;
m_log.InfoFormat( MainConsole.Instance.OutputFormat(
"[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.", "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
timeTaken.Minutes, timeTaken.Seconds); timeTaken.Minutes, timeTaken.Seconds);
} }

View File

@ -91,6 +91,14 @@ namespace OpenSim.Framework
public string Notes; public string Notes;
} }
public class UserPreferences
{
public UUID UserId;
public bool IMViaEmail = false;
public bool Visible = false;
public string EMail = string.Empty;
}
public class UserAccountProperties public class UserAccountProperties
{ {
public string EmailAddress = string.Empty; public string EmailAddress = string.Empty;

View File

@ -0,0 +1,157 @@
/*
* 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 OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
[Serializable]
public class WearableCacheItem
{
public uint TextureIndex { get; set; }
public UUID CacheId { get; set; }
public UUID TextureID { get; set; }
public AssetBase TextureAsset { get; set; }
public static WearableCacheItem[] GetDefaultCacheItem()
{
int itemmax = 21;
WearableCacheItem[] retitems = new WearableCacheItem[itemmax];
for (uint i=0;i<itemmax;i++)
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1};
return retitems;
}
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
{
List<WearableCacheItem> ret = new List<WearableCacheItem>();
if (pInput.Type == OSDType.Array)
{
OSDArray itemarray = (OSDArray) pInput;
foreach (OSDMap item in itemarray)
{
ret.Add(new WearableCacheItem()
{
TextureIndex = item["textureindex"].AsUInteger(),
CacheId = item["cacheid"].AsUUID(),
TextureID = item["textureid"].AsUUID()
});
if (dataCache != null && item.ContainsKey("assetdata"))
{
AssetBase asset = new AssetBase(item["textureid"].AsUUID(),"BakedTexture",(sbyte)AssetType.Texture,UUID.Zero.ToString());
asset.Temporary = true;
asset.Data = item["assetdata"].AsBinary();
dataCache.Cache(asset);
}
}
}
else if (pInput.Type == OSDType.Map)
{
OSDMap item = (OSDMap) pInput;
ret.Add(new WearableCacheItem(){
TextureIndex = item["textureindex"].AsUInteger(),
CacheId = item["cacheid"].AsUUID(),
TextureID = item["textureid"].AsUUID()
});
if (dataCache != null && item.ContainsKey("assetdata"))
{
string assetCreator = item["assetcreator"].AsString();
string assetName = item["assetname"].AsString();
AssetBase asset = new AssetBase(item["textureid"].AsUUID(), assetName, (sbyte)AssetType.Texture, assetCreator);
asset.Temporary = true;
asset.Data = item["assetdata"].AsBinary();
dataCache.Cache(asset);
}
}
else
{
return new WearableCacheItem[0];
}
return ret.ToArray();
}
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
{
OSDArray arr = new OSDArray();
foreach (WearableCacheItem item in pcacheItems)
{
OSDMap itemmap = new OSDMap();
itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex));
itemmap.Add("cacheid", OSD.FromUUID(item.CacheId));
itemmap.Add("textureid", OSD.FromUUID(item.TextureID));
if (dataCache != null)
{
if (dataCache.Check(item.TextureID.ToString()))
{
AssetBase assetItem = dataCache.Get(item.TextureID.ToString());
if (assetItem != null)
{
itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data));
itemmap.Add("assetcreator", OSD.FromString(assetItem.CreatorID));
itemmap.Add("assetname", OSD.FromString(assetItem.Name));
}
}
}
arr.Add(itemmap);
}
return arr;
}
public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
{
for (int i = 0; i < pcacheItems.Length; i++)
{
if (pcacheItems[i].TextureIndex == pTextureIndex)
return pcacheItems[i];
}
return null;
}
public static WearableCacheItem SearchTextureCacheId(UUID pCacheId, WearableCacheItem[] pcacheItems)
{
for (int i = 0; i < pcacheItems.Length; i++)
{
if (pcacheItems[i].CacheId == pCacheId)
return pcacheItems[i];
}
return null;
}
public static WearableCacheItem SearchTextureTextureId(UUID pTextureId, WearableCacheItem[] pcacheItems)
{
for (int i = 0; i < pcacheItems.Length; i++)
{
if (pcacheItems[i].TextureID == pTextureId)
return pcacheItems[i];
}
return null;
}
}
}

View File

@ -297,10 +297,20 @@ namespace OpenSim
HandleEditScale); HandleEditScale);
m_console.Commands.AddCommand("Objects", false, "rotate scene", m_console.Commands.AddCommand("Objects", false, "rotate scene",
"rotate scene <degrees>", "rotate scene <degrees> [centerX, centerY]",
"Rotates all scene objects around x:128, y:128", "Rotates all scene objects around centerX, centerY (defailt 128, 128) (please back up your region before using)",
HandleRotateScene); HandleRotateScene);
m_console.Commands.AddCommand("Objects", false, "scale scene",
"scale scene <factor>",
"Scales the scene objects (please back up your region before using)",
HandleScaleScene);
m_console.Commands.AddCommand("Objects", false, "translate scene",
"translate scene xOffset yOffset zOffset",
"translates the scene objects (please back up your region before using)",
HandleTranslateScene);
m_console.Commands.AddCommand("Users", false, "kick user", m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [--force] [message]", "kick user <first> <last> [--force] [message]",
"Kick a user off the simulator", "Kick a user off the simulator",
@ -549,6 +559,82 @@ namespace OpenSim
}); });
} }
private void HandleScaleScene(string module, string[] args)
{
string usage = "Usage: scale scene <factor>";
if (args.Length < 3)
{
MainConsole.Instance.Output(usage);
return;
}
float factor = (float)(Convert.ToSingle(args[2]));
float minZ = float.MaxValue;
SceneManager.ForEachSelectedScene(delegate(Scene scene)
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
{
if (sog.RootPart.AbsolutePosition.Z < minZ)
minZ = sog.RootPart.AbsolutePosition.Z;
}
});
});
SceneManager.ForEachSelectedScene(delegate(Scene scene)
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
{
Vector3 tmpRootPos = sog.RootPart.AbsolutePosition;
tmpRootPos.Z -= minZ;
tmpRootPos *= factor;
tmpRootPos.Z += minZ;
foreach (SceneObjectPart sop in sog.Parts)
{
if (sop.ParentID != 0)
sop.OffsetPosition *= factor;
sop.Scale *= factor;
}
sog.UpdateGroupPosition(tmpRootPos);
}
});
});
}
private void HandleTranslateScene(string module, string[] args)
{
string usage = "Usage: translate scene <xOffset, yOffset, zOffset>";
if (args.Length < 5)
{
MainConsole.Instance.Output(usage);
return;
}
float xOFfset = (float)Convert.ToSingle(args[2]);
float yOffset = (float)Convert.ToSingle(args[3]);
float zOffset = (float)Convert.ToSingle(args[4]);
Vector3 offset = new Vector3(xOFfset, yOffset, zOffset);
SceneManager.ForEachSelectedScene(delegate(Scene scene)
{
scene.ForEachSOG(delegate(SceneObjectGroup sog)
{
if (sog.AttachmentPoint == 0)
sog.UpdateGroupPosition(sog.AbsolutePosition + offset);
});
});
}
/// <summary> /// <summary>
/// Creates a new region based on the parameters specified. This will ask the user questions on the console /// Creates a new region based on the parameters specified. This will ask the user questions on the console
/// </summary> /// </summary>

View File

@ -6409,26 +6409,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Temporarily protect ourselves from the mantis #951 failure. // Temporarily protect ourselves from the mantis #951 failure.
// However, we could do this for several other handlers where a failure isn't terminal // However, we could do this for several other handlers where a failure isn't terminal
// for the client session anyway, in order to protect ourselves against bad code in plugins // for the client session anyway, in order to protect ourselves against bad code in plugins
Vector3 avSize = appear.AgentData.Size;
try try
{ {
byte[] visualparams = new byte[appear.VisualParam.Length]; byte[] visualparams = new byte[appear.VisualParam.Length];
for (int i = 0; i < appear.VisualParam.Length; i++) for (int i = 0; i < appear.VisualParam.Length; i++)
visualparams[i] = appear.VisualParam[i].ParamValue; visualparams[i] = appear.VisualParam[i].ParamValue;
//var b = appear.WearableData[0];
Primitive.TextureEntry te = null; Primitive.TextureEntry te = null;
if (appear.ObjectData.TextureEntry.Length > 1) if (appear.ObjectData.TextureEntry.Length > 1)
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
for (int i = 0; i < appear.WearableData.Length; i++) for (int i=0; i<appear.WearableData.Length;i++)
{ cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
CachedTextureRequestArg arg = new CachedTextureRequestArg();
arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
arg.WearableHashID = appear.WearableData[i].CacheID;
hashes.Add(arg);
}
handlerSetAppearance(sender, te, visualparams, hashes);
handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -194,6 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset
#region IImprovedAssetCache Members #region IImprovedAssetCache Members
public bool Check(string id)
{
return false;
}
/// <summary> /// <summary>
/// Cache asset. /// Cache asset.
/// </summary> /// </summary>

View File

@ -112,6 +112,10 @@ namespace OpenSim.Region.CoreModules.Asset
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// IImprovedAssetCache // IImprovedAssetCache
// //
public bool Check(string id)
{
return false;
}
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
{ {

View File

@ -248,57 +248,70 @@ namespace OpenSim.Region.CoreModules.Asset
private void UpdateFileCache(string key, AssetBase asset) private void UpdateFileCache(string key, AssetBase asset)
{ {
string filename = GetFileName(asset.ID); // TODO: Spawn this off to some seperate thread to do the actual writing
if (asset != null)
try
{ {
// If the file is already cached just update access time. string filename = GetFileName(key);
if (File.Exists(filename))
try
{ {
lock (m_CurrentlyWriting) // If the file is already cached, don't cache it, just touch it so access time is updated
if (File.Exists(filename))
{ {
if (!m_CurrentlyWriting.Contains(filename)) // We don't really want to know about sharing
File.SetLastAccessTime(filename, DateTime.Now); // violations here. If the file is locked, then
} // the other thread has updated the time for us.
} try
else
{
// Once we start writing, make sure we flag that we're writing
// that object to the cache so that we don't try to write the
// same file multiple times.
lock (m_CurrentlyWriting)
{
#if WAIT_ON_INPROGRESS_REQUESTS
if (m_CurrentlyWriting.ContainsKey(filename))
{ {
return; lock (m_CurrentlyWriting)
{
if (!m_CurrentlyWriting.Contains(filename))
File.SetLastAccessTime(filename, DateTime.Now);
}
} }
else catch
{ {
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); }
} } else {
// Once we start writing, make sure we flag that we're writing
// that object to the cache so that we don't try to write the
// same file multiple times.
lock (m_CurrentlyWriting)
{
#if WAIT_ON_INPROGRESS_REQUESTS
if (m_CurrentlyWriting.ContainsKey(filename))
{
return;
}
else
{
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
}
#else #else
if (m_CurrentlyWriting.Contains(filename)) if (m_CurrentlyWriting.Contains(filename))
{ {
return; return;
} }
else else
{ {
m_CurrentlyWriting.Add(filename); m_CurrentlyWriting.Add(filename);
} }
#endif #endif
}
Util.FireAndForget( }
delegate { WriteFileCache(filename, asset); });
Util.FireAndForget(
delegate { WriteFileCache(filename, asset); });
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
asset.ID, e.Message, e.StackTrace);
} }
}
catch (Exception e)
{
m_log.WarnFormat(
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
asset.ID, e.Message, e.StackTrace);
} }
} }
@ -332,6 +345,17 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
private bool CheckFromMemoryCache(string id)
{
AssetBase asset = null;
if (m_MemoryCache.TryGetValue(id, out asset))
return true;
return false;
}
/// <summary> /// <summary>
/// Try to get an asset from the file cache. /// Try to get an asset from the file cache.
/// </summary> /// </summary>
@ -396,6 +420,7 @@ namespace OpenSim.Region.CoreModules.Asset
m_log.WarnFormat( m_log.WarnFormat(
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace); filename, id, e.Message, e.StackTrace);
} }
finally finally
{ {
@ -407,6 +432,50 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
private bool CheckFromFileCache(string id)
{
bool found = false;
string filename = GetFileName(id);
if (File.Exists(filename))
{
// actually check if we can open it, and so update expire
FileStream stream = null;
try
{
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
if (stream != null)
{
found = true;
stream.Close();
}
}
catch (System.Runtime.Serialization.SerializationException e)
{
found = false;
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace);
// If there was a problem deserializing the asset, the asset may
// either be corrupted OR was serialized under an old format
// {different version of AssetBase} -- we should attempt to
// delete it and re-cache
File.Delete(filename);
}
catch (Exception e)
{
found = false;
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace);
}
}
return found;
}
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
m_Requests++; m_Requests++;
@ -434,11 +503,26 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
public bool Check(string id)
{
if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
return true;
if (m_FileCacheEnabled && CheckFromFileCache(id))
return true;
return false;
}
public AssetBase GetCached(string id) public AssetBase GetCached(string id)
{ {
return Get(id); return Get(id);
} }
public AssetBase CheckCached(string id)
{
return Get(id);
}
public void Expire(string id) public void Expire(string id)
{ {
if (m_LogLevel >= 2) if (m_LogLevel >= 2)
@ -983,6 +1067,11 @@ namespace OpenSim.Region.CoreModules.Asset
return asset.Data; return asset.Data;
} }
public bool CheckData(string id)
{
return Check(id); ;
}
public bool Get(string id, object sender, AssetRetrieved handler) public bool Get(string id, object sender, AssetRetrieved handler)
{ {
AssetBase asset = Get(id); AssetBase asset = Get(id);

View File

@ -115,6 +115,11 @@ namespace OpenSim.Region.CoreModules.Asset
// IImprovedAssetCache // IImprovedAssetCache
// //
public bool Check(string id)
{
return false;
}
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
{ {
if (asset != null) if (asset != null)

View File

@ -145,9 +145,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="texture"></param> /// <param name="texture"></param>
/// <param name="visualParam"></param> /// <param name="visualParam"></param>
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
{ {
DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>()); SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
}
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
{
float oldoff = sp.Appearance.AvatarFeetOffset;
Vector3 oldbox = sp.Appearance.AvatarBoxSize;
SetAppearance(sp, textureEntry, visualParams, cacheItems);
sp.Appearance.SetSize(avSize);
float off = sp.Appearance.AvatarFeetOffset;
Vector3 box = sp.Appearance.AvatarBoxSize;
if (oldoff != off || oldbox != box)
((ScenePresence)sp).SetSize(box, off);
} }
/// <summary> /// <summary>
@ -156,22 +171,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="texture"></param> /// <param name="texture"></param>
/// <param name="visualParam"></param> /// <param name="visualParam"></param>
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
{ {
DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>()); // m_log.DebugFormat(
} // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
// sp.Name, textureEntry, visualParams);
/// <summary>
/// Set appearance data (texture asset IDs and slider settings)
/// </summary>
/// <param name="sp"></param>
/// <param name="texture"></param>
/// <param name="visualParam"></param>
protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
{
// m_log.DebugFormat(
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
// sp.Name, textureEntry, visualParams);
// TODO: This is probably not necessary any longer, just assume the // TODO: This is probably not necessary any longer, just assume the
// textureEntry set implies that the appearance transaction is complete // textureEntry set implies that the appearance transaction is complete
@ -190,36 +194,38 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// m_log.DebugFormat( // m_log.DebugFormat(
// "[AVFACTORY]: Setting visual params for {0} to {1}", // "[AVFACTORY]: Setting visual params for {0} to {1}",
// client.Name, string.Join(", ", visualParamsStrings)); // client.Name, string.Join(", ", visualParamsStrings));
/*
float oldHeight = sp.Appearance.AvatarHeight; float oldHeight = sp.Appearance.AvatarHeight;
changed = sp.Appearance.SetVisualParams(visualParams); changed = sp.Appearance.SetVisualParams(visualParams);
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
*/
// float oldoff = sp.Appearance.AvatarFeetOffset;
// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
changed = sp.Appearance.SetVisualParams(visualParams);
// float off = sp.Appearance.AvatarFeetOffset;
// Vector3 box = sp.Appearance.AvatarBoxSize;
// if(oldoff != off || oldbox != box)
// ((ScenePresence)sp).SetSize(box,off);
} }
// Process the baked texture array // Process the baked texture array
if (textureEntry != null) if (textureEntry != null)
{ {
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
// WriteBakedTexturesReport(sp, m_log.DebugFormat); // WriteBakedTexturesReport(sp, m_log.DebugFormat);
// If bake textures are missing and this is not an NPC, request a rebake from client // If bake textures are missing and this is not an NPC, request a rebake from client
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
RequestRebake(sp, true); RequestRebake(sp, true);
// Save the wearble hashes in the appearance
sp.Appearance.ResetTextureHashes();
if (m_reusetextures)
{
foreach (CachedTextureRequestArg arg in hashes)
sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
}
// This appears to be set only in the final stage of the appearance // This appears to be set only in the final stage of the appearance
// update transaction. In theory, we should be able to do an immediate // update transaction. In theory, we should be able to do an immediate
// appearance send and save here. // appearance send and save here.
@ -253,13 +259,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public bool SendAppearance(UUID agentId) public bool SendAppearance(UUID agentId)
{ {
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
ScenePresence sp = m_scene.GetScenePresence(agentId); ScenePresence sp = m_scene.GetScenePresence(agentId);
if (sp == null) if (sp == null)
{ {
// This is expected if the user has gone away. // This is expected if the user has gone away.
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
return false; return false;
} }
@ -277,6 +283,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return GetBakedTextureFaces(sp); return GetBakedTextureFaces(sp);
} }
public WearableCacheItem[] GetCachedItems(UUID agentId)
{
ScenePresence sp = m_scene.GetScenePresence(agentId);
WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
//foreach (WearableCacheItem item in items)
//{
//}
return items;
}
public bool SaveBakedTextures(UUID agentId) public bool SaveBakedTextures(UUID agentId)
{ {
ScenePresence sp = m_scene.GetScenePresence(agentId); ScenePresence sp = m_scene.GetScenePresence(agentId);
@ -336,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="agentId"></param> /// <param name="agentId"></param>
public void QueueAppearanceSend(UUID agentid) public void QueueAppearanceSend(UUID agentid)
{ {
// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
// 10000 ticks per millisecond, 1000 milliseconds per second // 10000 ticks per millisecond, 1000 milliseconds per second
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
@ -349,7 +366,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public void QueueAppearanceSave(UUID agentid) public void QueueAppearanceSave(UUID agentid)
{ {
// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
// 10000 ticks per millisecond, 1000 milliseconds per second // 10000 ticks per millisecond, 1000 milliseconds per second
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@ -363,6 +380,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public bool ValidateBakedTextureCache(IScenePresence sp) public bool ValidateBakedTextureCache(IScenePresence sp)
{ {
bool defonly = true; // are we only using default textures bool defonly = true; // are we only using default textures
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
WearableCacheItem[] wearableCache = null;
// Cache wearable data for teleport.
// Only makes sense if there's a bake module and a cache module
if (bakedModule != null && cache != null)
{
try
{
wearableCache = bakedModule.Get(sp.UUID);
}
catch (Exception)
{
}
if (wearableCache != null)
{
for (int i = 0; i < wearableCache.Length; i++)
{
cache.Cache(wearableCache[i].TextureAsset);
}
}
}
/*
IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
if (invService.GetRootFolder(userID) != null)
{
WearableCacheItem[] wearableCache = null;
if (bakedModule != null)
{
try
{
wearableCache = bakedModule.Get(userID);
appearance.WearableCacheItems = wearableCache;
appearance.WearableCacheItemsDirty = false;
foreach (WearableCacheItem item in wearableCache)
{
appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID;
}
}
catch (Exception)
{
}
}
*/
// Process the texture entry // Process the texture entry
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@ -370,13 +434,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
int idx = AvatarAppearance.BAKE_INDICES[i]; int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
// if there is no texture entry, skip it // No face, so lets check our baked service cache, teleport or login.
if (face == null) if (face == null)
continue; {
if (wearableCache != null)
{
// If we find the an appearance item, set it as the textureentry and the face
WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache);
if (searchitem != null)
{
sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx);
sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID;
face = sp.Appearance.Texture.FaceTextures[idx];
}
else
{
// if there is no texture entry and no baked cache, skip it
continue;
}
}
else
{
//No texture entry face and no cache. Skip this face.
continue;
}
}
// m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", // m_log.DebugFormat(
// face.TextureID, idx, client.Name, client.AgentId); // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it // if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter // this should probably be more intelligent (skirt texture doesnt matter
@ -387,11 +474,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
defonly = false; // found a non-default texture reference defonly = false; // found a non-default texture reference
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) if (cache != null)
return false; {
if (!cache.Check(face.TextureID.ToString()))
return false;
}
else
{
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
return false;
}
} }
// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
// If we only found default textures, then the appearance is not cached // If we only found default textures, then the appearance is not cached
return (defonly ? false : true); return (defonly ? false : true);
@ -400,6 +495,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{ {
int texturesRebaked = 0; int texturesRebaked = 0;
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
@ -410,9 +506,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (face == null) if (face == null)
continue; continue;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId); // face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it // if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter // this should probably be more intelligent (skirt texture doesnt matter
@ -423,21 +519,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (missingTexturesOnly) if (missingTexturesOnly)
{ {
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) if (cache != null)
{ {
continue; if (cache.Check(face.TextureID.ToString()))
continue;
else
{
m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
}
} }
else else
{ {
// On inter-simulator teleports, this occurs if baked textures are not being stored by the if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
// grid asset service (which means that they are not available to the new region and so have {
// to be re-requested from the client). continue;
// }
// The only available core OpenSimulator behaviour right now
// is not to store these textures, temporarily or otherwise. else
m_log.DebugFormat( {
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", // On inter-simulator teleports, this occurs if baked textures are not being stored by the
face.TextureID, idx, sp.Name); // 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(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
}
} }
} }
else else
@ -476,9 +587,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (bakeType == BakeType.Unknown) if (bakeType == BakeType.Unknown)
continue; continue;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
@ -502,7 +613,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
UUID avatarID = kvp.Key; UUID avatarID = kvp.Key;
long sendTime = kvp.Value; long sendTime = kvp.Value;
// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
if (sendTime < now) if (sendTime < now)
{ {
@ -548,11 +659,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (sp == null) if (sp == null)
{ {
// This is expected if the user has gone away. // This is expected if the user has gone away.
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
return; return;
} }
// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
// This could take awhile since it needs to pull inventory // This could take awhile since it needs to pull inventory
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
@ -579,19 +690,52 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
{ {
IInventoryService invService = m_scene.InventoryService; IInventoryService invService = m_scene.InventoryService;
bool resetwearable = false;
if (invService.GetRootFolder(userID) != null) if (invService.GetRootFolder(userID) != null)
{ {
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
{ {
for (int j = 0; j < appearance.Wearables[i].Count; j++) for (int j = 0; j < appearance.Wearables[i].Count; j++)
{ {
// Check if the default wearables are not set
if (appearance.Wearables[i][j].ItemID == UUID.Zero) if (appearance.Wearables[i][j].ItemID == UUID.Zero)
continue; {
switch ((WearableType) i)
{
case WearableType.Eyes:
case WearableType.Hair:
case WearableType.Shape:
case WearableType.Skin:
//case WearableType.Underpants:
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
resetwearable = true;
m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
resetwearable = true;
break;
// Ignore ruth's assets }
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
continue; continue;
}
// Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
{
switch ((WearableType)i)
{
case WearableType.Eyes:
case WearableType.Hair:
case WearableType.Shape:
case WearableType.Skin:
//case WearableType.Underpants:
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
resetwearable = true;
break;
}
continue;
}
InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
baseItem = invService.GetItem(baseItem); baseItem = invService.GetItem(baseItem);
@ -599,6 +743,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (baseItem != null) if (baseItem != null)
{ {
appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
int unmodifiedWearableIndexForClosure = i;
m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
delegate(string x, object y, AssetBase z)
{
if (z == null)
{
TryAndRepairBrokenWearable(
(WearableType)unmodifiedWearableIndexForClosure, invService,
userID, appearance);
}
});
} }
else else
{ {
@ -606,17 +761,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
"[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
appearance.Wearables[i][j].ItemID, (WearableType)i); appearance.Wearables[i][j].ItemID, (WearableType)i);
appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
resetwearable = true;
} }
} }
} }
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int) WearableType.Eyes] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Shape] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Shape][0].ItemID,
appearance.Wearables[(int)WearableType.Shape][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Hair] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Hair][0].ItemID,
appearance.Wearables[(int)WearableType.Hair][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Skin] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Skin][0].ItemID,
appearance.Wearables[(int)WearableType.Skin][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
resetwearable = true;
}
}
if (resetwearable)
{
ScenePresence presence = null;
if (m_scene.TryGetScenePresence(userID, out presence))
{
presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
presence.Appearance.Serial++);
}
}
} }
else else
{ {
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
} }
} }
private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
{
UUID defaultwearable = GetDefaultItem(type);
if (defaultwearable != UUID.Zero)
{
UUID newInvItem = UUID.Random();
InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
{
AssetID =
defaultwearable,
AssetType
=
(int)
AssetType
.Bodypart,
CreatorId
=
userID
.ToString
(),
//InvType = (int)InventoryType.Wearable,
Description
=
"Failed Wearable Replacement",
Folder =
invService
.GetFolderForType
(userID,
AssetType
.Bodypart)
.ID,
Flags = (uint) type,
Name = Enum.GetName(typeof (WearableType), type),
BasePermissions = (uint) PermissionMask.Copy,
CurrentPermissions = (uint) PermissionMask.Copy,
EveryOnePermissions = (uint) PermissionMask.Copy,
GroupPermissions = (uint) PermissionMask.Copy,
NextPermissions = (uint) PermissionMask.Copy
};
invService.AddItem(itembase);
UUID LinkInvItem = UUID.Random();
itembase = new InventoryItemBase(LinkInvItem, userID)
{
AssetID =
newInvItem,
AssetType
=
(int)
AssetType
.Link,
CreatorId
=
userID
.ToString
(),
InvType = (int) InventoryType.Wearable,
Description
=
"Failed Wearable Replacement",
Folder =
invService
.GetFolderForType
(userID,
AssetType
.CurrentOutfitFolder)
.ID,
Flags = (uint) type,
Name = Enum.GetName(typeof (WearableType), type),
BasePermissions = (uint) PermissionMask.Copy,
CurrentPermissions = (uint) PermissionMask.Copy,
EveryOnePermissions = (uint) PermissionMask.Copy,
GroupPermissions = (uint) PermissionMask.Copy,
NextPermissions = (uint) PermissionMask.Copy
};
invService.AddItem(itembase);
appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
ScenePresence presence = null;
if (m_scene.TryGetScenePresence(userID, out presence))
{
m_scene.SendInventoryUpdate(presence.ControllingClient,
invService.GetFolderForType(userID,
AssetType
.CurrentOutfitFolder),
false, true);
}
}
}
private UUID GetDefaultItem(WearableType wearable)
{
// These are ruth
UUID ret = UUID.Zero;
switch (wearable)
{
case WearableType.Eyes:
ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
break;
case WearableType.Hair:
ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
break;
case WearableType.Pants:
ret = new UUID("00000000-38f9-1111-024e-222222111120");
break;
case WearableType.Shape:
ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
break;
case WearableType.Shirt:
ret = new UUID("00000000-38f9-1111-024e-222222111110");
break;
case WearableType.Skin:
ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
break;
case WearableType.Undershirt:
ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
break;
case WearableType.Underpants:
ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
break;
}
return ret;
}
#endregion #endregion
#region Client Event Handlers #region Client Event Handlers
@ -626,12 +1000,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="client"></param> /// <param name="client"></param>
private void Client_OnRequestWearables(IClientAPI client) private void Client_OnRequestWearables(IClientAPI client)
{ {
// m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); Util.FireAndForget(delegate(object x)
ScenePresence sp = m_scene.GetScenePresence(client.AgentId); {
if (sp != null) Thread.Sleep(4000);
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
else // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null)
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
else
m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
});
} }
/// <summary> /// <summary>
@ -640,12 +1019,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="client"></param> /// <param name="client"></param>
/// <param name="texture"></param> /// <param name="texture"></param>
/// <param name="visualParam"></param> /// <param name="visualParam"></param>
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
{ {
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null) if (sp != null)
DoSetAppearance(sp, textureEntry, visualParams, hashes); SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
else else
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
} }
@ -702,7 +1081,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="cachedTextureRequest"></param> /// <param name="cachedTextureRequest"></param>
private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
{ {
// m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
@ -713,20 +1092,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (m_reusetextures) if (m_reusetextures)
{ {
if (sp.Appearance.GetTextureHash(index) == request.WearableHashID) // this is the most insanely dumb way to do this... however it seems to
{ // actually work. if the appearance has been reset because wearables have
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; // changed then the texture entries are zero'd out until the bakes are
if (face != null) // uploaded. on login, if the textures exist in the cache (eg if you logged
texture = face.TextureID; // into the simulator recently, then the appearance will pull those and send
} // them back in the packet and you won't have to rebake. if the textures aren't
else // in the cache then the intial makeroot() call in scenepresence will zero
{ // them out.
// We know that that hash is wrong, null it out //
// and wait for the setappearance call // a better solution (though how much better is an open question) is to
sp.Appearance.SetTextureHash(index,UUID.Zero); // store the hashes in the appearance and compare them. Thats's coming.
}
// m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID); Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
if (face != null)
texture = face.TextureID;
// m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
} }
CachedTextureResponseArg response = new CachedTextureResponseArg(); CachedTextureResponseArg response = new CachedTextureResponseArg();

View File

@ -61,10 +61,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
for (byte i = 0; i < visualParams.Length; i++) for (byte i = 0; i < visualParams.Length; i++)
visualParams[i] = i; visualParams[i] = i;
afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); // afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
// TODO: Check baked texture // TODO: Check baked texture
Assert.AreEqual(visualParams, sp.Appearance.VisualParams); // Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
} }
[Test] [Test]
@ -102,6 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
eyesFace.TextureID = eyesTextureId; eyesFace.TextureID = eyesTextureId;
/*
afm.SetAppearance(sp, bakedTextureEntry, visualParams); afm.SetAppearance(sp, bakedTextureEntry, visualParams);
afm.SaveBakedTextures(userId); afm.SaveBakedTextures(userId);
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); // Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
@ -113,6 +114,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
Assert.That(eyesBake, Is.Not.Null); Assert.That(eyesBake, Is.Not.Null);
Assert.That(eyesBake.Temporary, Is.False); Assert.That(eyesBake.Temporary, Is.False);
Assert.That(eyesBake.Local, Is.False); Assert.That(eyesBake.Local, Is.False);
*/
} }
} }
} }

View File

@ -270,6 +270,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
// Notes // Notes
client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest); client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest);
client.OnAvatarNotesUpdate += NotesUpdate; client.OnAvatarNotesUpdate += NotesUpdate;
// Preferences
client.OnUserInfoRequest += UserPreferencesRequest;
client.OnUpdateUserInfo += UpdateUserPreferences;
} }
#endregion Region Event Handlers #endregion Region Event Handlers
@ -754,8 +758,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
IClientAPI remoteClient = (IClientAPI)sender; IClientAPI remoteClient = (IClientAPI)sender;
string serverURI = string.Empty; string serverURI = string.Empty;
GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
note.TargetId = remoteClient.AgentId; note.UserId = remoteClient.AgentId;
UUID.TryParse(args[0], out note.UserId); UUID.TryParse(args[0], out note.TargetId);
object Note = (object)note; object Note = (object)note;
if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
@ -799,6 +803,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
#endregion Notes #endregion Notes
#region User Preferences
/// <summary>
/// Updates the user preferences.
/// </summary>
/// <param name='imViaEmail'>
/// Im via email.
/// </param>
/// <param name='visible'>
/// Visible.
/// </param>
/// <param name='remoteClient'>
/// Remote client.
/// </param>
public void UpdateUserPreferences(bool imViaEmail, bool visible, IClientAPI remoteClient)
{
UserPreferences pref = new UserPreferences();
pref.UserId = remoteClient.AgentId;
pref.IMViaEmail = imViaEmail;
pref.Visible = visible;
string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
object Pref = pref;
if(!JsonRpcRequest(ref Pref, "user_preferences_update", serverURI, UUID.Random().ToString()))
{
m_log.InfoFormat("[PROFILES]: UserPreferences update error");
remoteClient.SendAgentAlertMessage("Error updating preferences", false);
return;
}
}
/// <summary>
/// Users the preferences request.
/// </summary>
/// <param name='remoteClient'>
/// Remote client.
/// </param>
public void UserPreferencesRequest(IClientAPI remoteClient)
{
UserPreferences pref = new UserPreferences();
pref.UserId = remoteClient.AgentId;
string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
object Pref = (object)pref;
if(!JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString()))
{
m_log.InfoFormat("[PROFILES]: UserPreferences request error");
remoteClient.SendAgentAlertMessage("Error requesting preferences", false);
return;
}
pref = (UserPreferences) Pref;
remoteClient.SendUserInfoReply(pref.IMViaEmail, pref.Visible, pref.EMail);
}
#endregion User Preferences
#region Avatar Properties #region Avatar Properties
/// <summary> /// <summary>
/// Update the avatars interests . /// Update the avatars interests .

View File

@ -410,7 +410,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="position"></param> /// <param name="position"></param>
/// <param name="lookAt"></param> /// <param name="lookAt"></param>
/// <param name="teleportFlags"></param /// <param name="teleportFlags"></param>
private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
{ {
m_log.DebugFormat( m_log.DebugFormat(
@ -442,11 +442,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
position.Z = newPosZ; position.Z = newPosZ;
} }
if (sp.Flying)
teleportFlags |= (uint)TeleportFlags.IsFlying;
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendTeleportStart(teleportFlags);
sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
sp.Velocity = Vector3.Zero; sp.Velocity = Vector3.Zero;
sp.Teleport(position); sp.Teleport(position);
@ -649,8 +653,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
// it's actually doing a lot of work. // it's actually doing a lot of work.
IPEndPoint endPoint = finalDestination.ExternalEndPoint; IPEndPoint endPoint = finalDestination.ExternalEndPoint;
if (endPoint == null || endPoint.Address == null)
if (endPoint.Address == null)
{ {
sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
@ -689,6 +692,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// both regions // both regions
if (sp.ParentID != (uint)0) if (sp.ParentID != (uint)0)
sp.StandUp(); sp.StandUp();
else if (sp.Flying)
teleportFlags |= (uint)TeleportFlags.IsFlying;
if (DisableInterRegionTeleportCancellation) if (DisableInterRegionTeleportCancellation)
teleportFlags |= (uint)TeleportFlags.DisableCancel; teleportFlags |= (uint)TeleportFlags.DisableCancel;
@ -1331,6 +1336,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (uinfo != null) if (uinfo != null)
{ {
if (uinfo.HomeRegionID == UUID.Zero)
{
// can't find the Home region: Tell viewer and abort
m_log.ErrorFormat("{0} No grid user info found for {1} {2}. Cannot send home.",
LogHeader, client.Name, client.AgentId);
client.SendTeleportFailed("You don't have a home position set.");
return false;
}
GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
if (regionInfo == null) if (regionInfo == null)
{ {
@ -1350,9 +1363,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else else
{ {
m_log.ErrorFormat( // can't find the Home region: Tell viewer and abort
"[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", client.SendTeleportFailed("Your home region could not be found.");
client.Name, client.AgentId);
} }
return false; return false;
} }
@ -1362,177 +1374,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings #region Agent Crossings
public bool Cross(ScenePresence agent, bool isFlying) // Given a position relative to the current region (which has previously been tested to
// see that it is actually outside the current region), find the new region that the
// point is actually in.
// Returns the coordinates and information of the new region or 'null' of it doesn't exist.
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
{ {
Scene scene = agent.Scene; version = String.Empty;
Vector3 pos = agent.AbsolutePosition; newpos = new Vector3(pos.X, pos.Y, pos.Z);
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
/*
Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); // Compute world location of the object's position
uint neighbourx = scene.RegionInfo.LegacyRegionLocX; double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
uint neighboury = scene.RegionInfo.LegacyRegionLocY; double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
const float boundaryDistance = 1.7f;
Vector3 northCross = new Vector3(0, boundaryDistance, 0);
Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);
// distance into new region to place avatar
const float enterDistance = 0.5f;
if (scene.TestBorderCross(pos + westCross, Cardinals.W))
{
if (scene.TestBorderCross(pos + northCross, Cardinals.N))
{
Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
}
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
}
Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
{
neighbourx--;
newpos.X = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
}
else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
{
Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
newpos.X = enterDistance;
if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
}
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
{
Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
newpos.Y = enterDistance;
}
}
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
}
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
{
Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
newpos.Y = enterDistance;
}
*/
/*
if (pos.X < boundaryDistance) //West
{
neighbourx--;
newpos.X = Constants.RegionSize - enterDistance;
}
else if (pos.X > Constants.RegionSize - boundaryDistance) // East
{
neighbourx++;
newpos.X = enterDistance;
}
if (pos.Y < boundaryDistance) // South
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
{
neighboury++;
newpos.Y = enterDistance;
}
*/
double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X;
double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y;
// Call the grid service to lookup the region containing the new position. // Call the grid service to lookup the region containing the new position.
GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
@ -1540,24 +1396,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (neighbourRegion != null) if (neighbourRegion != null)
{ {
Vector3 newRegionRelativeObjectPosition = new Vector3( // Compute the entity's position relative to the new region
(float)(presenceWorldX - (double)neighbourRegion.RegionLocX), newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
(float)(presenceWorldY - (double)neighbourRegion.RegionLocY), (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
pos.Z); pos.Z);
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false);
InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
newRegionRelativeObjectPosition, scene);
// Check if banned from destination region.
ExpiringCache<ulong, DateTime> r; ExpiringCache<ulong, DateTime> r;
DateTime banUntil; DateTime banUntil;
if (m_bannedRegions.TryGetValue(agentID, out r))
if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
{ {
if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil)) if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
{ {
if (DateTime.Now < banUntil) if (DateTime.Now < banUntil)
return false; {
// If we're banned from the destination, we just can't go there.
neighbourRegion = null;
}
r.Remove(neighbourRegion.RegionHandle); r.Remove(neighbourRegion.RegionHandle);
} }
} }
@ -1566,37 +1421,48 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
r = null; r = null;
} }
// Check to see if we have access to the target region.
string reason; string reason;
string version; if (neighbourRegion != null
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason)) && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
if (r == null) if (r == null)
{ {
r = new ExpiringCache<ulong, DateTime>(); r = new ExpiringCache<ulong, DateTime>();
r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
} }
else else
{ {
r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
} }
return false; neighbourRegion = null;
} }
agent.IsInTransit = true;
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newRegionRelativeObjectPosition,
(uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY,
neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
} }
else
return neighbourRegion;
}
public bool Cross(ScenePresence agent, bool isFlying)
{
uint x;
uint y;
Vector3 newpos;
string version;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos);
if (neighbourRegion == null)
{ {
m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos); agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
return false;
} }
agent.IsInTransit = true;
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
return true; return true;
} }
@ -1677,52 +1543,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
icon.EndInvoke(iar); icon.EndInvoke(iar);
} }
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
{
if (neighbourRegion == null)
return false;
m_entityTransferStateMachine.SetInTransit(agent.UUID);
agent.RemoveFromPhysicalScene();
return true;
}
/// <summary> /// <summary>
/// This Closes child agents on neighbouring regions /// This Closes child agents on neighbouring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
protected ScenePresence CrossAgentToNewRegionAsync( public ScenePresence CrossAgentToNewRegionAsync(
ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, string version) bool isFlying, string version)
{ {
if (neighbourRegion == null) if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
return agent;
if (!m_entityTransferStateMachine.SetInTransit(agent.UUID))
{ {
m_log.ErrorFormat( m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
"[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
return agent; return agent;
} }
bool transitWasReset = false; if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
{
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
return agent;
}
CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
return agent;
}
public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
{
try try
{ {
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
Scene m_scene = agent.Scene;
if (!agent.ValidateAttachments())
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
pos = pos + agent.Velocity;
Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
agent.RemoveFromPhysicalScene();
AgentData cAgent = new AgentData(); AgentData cAgent = new AgentData();
agent.CopyTo(cAgent); agent.CopyTo(cAgent);
cAgent.Position = pos; cAgent.Position = pos + agent.Velocity;
if (isFlying) if (isFlying)
cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@ -1732,7 +1595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Beyond this point, extra cleanup is needed beyond removing transit state // Beyond this point, extra cleanup is needed beyond removing transit state
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
{ {
// region doesn't take it // region doesn't take it
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@ -1744,72 +1607,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
ReInstantiateScripts(agent); ReInstantiateScripts(agent);
agent.AddToPhysicalScene(isFlying); agent.AddToPhysicalScene(isFlying);
return agent; return false;
} }
//m_log.Debug("BEFORE CROSS");
//Scene.DumpChildrenSeeds(UUID);
//DumpKnownRegions();
string agentcaps;
if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
{
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
neighbourRegion.RegionHandle);
return agent;
}
// No turning back
agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
if (m_eqModule != null)
{
m_eqModule.CrossRegion(
neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
capsPath, agent.UUID, agent.ControllingClient.SessionId);
}
else
{
agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
capsPath);
}
// SUCCESS!
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
agent.MakeChildAgent();
// FIXME: Possibly this should occur lower down after other commands to close other agents,
// but not sure yet what the side effects would be.
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
transitWasReset = true;
// now we have a child agent in this region. Request all interesting data about other (root) agents
agent.SendOtherAgentsAvatarDataToMe();
agent.SendOtherAgentsAppearanceToMe();
// Backwards compatibility. Best effort
if (version == "Unknown" || version == string.Empty)
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
}
// Next, let's close the child agent connections that are too far away.
agent.CloseChildAgents(neighbourx, neighboury);
AgentHasMovedAway(agent, false);
//m_log.Debug("AFTER CROSS");
//Scene.DumpChildrenSeeds(UUID);
//DumpKnownRegions();
} }
catch (Exception e) catch (Exception e)
{ {
@ -1818,14 +1618,97 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
// TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
} return false;
finally
{
if (!transitWasReset)
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
} }
return agent; return true;
}
public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, string version)
{
agent.ControllingClient.RequestClientInfo();
string agentcaps;
if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
{
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
neighbourRegion.RegionHandle);
return;
}
// No turning back
agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
if (m_eqModule != null)
{
m_eqModule.CrossRegion(
neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
capsPath, agent.UUID, agent.ControllingClient.SessionId);
}
else
{
agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
capsPath);
}
// SUCCESS!
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
agent.MakeChildAgent();
// FIXME: Possibly this should occur lower down after other commands to close other agents,
// but not sure yet what the side effects would be.
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
// now we have a child agent in this region. Request all interesting data about other (root) agents
agent.SendOtherAgentsAvatarDataToMe();
agent.SendOtherAgentsAppearanceToMe();
// Backwards compatibility. Best effort
if (version == "Unknown" || version == string.Empty)
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
}
// Next, let's close the child agent connections that are too far away.
uint neighbourx;
uint neighboury;
Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
neighbourx /= Constants.RegionSize;
neighboury /= Constants.RegionSize;
agent.CloseChildAgents(neighbourx, neighboury);
AgentHasMovedAway(agent, false);
// the user may change their profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
// {
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
// }
//m_log.Debug("AFTER CROSS");
//Scene.DumpChildrenSeeds(UUID);
//DumpKnownRegions();
return;
} }
private void CrossAgentToNewRegionCompleted(IAsyncResult iar) private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@ -1896,10 +1779,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Id0 = currentAgentCircuit.Id0; agent.Id0 = currentAgentCircuit.Id0;
} }
InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; IPEndPoint external = region.ExternalEndPoint;
d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, if (external != null)
{
InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
d.BeginInvoke(sp, agent, region, external, true,
InformClientOfNeighbourCompleted, InformClientOfNeighbourCompleted,
d); d);
}
} }
#endregion #endregion
@ -2116,7 +2003,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (ret == null) if (ret == null)
{ {
// If the simple lookup failed, search the larger area for a region that contains this point // If the simple lookup failed, search the larger area for a region that contains this point
double range = (double)Constants.RegionSize + 2; double range = (double)Constants.RegionSize * 2 + 2;
while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
{ {
// Get from the grid service a list of regions that might contain this point // Get from the grid service a list of regions that might contain this point
@ -2387,175 +2274,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
} }
/*
int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
Vector3 EastCross = new Vector3(0.1f, 0, 0);
Vector3 WestCross = new Vector3(-0.1f, 0, 0);
Vector3 NorthCross = new Vector3(0, 0.1f, 0);
Vector3 SouthCross = new Vector3(0, -0.1f, 0);
// use this default if no borders were crossed (handle of the current region)
ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY);
Vector3 pos = attemptedPosition;
int changeX = 1;
int changeY = 1;
if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
{
if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
{
Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
if (crossedBorderx.BorderLine.Z > 0)
{
pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.X = ((pos.X + Constants.RegionSize));
Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
//(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
if (crossedBordery.BorderLine.Z > 0)
{
pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.Y = ((pos.Y + Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
(uint)((thisy - changeY) * Constants.RegionSize));
// x - 1
// y - 1
}
else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
{
Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
if (crossedBorderx.BorderLine.Z > 0)
{
pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.X = ((pos.X + Constants.RegionSize));
Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
//(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
if (crossedBordery.BorderLine.Z > 0)
{
pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.Y = ((pos.Y + Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
(uint)((thisy + changeY) * Constants.RegionSize));
// x - 1
// y + 1
}
else
{
Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
if (crossedBorderx.BorderLine.Z > 0)
{
pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.X = ((pos.X + Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
(uint)(thisy * Constants.RegionSize));
// x - 1
}
}
else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
{
if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
{
pos.X = ((pos.X - Constants.RegionSize));
Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
//(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
if (crossedBordery.BorderLine.Z > 0)
{
pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.Y = ((pos.Y + Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
(uint)((thisy - changeY) * Constants.RegionSize));
// x + 1
// y - 1
}
else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
{
pos.X = ((pos.X - Constants.RegionSize));
pos.Y = ((pos.Y - Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
(uint)((thisy + changeY) * Constants.RegionSize));
// x + 1
// y + 1
}
else
{
pos.X = ((pos.X - Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
(uint)(thisy * Constants.RegionSize));
// x + 1
}
}
else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
{
Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
//(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
if (crossedBordery.BorderLine.Z > 0)
{
pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
}
else
pos.Y = ((pos.Y + Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
// y - 1
}
else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
{
pos.Y = ((pos.Y - Constants.RegionSize));
newRegionHandle
= Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
// y + 1
}
*/
// Remember the old group position in case the region lookup fails so position can be restored. // Remember the old group position in case the region lookup fails so position can be restored.
Vector3 oldGroupPosition = grp.RootPart.GroupPosition; Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
@ -2576,30 +2294,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
attemptedPosition.Z); attemptedPosition.Z);
} }
if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) if (destination != null)
{ {
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); if (!CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
{
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
// We are going to move the object back to the old position so long as the old position // We are going to move the object back to the old position so long as the old position
// is in the region // is in the region
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
grp.RootPart.GroupPosition = oldGroupPosition; grp.AbsolutePosition = oldGroupPosition;
grp.Velocity = Vector3.Zero;
if (grp.RootPart.PhysActor != null)
grp.RootPart.PhysActor.CrossingFailure();
// Need to turn off the physics flags, otherwise the object will continue to attempt to if (grp.RootPart.KeyframeMotion != null)
// move out of the region creating an infinite loop of failed attempts to cross grp.RootPart.KeyframeMotion.CrossingFailure();
grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false);
if (grp.RootPart.KeyframeMotion != null) grp.ScheduleGroupForFullUpdate();
grp.RootPart.KeyframeMotion.CrossingFailure(); }
grp.ScheduleGroupForFullUpdate();
} }
} }
/// <summary> /// <summary>
/// Move the given scene object into a new region /// Move the given scene object into a new region
/// </summary> /// </summary>
@ -2650,17 +2369,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
grp, e); grp, e);
} }
} }
/*
* done on caller ( not in attachments crossing for now)
else else
{ {
if (!grp.IsDeleted) if (!grp.IsDeleted)
{ {
PhysicsActor pa = grp.RootPart.PhysActor; PhysicsActor pa = grp.RootPart.PhysActor;
if (pa != null) if (pa != null)
{
pa.CrossingFailure(); pa.CrossingFailure();
if (grp.RootPart.KeyframeMotion != null)
{
// moved to KeyframeMotion.CrossingFailure
// grp.RootPart.Velocity = Vector3.Zero;
grp.RootPart.KeyframeMotion.CrossingFailure();
// grp.SendGroupRootTerseUpdate();
}
}
} }
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
} }
*/
} }
else else
{ {

View File

@ -153,6 +153,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile
Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest); Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate); Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate); Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
Server.AddJsonRPCHandler("user_preferences_update", handler.UserPreferenecesUpdate);
Server.AddJsonRPCHandler("user_preferences_request", handler.UserPreferencesRequest);
Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest); Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData); Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);

View File

@ -425,6 +425,19 @@ namespace OpenSim.Region.CoreModules.World.Land
return false; return false;
} }
public bool CanBeOnThisLand(UUID avatar, float posHeight)
{
if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
{
return false;
}
else if (IsRestrictedFromLand(avatar))
{
return false;
}
return true;
}
public bool HasGroupAccess(UUID avatar) public bool HasGroupAccess(UUID avatar)
{ {
if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)

View File

@ -216,13 +216,13 @@ namespace OpenSim.Region.CoreModules
// FIXME: If console region is root then this will be printed by every module. Currently, there is no // FIXME: If console region is root then this will be printed by every module. Currently, there is no
// way to prevent this, short of making the entire module shared (which is complete overkill). // way to prevent this, short of making the entire module shared (which is complete overkill).
// One possibility is to return a bool to signal whether the module has completely handled the command // One possibility is to return a bool to signal whether the module has completely handled the command
m_log.InfoFormat("[WIND]: Please change to a specific region in order to set Sun parameters."); MainConsole.Instance.Output("Please change to a specific region in order to set Sun parameters.");
return; return;
} }
if (m_scene.ConsoleScene() != m_scene) if (m_scene.ConsoleScene() != m_scene)
{ {
m_log.InfoFormat("[WIND]: Console Scene is not my scene."); MainConsole.Instance.Output("Console Scene is not my scene.");
return; return;
} }
} }
@ -233,7 +233,9 @@ namespace OpenSim.Region.CoreModules
private void HandleConsoleCommand(string module, string[] cmdparams) private void HandleConsoleCommand(string module, string[] cmdparams)
{ {
ValidateConsole(); ValidateConsole();
m_log.Info("[WIND] The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins.");
MainConsole.Instance.Output(
"The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins.");
} }
/// <summary> /// <summary>
@ -246,7 +248,9 @@ namespace OpenSim.Region.CoreModules
if ((cmdparams.Length != 4) if ((cmdparams.Length != 4)
|| !cmdparams[1].Equals("base")) || !cmdparams[1].Equals("base"))
{ {
m_log.Info("[WIND] Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>"); MainConsole.Instance.Output(
"Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>");
return; return;
} }
@ -261,7 +265,9 @@ namespace OpenSim.Region.CoreModules
} }
else else
{ {
m_log.InfoFormat("[WIND] Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]); MainConsole.Instance.OutputFormat(
"Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]);
return; return;
} }
@ -271,22 +277,23 @@ namespace OpenSim.Region.CoreModules
if (desiredPlugin.Equals(m_activeWindPlugin.Name)) if (desiredPlugin.Equals(m_activeWindPlugin.Name))
{ {
m_log.InfoFormat("[WIND] Wind model plugin {0} is already active", cmdparams[3]); MainConsole.Instance.OutputFormat("Wind model plugin {0} is already active", cmdparams[3]);
return; return;
} }
if (m_availableWindPlugins.ContainsKey(desiredPlugin)) if (m_availableWindPlugins.ContainsKey(desiredPlugin))
{ {
m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]]; m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]];
m_log.InfoFormat("[WIND] {0} wind model plugin now active", m_activeWindPlugin.Name);
MainConsole.Instance.OutputFormat("{0} wind model plugin now active", m_activeWindPlugin.Name);
} }
else else
{ {
m_log.InfoFormat("[WIND] Could not find wind model plugin {0}", desiredPlugin); MainConsole.Instance.OutputFormat("Could not find wind model plugin {0}", desiredPlugin);
} }
break; break;
} }
} }
/// <summary> /// <summary>
@ -300,7 +307,7 @@ namespace OpenSim.Region.CoreModules
if ((cmdparams.Length != 4) if ((cmdparams.Length != 4)
&& (cmdparams.Length != 3)) && (cmdparams.Length != 3))
{ {
m_log.Info("[WIND] Usage: wind <plugin> <param> [value]"); MainConsole.Instance.Output("Usage: wind <plugin> <param> [value]");
return; return;
} }
@ -311,16 +318,17 @@ namespace OpenSim.Region.CoreModules
{ {
if (!float.TryParse(cmdparams[3], out value)) if (!float.TryParse(cmdparams[3], out value))
{ {
m_log.InfoFormat("[WIND] Invalid value {0}", cmdparams[3]); MainConsole.Instance.OutputFormat("Invalid value {0}", cmdparams[3]);
} }
try try
{ {
WindParamSet(plugin, param, value); WindParamSet(plugin, param, value);
MainConsole.Instance.OutputFormat("{0} set to {1}", param, value);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.InfoFormat("[WIND] {0}", e.Message); MainConsole.Instance.OutputFormat("{0}", e.Message);
} }
} }
else else
@ -328,11 +336,11 @@ namespace OpenSim.Region.CoreModules
try try
{ {
value = WindParamGet(plugin, param); value = WindParamGet(plugin, param);
m_log.InfoFormat("[WIND] {0} : {1}", param, value); MainConsole.Instance.OutputFormat("{0} : {1}", param, value);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.InfoFormat("[WIND] {0}", e.Message); MainConsole.Instance.OutputFormat("{0}", e.Message);
} }
} }
@ -366,13 +374,11 @@ namespace OpenSim.Region.CoreModules
{ {
IWindModelPlugin windPlugin = m_availableWindPlugins[plugin]; IWindModelPlugin windPlugin = m_availableWindPlugins[plugin];
windPlugin.WindParamSet(param, value); windPlugin.WindParamSet(param, value);
m_log.InfoFormat("[WIND] {0} set to {1}", param, value);
} }
else else
{ {
throw new Exception(String.Format("Could not find plugin {0}", plugin)); throw new Exception(String.Format("Could not find plugin {0}", plugin));
} }
} }
public float WindParamGet(string plugin, string param) public float WindParamGet(string plugin, string param)

View File

@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IAvatarFactoryModule public interface IAvatarFactoryModule
{ {
void SetAppearance(IScenePresence sp, AvatarAppearance appearance); void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems);
void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems);
/// <summary> /// <summary>
/// Send the appearance of an avatar to others in the scene. /// Send the appearance of an avatar to others in the scene.
@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns> /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId); Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
WearableCacheItem[] GetCachedItems(UUID agentId);
/// <summary> /// <summary>
/// Save the baked textures for the given agent permanently in the asset database. /// Save the baked textures for the given agent permanently in the asset database.
/// </summary> /// </summary>

View File

@ -0,0 +1,40 @@
/*
* 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 Nini.Config;
using OpenSim.Framework;
using OpenMetaverse;
namespace OpenSim.Services.Interfaces
{
public interface IBakedTextureModule
{
WearableCacheItem[] Get(UUID id);
void Store(UUID id, WearableCacheItem[] data);
}
}

View File

@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
public interface IEntityTransferModule public interface IEntityTransferModule
{ {
/// <summary> /// <summary>
@ -50,30 +52,11 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name='teleportFlags'></param> /// <param name='teleportFlags'></param>
void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags);
/// <summary>
/// Teleport an agent directly to a given region without checking whether the region should be subsituted.
/// </summary>
/// <remarks>
/// Please use Teleport() instead unless you know exactly what you're doing.
/// Do not use for same region teleports.
/// </remarks>
/// <param name='sp'></param>
/// <param name='reg'></param>
/// <param name='finalDestination'>/param>
/// <param name='position'></param>
/// <param name='lookAt'></param>
/// <param name='teleportFlags'></param>
void DoTeleport(
ScenePresence sp, GridRegion reg, GridRegion finalDestination,
Vector3 position, Vector3 lookAt, uint teleportFlags);
/// <summary>
/// Teleports the agent for the given client to their home destination.
/// </summary>
/// <param name='id'></param>
/// <param name='client'></param>
bool TeleportHome(UUID id, IClientAPI client); bool TeleportHome(UUID id, IClientAPI client);
void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
Vector3 position, Vector3 lookAt, uint teleportFlags);
/// <summary> /// <summary>
/// Show whether the given agent is being teleported. /// Show whether the given agent is being teleported.
/// </summary> /// </summary>
@ -89,7 +72,12 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region); void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos);
void Cross(SceneObjectGroup sog, Vector3 position, bool silent); void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
} }
public interface IUserAgentVerificationModule public interface IUserAgentVerificationModule

View File

@ -118,6 +118,7 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_hasGroupChanged = false; private bool m_hasGroupChanged = false;
private long timeFirstChanged; private long timeFirstChanged;
private long timeLastChanged; private long timeLastChanged;
private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
/// <summary> /// <summary>
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@ -428,6 +429,12 @@ namespace OpenSim.Region.Framework.Scenes
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
} }
private struct avtocrossInfo
{
public ScenePresence av;
public uint ParentID;
}
/// <summary> /// <summary>
/// The absolute position of this scene object in the scene /// The absolute position of this scene object in the scene
/// </summary> /// </summary>
@ -455,10 +462,119 @@ namespace OpenSim.Region.Framework.Scenes
|| Scene.TestBorderCross(val, Cardinals.S)) || Scene.TestBorderCross(val, Cardinals.S))
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
{ {
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
string version = String.Empty;
Vector3 newpos = Vector3.Zero;
OpenSim.Services.Interfaces.GridRegion destination = null;
if (m_rootPart.KeyframeMotion != null) if (m_rootPart.KeyframeMotion != null)
m_rootPart.KeyframeMotion.StartCrossingCheck(); m_rootPart.KeyframeMotion.StartCrossingCheck();
m_scene.CrossPrimGroupIntoNewRegion(val, this, true); bool canCross = true;
foreach (ScenePresence av in m_linkedAvatars)
{
// We need to cross these agents. First, let's find
// out if any of them can't cross for some reason.
// We have to deny the crossing entirely if any
// of them are banned. Alternatively, we could
// unsit banned agents....
// We set the avatar position as being the object
// position to get the region to send to
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null)
{
canCross = false;
break;
}
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
}
if (canCross)
{
// We unparent the SP quietly so that it won't
// be made to stand up
List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
foreach (ScenePresence av in m_linkedAvatars)
{
avtocrossInfo avinfo = new avtocrossInfo();
SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
if (parentPart != null)
av.ParentUUID = parentPart.UUID;
avinfo.av = av;
avinfo.ParentID = av.ParentID;
avsToCross.Add(avinfo);
av.PrevSitOffset = av.OffsetPosition;
av.ParentID = 0;
}
// m_linkedAvatars.Clear();
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
// Normalize
if (val.X >= Constants.RegionSize)
val.X -= Constants.RegionSize;
if (val.Y >= Constants.RegionSize)
val.Y -= Constants.RegionSize;
if (val.X < 0)
val.X += Constants.RegionSize;
if (val.Y < 0)
val.Y += Constants.RegionSize;
// If it's deleted, crossing was successful
if (IsDeleted)
{
// foreach (ScenePresence av in m_linkedAvatars)
foreach (avtocrossInfo avinfo in avsToCross)
{
ScenePresence av = avinfo.av;
if (!av.IsInTransit) // just in case...
{
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
av.IsInTransit = true;
CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
}
else
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
}
avsToCross.Clear();
return;
}
else // cross failed, put avas back ??
{
foreach (avtocrossInfo avinfo in avsToCross)
{
ScenePresence av = avinfo.av;
av.ParentUUID = UUID.Zero;
av.ParentID = avinfo.ParentID;
// m_linkedAvatars.Add(av);
}
}
avsToCross.Clear();
}
else
{
if (m_rootPart.KeyframeMotion != null)
m_rootPart.KeyframeMotion.CrossingFailure();
if (RootPart.PhysActor != null)
{
RootPart.PhysActor.CrossingFailure();
}
}
Vector3 oldp = AbsolutePosition;
val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
} }
} }
@ -495,6 +611,39 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public override Vector3 Velocity
{
get { return RootPart.Velocity; }
set { RootPart.Velocity = value; }
}
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
{
CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
ScenePresence agent = icon.EndInvoke(iar);
//// If the cross was successful, this agent is a child agent
if (agent.IsChildAgent)
{
if (agent.ParentUUID != UUID.Zero)
{
agent.ParentPart = null;
// agent.ParentPosition = Vector3.Zero;
// agent.ParentUUID = UUID.Zero;
}
}
agent.ParentUUID = UUID.Zero;
// agent.Reset();
// else // Not successful
// agent.RestoreInCurrentScene();
// In any case
agent.IsInTransit = false;
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
}
public override uint LocalId public override uint LocalId
{ {
get { return m_rootPart.LocalId; } get { return m_rootPart.LocalId; }
@ -1096,6 +1245,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -1105,6 +1255,46 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentID = m_rootPart.LocalId; part.ParentID = m_rootPart.LocalId;
part.ClearUndoState(); part.ClearUndoState();
} }
/// <summary>
/// Add the avatar to this linkset (avatar is sat).
/// </summary>
/// <param name="agentID"></param>
public void AddAvatar(UUID agentID)
{
ScenePresence presence;
if (m_scene.TryGetScenePresence(agentID, out presence))
{
if (!m_linkedAvatars.Contains(presence))
{
m_linkedAvatars.Add(presence);
}
}
}
/// <summary>
/// Delete the avatar from this linkset (avatar is unsat).
/// </summary>
/// <param name="agentID"></param>
public void DeleteAvatar(UUID agentID)
{
ScenePresence presence;
if (m_scene.TryGetScenePresence(agentID, out presence))
{
if (m_linkedAvatars.Contains(presence))
{
m_linkedAvatars.Remove(presence);
}
}
}
/// <summary>
/// Returns the list of linked presences (avatars sat on this group)
/// </summary>
/// <param name="agentID"></param>
public List<ScenePresence> GetLinkedAvatars()
{
return m_linkedAvatars;
}
public ushort GetTimeDilation() public ushort GetTimeDilation()
{ {

File diff suppressed because it is too large Load Diff

View File

@ -111,15 +111,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
// We need to preserve this here because phys actor is removed by the sit.
Vector3 spPhysActorSize = m_sp.PhysicsActor.Size;
m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
// FIXME: This is different for live avatars - z position is adjusted. This is half the height of the
// default avatar.
// Curiously, Vector3.ToString() will not display the last two places of the float. For example,
// printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337>
Assert.That( Assert.That(
m_sp.AbsolutePosition, m_sp.AbsolutePosition,
Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, spPhysActorSize.Z / 2)));
m_sp.StandUp(); m_sp.StandUp();
@ -147,9 +145,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID)); Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID));
Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
Assert.That( // Assert.That(
m_sp.AbsolutePosition, // m_sp.AbsolutePosition,
Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); // Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
Assert.That(m_sp.PhysicsActor, Is.Null); Assert.That(m_sp.PhysicsActor, Is.Null);
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));

View File

@ -181,9 +181,18 @@ namespace OpenSim.Region.Framework.Scenes
if (part.ParticleSystem.Length > 0) if (part.ParticleSystem.Length > 0)
{ {
Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); try
if (ps.Texture != UUID.Zero) {
assetUuids[ps.Texture] = AssetType.Texture; Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
if (ps.Texture != UUID.Zero)
assetUuids[ps.Texture] = AssetType.Texture;
}
catch (Exception e)
{
m_log.WarnFormat(
"[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
}
} }
TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();

View File

@ -908,7 +908,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
// Mimicking LLClientView which gets always set appearance from client. // Mimicking LLClientView which gets always set appearance from client.
AvatarAppearance appearance; AvatarAppearance appearance;
m_scene.GetAvatarAppearance(this, out appearance); m_scene.GetAvatarAppearance(this, out appearance);
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>()); OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]);
} }
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)

View File

@ -219,9 +219,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
// Warn level because the region cannot be used while logins are disabled // Putting this out to console to make it eye-catching for people who are running OpenSimulator
m_log.WarnFormat( // without info log messages enabled. Making this a warning is arguably misleading since it isn't a
"[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); // warning, and monitor scripts looking for warn/error/fatal messages will received false positives.
// Arguably, log4net needs a status log level (like Apache).
MainConsole.Instance.OutputFormat("INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name);
} }
m_scene.SceneGridService.InformNeighborsThatRegionisUp( m_scene.SceneGridService.InformNeighborsThatRegionisUp(

View File

@ -110,6 +110,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
// ScenePresence.SendInitialData() to reset our entire appearance. // ScenePresence.SendInitialData() to reset our entire appearance.
m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
/*
m_afMod.SetAppearance(sp, originalTe, null); m_afMod.SetAppearance(sp, originalTe, null);
UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
@ -125,6 +126,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
// Have to account for both SP and NPC. // Have to account for both SP and NPC.
Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(2)); Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(2));
*/
} }
[Test] [Test]
@ -321,9 +323,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId)); Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId));
Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
Assert.That( // Assert.That(
npc.AbsolutePosition, // npc.AbsolutePosition,
Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); // Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
m_npcMod.Stand(npc.UUID, m_scene); m_npcMod.Stand(npc.UUID, m_scene);
@ -335,7 +337,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
public void TestSitAndStandWithNoSitTarget() public void TestSitAndStandWithNoSitTarget()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // TestHelpers.EnableLogging();
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
@ -353,13 +355,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
// FIXME: This is different for live avatars - z position is adjusted. This is half the height of the // We should really be using the NPC size but this would mean preserving the physics actor since it is
// default avatar. // removed on sit.
// Curiously, Vector3.ToString() will not display the last two places of the float. For example,
// printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337>
Assert.That( Assert.That(
npc.AbsolutePosition, npc.AbsolutePosition,
Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, sp.PhysicsActor.Size.Z / 2)));
m_npcMod.Stand(npc.UUID, m_scene); m_npcMod.Stand(npc.UUID, m_scene);

View File

@ -118,14 +118,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
public override Vector3 Position { get; set; } public override Vector3 Position { get; set; }
public override Vector3 Size public override Vector3 Size { get; set; }
{
get { return _size; }
set {
_size = value;
_size.Z = _size.Z / 2.0f;
}
}
public override PrimitiveBaseShape Shape public override PrimitiveBaseShape Shape
{ {

View File

@ -40,7 +40,6 @@ using log4net;
using Nini.Config; using Nini.Config;
using System.Reflection; using System.Reflection;
using System.IO; using System.IO;
using ComponentAce.Compression.Libs.zlib;
namespace OpenSim.Region.Physics.Meshing namespace OpenSim.Region.Physics.Meshing
{ {
@ -549,7 +548,6 @@ namespace OpenSim.Region.Physics.Meshing
return true; return true;
} }
/// <summary> /// <summary>
/// decompresses a gzipped OSD object /// decompresses a gzipped OSD object
/// </summary> /// </summary>
@ -564,15 +562,17 @@ namespace OpenSim.Region.Physics.Meshing
{ {
using (MemoryStream outMs = new MemoryStream()) using (MemoryStream outMs = new MemoryStream())
{ {
using (ZOutputStream zOut = new ZOutputStream(outMs)) using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
{ {
byte[] readBuffer = new byte[2048]; byte[] readBuffer = new byte[2048];
inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
int readLen = 0; int readLen = 0;
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
{ while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
zOut.Write(readBuffer, 0, readLen); outMs.Write(readBuffer, 0, readLen);
}
zOut.Flush(); outMs.Flush();
outMs.Seek(0, SeekOrigin.Begin); outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer(); byte[] decompressedBuf = outMs.GetBuffer();

View File

@ -75,7 +75,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
string[] ncLines = { "One", "Two", "Three" }; string[] ncLines = { "One", "Twoè", "Three" };
TaskInventoryItem ncItem TaskInventoryItem ncItem
= TaskInventoryHelpers.AddNotecard(m_scene, m_so.RootPart, "nc", "1", "10", string.Join("\n", ncLines)); = TaskInventoryHelpers.AddNotecard(m_scene, m_so.RootPart, "nc", "1", "10", string.Join("\n", ncLines));

View File

@ -1709,9 +1709,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public bool GetScriptState(UUID itemID) public bool GetScriptState(UUID itemID)
{ {
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance != null) return instance != null && instance.Running;
return instance.Running;
return false;
} }
public void ApiResetScript(UUID itemID) public void ApiResetScript(UUID itemID)
@ -1755,9 +1753,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public DetectParams GetDetectParams(UUID itemID, int idx) public DetectParams GetDetectParams(UUID itemID, int idx)
{ {
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance != null) return instance != null ? instance.GetDetectParams(idx) : null;
return instance.GetDetectParams(idx);
return null;
} }
public void SetMinEventDelay(UUID itemID, double delay) public void SetMinEventDelay(UUID itemID, double delay)
@ -1770,9 +1766,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public UUID GetDetectID(UUID itemID, int idx) public UUID GetDetectID(UUID itemID, int idx)
{ {
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance != null) return instance != null ? instance.GetDetectID(idx) : UUID.Zero;
return instance.GetDetectID(idx);
return UUID.Zero;
} }
public void SetState(UUID itemID, string newState) public void SetState(UUID itemID, string newState)
@ -1786,9 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public int GetStartParameter(UUID itemID) public int GetStartParameter(UUID itemID)
{ {
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance == null) return instance == null ? 0 : instance.StartParam;
return 0;
return instance.StartParam;
} }
public void OnShutdown() public void OnShutdown()
@ -1822,9 +1814,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public IScriptApi GetApi(UUID itemID, string name) public IScriptApi GetApi(UUID itemID, string name)
{ {
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance == null) return instance == null ? null : instance.GetApi(name);
return null;
return instance.GetApi(name);
} }
public void OnGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) public void OnGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)

View File

@ -104,6 +104,8 @@ namespace OpenSim.Server.Handlers.Profiles
Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest); Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate); Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate); Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
Server.AddJsonRPCHandler("user_preferences_update", handler.UserPreferenecesUpdate);
Server.AddJsonRPCHandler("user_preferences_request", handler.UserPreferencesRequest);
Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest); Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData); Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);

View File

@ -381,6 +381,59 @@ namespace OpenSim.Server.Handlers
} }
#endregion Interests #endregion Interests
#region User Preferences
public bool UserPreferencesRequest(OSDMap json, ref JsonRpcResponse response)
{
if(!json.ContainsKey("params"))
{
response.Error.Code = ErrorCode.ParseError;
m_log.DebugFormat ("User Preferences Request");
return false;
}
string result = string.Empty;
UserPreferences prefs = new UserPreferences();
object Prefs = (object)prefs;
OSD.DeserializeMembers(ref Prefs, (OSDMap)json["params"]);
if(Service.UserPreferencesRequest(ref prefs, ref result))
{
response.Result = OSD.SerializeMembers(prefs);
return true;
}
response.Error.Code = ErrorCode.InternalError;
response.Error.Message = string.Format("{0}", result);
m_log.InfoFormat("[PROFILES]: User preferences request error - {0}", response.Error.Message);
return false;
}
public bool UserPreferenecesUpdate(OSDMap json, ref JsonRpcResponse response)
{
if(!json.ContainsKey("params"))
{
response.Error.Code = ErrorCode.ParseError;
response.Error.Message = "no parameters supplied";
m_log.DebugFormat ("User Preferences Update Request");
return false;
}
string result = string.Empty;
UserPreferences prefs = new UserPreferences();
object Prefs = (object)prefs;
OSD.DeserializeMembers(ref Prefs, (OSDMap)json["params"]);
if(Service.UserPreferencesUpdate(ref prefs, ref result))
{
response.Result = OSD.SerializeMembers(prefs);
return true;
}
response.Error.Code = ErrorCode.InternalError;
response.Error.Message = string.Format("{0}", result);
m_log.InfoFormat("[PROFILES]: User preferences update error - {0}", response.Error.Message);
return false;
}
#endregion User Preferences
#region Utility #region Utility
public bool AvatarImageAssetsRequest(OSDMap json, ref JsonRpcResponse response) public bool AvatarImageAssetsRequest(OSDMap json, ref JsonRpcResponse response)
{ {

View File

@ -177,6 +177,7 @@ namespace OpenSim.Services.Interfaces
/// <summary> /// <summary>
/// The location of this region in meters. /// The location of this region in meters.
/// DANGER DANGER! Note that this name means something different in RegionInfo.
/// </summary> /// </summary>
public int RegionLocX public int RegionLocX
{ {
@ -190,6 +191,7 @@ namespace OpenSim.Services.Interfaces
/// <summary> /// <summary>
/// The location of this region in meters. /// The location of this region in meters.
/// DANGER DANGER! Note that this name means something different in RegionInfo.
/// </summary> /// </summary>
public int RegionLocY public int RegionLocY
{ {

View File

@ -43,9 +43,6 @@ namespace OpenSim.Services.Interfaces
} }
/// <summary>
/// HG1.5 only
/// </summary>
public interface IUserAgentService public interface IUserAgentService
{ {
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason); bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason);

View File

@ -58,6 +58,11 @@ namespace OpenSim.Services.Interfaces
bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result); bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result);
#endregion Profile Properties #endregion Profile Properties
#region User Preferences
bool UserPreferencesRequest(ref UserPreferences pref, ref string result);
bool UserPreferencesUpdate(ref UserPreferences pref, ref string result);
#endregion User Preferences
#region Interests #region Interests
bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result); bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result);
#endregion Interests #endregion Interests

View File

@ -37,6 +37,7 @@ using OpenSim.Data;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Services.UserAccountService;
namespace OpenSim.Services.ProfilesService namespace OpenSim.Services.ProfilesService
{ {
@ -163,6 +164,78 @@ namespace OpenSim.Services.ProfilesService
} }
#endregion Interests #endregion Interests
#region User Preferences
public bool UserPreferencesUpdate(ref UserPreferences pref, ref string result)
{
if(string.IsNullOrEmpty(pref.EMail))
{
UserAccount account = new UserAccount();
if(userAccounts is UserAccountService.UserAccountService)
{
try
{
account = userAccounts.GetUserAccount(UUID.Zero, pref.UserId);
if(string.IsNullOrEmpty(account.Email))
{
result = "No Email address on record!";
return false;
}
else
pref.EMail = account.Email;
}
catch
{
m_log.Info ("[PROFILES]: UserAccountService Exception: Could not get user account");
result = "Missing Email address!";
return false;
}
}
else
{
m_log.Info ("[PROFILES]: UserAccountService: Could not get user account");
result = "Missing Email address!";
return false;
}
}
return ProfilesData.UpdateUserPreferences(ref pref, ref result);
}
public bool UserPreferencesRequest(ref UserPreferences pref, ref string result)
{
if(string.IsNullOrEmpty(pref.EMail))
{
UserAccount account = new UserAccount();
if(userAccounts is UserAccountService.UserAccountService)
{
try
{
account = userAccounts.GetUserAccount(UUID.Zero, pref.UserId);
if(string.IsNullOrEmpty(account.Email))
{
result = "No Email address on record!";
return false;
}
else
pref.EMail = account.Email;
}
catch
{
m_log.Info ("[PROFILES]: UserAccountService Exception: Could not get user account");
result = "Missing Email address!";
return false;
}
}
else
{
m_log.Info ("[PROFILES]: UserAccountService: Could not get user account");
result = "Missing Email address!";
return false;
}
}
return ProfilesData.GetUserPreferences(ref pref, ref result);
}
#endregion User Preferences
#region Utility #region Utility
public OSD AvatarImageAssetsRequest(UUID avatarId) public OSD AvatarImageAssetsRequest(UUID avatarId)
{ {

View File

@ -144,6 +144,7 @@ namespace OpenSim.Tests.Performance
// ScenePresence.SendInitialData() to reset our entire appearance. // ScenePresence.SendInitialData() to reset our entire appearance.
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
/*
afm.SetAppearance(sp, originalTe, null); afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
@ -185,6 +186,7 @@ namespace OpenSim.Tests.Performance
endGcMemory / 1024 / 1024, endGcMemory / 1024 / 1024,
startGcMemory / 1024 / 1024, startGcMemory / 1024 / 1024,
(endGcMemory - startGcMemory) / 1024 / 1024); (endGcMemory - startGcMemory) / 1024 / 1024);
*/
} }
} }
} }

View File

@ -585,7 +585,6 @@
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="log4net" path="../../../../bin/"/> <Reference name="log4net" path="../../../../bin/"/>
<Reference name="zlib.net" path="../../../../bin/"/>
<Files> <Files>
<Match pattern="*.cs" recurse="true"/> <Match pattern="*.cs" recurse="true"/>