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.csvarregion
commit
6937eec258
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
|
@ -88,6 +117,18 @@ namespace OpenSim.Framework
|
||||||
get { return m_avatarHeight; }
|
get { return m_avatarHeight; }
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,14 @@ namespace OpenSim.Framework
|
||||||
public UUID TargetId;
|
public UUID TargetId;
|
||||||
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(
|
// 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
|
||||||
|
@ -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,26 +690,70 @@ 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
|
}
|
||||||
|
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)
|
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
|
||||||
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
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();
|
||||||
|
|
|
@ -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);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 .
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -1316,11 +1321,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
#region Teleport Home
|
#region Teleport Home
|
||||||
|
|
||||||
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
|
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
|
||||||
{
|
{
|
||||||
TeleportHome(id, client);
|
TeleportHome(id, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool TeleportHome(UUID id, IClientAPI client)
|
public virtual bool TeleportHome(UUID id, IClientAPI client)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
|
@ -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,63 +1396,73 @@ 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);
|
// Check if banned from destination region.
|
||||||
InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
|
|
||||||
newRegionRelativeObjectPosition, scene);
|
|
||||||
|
|
||||||
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.
|
||||||
r.Remove(neighbourRegion.RegionHandle);
|
neighbourRegion = null;
|
||||||
}
|
}
|
||||||
}
|
r.Remove(neighbourRegion.RegionHandle);
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
r = null;
|
else
|
||||||
|
{
|
||||||
|
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));
|
AgentData cAgent = new AgentData();
|
||||||
|
|
||||||
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();
|
|
||||||
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))
|
||||||
|
{
|
||||||
// We are going to move the object back to the old position so long as the old position
|
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
|
||||||
// is in the region
|
|
||||||
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
|
// We are going to move the object back to the old position so long as the old position
|
||||||
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
|
// is in the region
|
||||||
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
|
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));
|
||||||
grp.RootPart.GroupPosition = oldGroupPosition;
|
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
|
||||||
|
|
||||||
// Need to turn off the physics flags, otherwise the object will continue to attempt to
|
grp.AbsolutePosition = oldGroupPosition;
|
||||||
// move out of the region creating an infinite loop of failed attempts to cross
|
grp.Velocity = Vector3.Zero;
|
||||||
grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false);
|
if (grp.RootPart.PhysActor != null)
|
||||||
|
grp.RootPart.PhysActor.CrossingFailure();
|
||||||
if (grp.RootPart.KeyframeMotion != null)
|
|
||||||
grp.RootPart.KeyframeMotion.CrossingFailure();
|
if (grp.RootPart.KeyframeMotion != null)
|
||||||
|
grp.RootPart.KeyframeMotion.CrossingFailure();
|
||||||
grp.ScheduleGroupForFullUpdate();
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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,13 +462,122 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RootPart.GetStatusSandbox())
|
if (RootPart.GetStatusSandbox())
|
||||||
{
|
{
|
||||||
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
||||||
|
@ -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
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -189,7 +190,8 @@ namespace OpenSim.Services.Interfaces
|
||||||
public int RegionSizeY { get; set; }
|
public int RegionSizeY { get; set; }
|
||||||
|
|
||||||
/// <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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -57,6 +57,11 @@ namespace OpenSim.Services.Interfaces
|
||||||
bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result);
|
bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result);
|
||||||
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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
Loading…
Reference in New Issue