Merge branch 'ubitworkmaster'

avinationmerge
Melanie Thielker 2014-08-20 04:39:48 +02:00
commit 24b4f6ad7b
15 changed files with 758 additions and 407 deletions

View File

@ -431,6 +431,8 @@ namespace OpenSim.Framework
// The code to pack textures, visuals, wearables and attachments // The code to pack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance // should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only // This is retained for backward compatibility only
/* then lets remove
if (Appearance.Texture != null) if (Appearance.Texture != null)
{ {
byte[] rawtextures = Appearance.Texture.GetBytes(); byte[] rawtextures = Appearance.Texture.GetBytes();
@ -459,7 +461,7 @@ namespace OpenSim.Framework
args["attachments"] = attachs; args["attachments"] = attachs;
} }
// End of code to remove // End of code to remove
*/
if ((Controllers != null) && (Controllers.Length > 0)) if ((Controllers != null) && (Controllers.Length > 0))
{ {
OSDArray controls = new OSDArray(Controllers.Length); OSDArray controls = new OSDArray(Controllers.Length);
@ -647,58 +649,71 @@ namespace OpenSim.Framework
// AgentTextures[i++] = o.AsUUID(); // AgentTextures[i++] = o.AsUUID();
//} //}
Appearance = new AvatarAppearance();
// The code to unpack textures, visuals, wearables and attachments // packed_appearence should contain all appearance information
// should be removed; packed appearance contains the full appearance if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
// This is retained for backward compatibility only
if (args["texture_entry"] != null)
{ {
byte[] rawtextures = args["texture_entry"].AsBinary(); m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length); Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
Appearance.SetTextureEntries(textures);
} }
else
if (args["visual_params"] != null)
Appearance.SetVisualParams(args["visual_params"].AsBinary());
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
{ {
OSDArray wears = (OSDArray)(args["wearables"]); // if missing try the old pack method
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method");
int count = wears.Count; Appearance = new AvatarAppearance();
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count / 2; i++) // The code to unpack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
if (args["texture_entry"] != null)
{ {
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); byte[] rawtextures = args["texture_entry"].AsBinary();
Appearance.SetWearable(i,awear); Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
Appearance.SetTextureEntries(textures);
} }
}
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) if (args["visual_params"] != null)
{ Appearance.SetVisualParams(args["visual_params"].AsBinary());
OSDArray attachs = (OSDArray)(args["attachments"]);
foreach (OSD o in attachs) if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
{ {
if (o.Type == OSDType.Map) OSDArray wears = (OSDArray)(args["wearables"]);
int count = wears.Count;
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count / 2; i++)
{ {
// We know all of these must end up as attachments so we AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
// append rather than replace to ensure multiple attachments Appearance.SetWearable(i, awear);
// per point continues to work
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
} }
} }
}
// end of code to remove
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
{
OSDArray attachs = (OSDArray)(args["attachments"]);
foreach (OSD o in attachs)
{
if (o.Type == OSDType.Map)
{
// We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments
// per point continues to work
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
}
}
}
// end of code to remove
}
/* moved above
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
else else
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
*/
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{ {
OSDArray controls = (OSDArray)(args["controllers"]); OSDArray controls = (OSDArray)(args["controllers"]);

View File

@ -755,6 +755,8 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
bool IsActive { get; set; } bool IsActive { get; set; }
int PingTimeMS { get; }
/// <summary> /// <summary>
/// Set if the client is closing due to a logout request /// Set if the client is closing due to a logout request
/// </summary> /// </summary>

View File

@ -81,7 +81,7 @@ namespace OpenSim.Framework
/// Number of milliseconds a call can take before it is considered /// Number of milliseconds a call can take before it is considered
/// a "long" call for warning & debugging purposes /// a "long" call for warning & debugging purposes
/// </summary> /// </summary>
public const int LongCallTime = 3000; public const int LongCallTime = 500;
/// <summary> /// <summary>
/// The maximum length of any data logged because of a long request time. /// The maximum length of any data logged because of a long request time.
@ -208,6 +208,9 @@ namespace OpenSim.Framework
string errorMessage = "unknown error"; string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount(); int tickstart = Util.EnvironmentTickCount();
int tickdata = 0; int tickdata = 0;
int tickcompressdata = 0;
int tickJsondata = 0;
int compsize = 0;
string strBuffer = null; string strBuffer = null;
try try
@ -225,6 +228,8 @@ namespace OpenSim.Framework
{ {
strBuffer = OSDParser.SerializeJsonString(data); strBuffer = OSDParser.SerializeJsonString(data);
tickJsondata = Util.EnvironmentTickCountSubtract(tickstart);
if (DebugLevel >= 5) if (DebugLevel >= 5)
LogOutgoingDetail(strBuffer); LogOutgoingDetail(strBuffer);
@ -243,13 +248,19 @@ namespace OpenSim.Framework
// gets written on the strteam upon Dispose() // gets written on the strteam upon Dispose()
} }
byte[] buf = ms.ToArray(); byte[] buf = ms.ToArray();
tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart);
request.ContentLength = buf.Length; //Count bytes to send request.ContentLength = buf.Length; //Count bytes to send
compsize = buf.Length;
using (Stream requestStream = request.GetRequestStream()) using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buf, 0, (int)buf.Length); requestStream.Write(buf, 0, (int)buf.Length);
} }
} }
else else
{ {
tickcompressdata = tickJsondata;
compsize = buffer.Length;
request.ContentType = "application/json"; request.ContentType = "application/json";
request.ContentLength = buffer.Length; //Count bytes to send request.ContentLength = buffer.Length; //Count bytes to send
using (Stream requestStream = request.GetRequestStream()) using (Stream requestStream = request.GetRequestStream())
@ -291,12 +302,16 @@ namespace OpenSim.Framework
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime) if (tickdiff > LongCallTime)
m_log.InfoFormat( m_log.InfoFormat(
"[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing, {5}", "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing({5} at Json; {6} at comp), {7} bytes ({8} uncomp): {9}",
reqnum, reqnum,
method, method,
url, url,
tickdiff, tickdiff,
tickdata, tickdata,
tickJsondata,
tickcompressdata,
compsize,
strBuffer != null ? strBuffer.Length : 0,
strBuffer != null strBuffer != null
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
: ""); : "");

View File

@ -978,15 +978,25 @@ namespace OpenSim
cdt.AddColumn("Circuit code", 12); cdt.AddColumn("Circuit code", 12);
cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Endpoint", 23);
cdt.AddColumn("Active?", 7); cdt.AddColumn("Active?", 7);
cdt.AddColumn("ChildAgent?", 7);
cdt.AddColumn("ping(ms)", 8);
SceneManager.ForEachScene( SceneManager.ForEachScene(
s => s.ForEachClient( s => s.ForEachClient(
c => cdt.AddRow( c =>
s.Name, {
c.Name, bool child = false;
c.CircuitCode.ToString(), if(c.SceneAgent != null && c.SceneAgent.IsChildAgent)
c.RemoteEndPoint.ToString(), child = true;
c.IsActive.ToString()))); cdt.AddRow(
s.Name,
c.Name,
c.CircuitCode.ToString(),
c.RemoteEndPoint.ToString(),
c.IsActive.ToString(),
child.ToString(),
c.PingTimeMS);
}));
MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.Output(cdt.ToString());
} }

View File

@ -358,7 +358,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// protected HashSet<uint> m_attachmentsSent; // protected HashSet<uint> m_attachmentsSent;
private bool m_deliverPackets = true; private bool m_deliverPackets = true;
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true; private bool m_SendLogoutPacketWhenClosing = true;
/// <summary> /// <summary>
@ -419,6 +419,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
public int PingTimeMS
{
get
{
if (UDPClient != null)
return UDPClient.PingTimeMS;
return 0;
}
}
/// <summary> /// <summary>
/// Entity update queues /// Entity update queues
/// </summary> /// </summary>
@ -440,7 +450,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string Name { get { return FirstName + " " + LastName; } } public string Name { get { return FirstName + " " + LastName; } }
public uint CircuitCode { get { return m_circuitCode; } } public uint CircuitCode { get { return m_circuitCode; } }
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } public int NextAnimationSequenceNumber
{
get { return m_udpServer.NextAnimationSequenceNumber; }
}
/// <summary> /// <summary>
/// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
@ -461,6 +474,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
set { m_disableFacelights = value; } set { m_disableFacelights = value; }
} }
public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
@ -1638,6 +1652,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
pc.PingID.OldestUnacked = 0; pc.PingID.OldestUnacked = 0;
OutPacket(pc, ThrottleOutPacketType.Unknown); OutPacket(pc, ThrottleOutPacketType.Unknown);
UDPClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
} }
public void SendKillObject(List<uint> localIDs) public void SendKillObject(List<uint> localIDs)
@ -3813,8 +3828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
SceneObjectPart e = (SceneObjectPart)entity; SceneObjectPart e = (SceneObjectPart)entity;
SceneObjectGroup g = e.ParentGroup; SceneObjectGroup g = e.ParentGroup;
if (g.RootPart.Shape.State > 30 && g.RootPart.Shape.State < 39) // HUD if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId)
if (g.OwnerID != AgentId)
return; // Don't send updates for other people's HUDs return; // Don't send updates for other people's HUDs
} }
@ -3932,8 +3946,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (part.ParentGroup.IsAttachment) if (part.ParentGroup.IsAttachment)
{ // Someone else's HUD, why are we getting these? { // Someone else's HUD, why are we getting these?
if (part.ParentGroup.OwnerID != AgentId && if (part.ParentGroup.OwnerID != AgentId && part.ParentGroup.HasPrivateAttachmentPoint)
part.ParentGroup.RootPart.Shape.State > 30 && part.ParentGroup.RootPart.Shape.State < 39)
continue; continue;
ScenePresence sp; ScenePresence sp;
// Owner is not in the sim, don't update it to // Owner is not in the sim, don't update it to
@ -5278,16 +5291,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
byte[] objectData = new byte[76]; byte[] objectData = new byte[76];
data.CollisionPlane.ToBytes(objectData, 0);
offsetPosition.ToBytes(objectData, 16);
Vector3 velocity = new Vector3(0, 0, 0); Vector3 velocity = new Vector3(0, 0, 0);
Vector3 acceleration = new Vector3(0, 0, 0); Vector3 acceleration = new Vector3(0, 0, 0);
rotation.Normalize();
Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z);
data.CollisionPlane.ToBytes(objectData, 0);
offsetPosition.ToBytes(objectData, 16);
velocity.ToBytes(objectData, 28); velocity.ToBytes(objectData, 28);
acceleration.ToBytes(objectData, 40); acceleration.ToBytes(objectData, 40);
// data.Velocity.ToBytes(objectData, 28); vrot.ToBytes(objectData, 52);
// data.Acceleration.ToBytes(objectData, 40); data.AngularVelocity.ToBytes(objectData, 64);
rotation.ToBytes(objectData, 52);
//data.AngularVelocity.ToBytes(objectData, 64);
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@ -5343,15 +5357,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
data.RelativePosition.ToBytes(objectData, 0); data.RelativePosition.ToBytes(objectData, 0);
data.Velocity.ToBytes(objectData, 12); data.Velocity.ToBytes(objectData, 12);
data.Acceleration.ToBytes(objectData, 24); data.Acceleration.ToBytes(objectData, 24);
try
{ Quaternion rotation = data.RotationOffset;
data.RotationOffset.ToBytes(objectData, 36); rotation.Normalize();
} Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z);
catch (Exception e) vrot.ToBytes(objectData, 36);
{
m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString());
OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36);
}
data.AngularVelocity.ToBytes(objectData, 48); data.AngularVelocity.ToBytes(objectData, 48);
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();

View File

@ -163,6 +163,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_maxRTO = 60000; private int m_maxRTO = 60000;
public bool m_deliverPackets = true; public bool m_deliverPackets = true;
public int m_lastStartpingTimeMS;
public int m_pingMS;
public int PingTimeMS
{
get
{
if (m_pingMS < 10)
return 10;
if(m_pingMS > 2000)
return 2000;
return m_pingMS;
}
}
/// <summary> /// <summary>
/// This is the percentage of the udp texture queue to add to the task queue since /// This is the percentage of the udp texture queue to add to the task queue since
/// textures are now generally handled through http. /// textures are now generally handled through http.
@ -225,6 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Initialize this to a sane value to prevent early disconnects // Initialize this to a sane value to prevent early disconnects
TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
m_pingMS = (int)(3.0 * server.TickCountResolution); // so filter doesnt start at 0;
} }
/// <summary> /// <summary>

View File

@ -293,6 +293,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Flag to signal when clients should send pings</summary> /// <summary>Flag to signal when clients should send pings</summary>
protected bool m_sendPing; protected bool m_sendPing;
private int m_animationSequenceNumber;
public int NextAnimationSequenceNumber
{
get
{
m_animationSequenceNumber++;
if (m_animationSequenceNumber > 2147482624)
m_animationSequenceNumber = 1;
return m_animationSequenceNumber;
}
}
private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
/// <summary> /// <summary>
@ -369,16 +384,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Measure the resolution of Environment.TickCount // Measure the resolution of Environment.TickCount
TickCountResolution = 0f; TickCountResolution = 0f;
for (int i = 0; i < 5; i++) for (int i = 0; i < 10; i++)
{ {
int start = Environment.TickCount; int start = Environment.TickCount;
int now = start; int now = start;
while (now == start) while (now == start)
now = Environment.TickCount; now = Environment.TickCount;
TickCountResolution += (float)(now - start) * 0.2f; TickCountResolution += (float)(now - start) * 0.1f;
} }
m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
TickCountResolution = (float)Math.Ceiling(TickCountResolution); TickCountResolution = (float)Math.Ceiling(TickCountResolution);
m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
#endregion Environment.TickCount Measurement #endregion Environment.TickCount Measurement
@ -386,6 +401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int sceneThrottleBps = 0; int sceneThrottleBps = 0;
bool usePools = false; bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"]; IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null) if (config != null)
{ {
@ -435,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps); m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource); ThrottleRates = new ThrottleRates(configSource);
Random rnd = new Random(Util.EnvironmentTickCount());
m_animationSequenceNumber = rnd.Next(11474826);
if (usePools) if (usePools)
EnablePools(); EnablePools();
} }
@ -1128,6 +1148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
pc.PingID.OldestUnacked = 0; pc.PingID.OldestUnacked = 0;
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null); SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
} }
public void CompletePing(LLUDPClient udpClient, byte pingID) public void CompletePing(LLUDPClient udpClient, byte pingID)
@ -1577,7 +1598,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else if (packet.Type == PacketType.CompletePingCheck) else if (packet.Type == PacketType.CompletePingCheck)
{ {
// We don't currently track client ping times int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS);
int c = udpClient.m_pingMS;
c = 800 * c + 200 * t;
c /= 1000;
udpClient.m_pingMS = c;
return; return;
} }

View File

@ -120,10 +120,16 @@ namespace OpenSim.Region.CoreModules.Framework
public void CreateCaps(UUID agentId, uint circuitCode) public void CreateCaps(UUID agentId, uint circuitCode)
{ {
// int ts = Util.EnvironmentTickCount();
/* this as no business here...
* must be done elsewhere ( and is )
int flags = m_scene.GetUserFlags(agentId); int flags = m_scene.GetUserFlags(agentId);
m_log.ErrorFormat("[CreateCaps]: banCheck {0} ", Util.EnvironmentTickCountSubtract(ts));
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
return; return;
*/
Caps caps; Caps caps;
String capsObjectPath = GetCapsPath(agentId); String capsObjectPath = GetCapsPath(agentId);
@ -133,18 +139,26 @@ namespace OpenSim.Region.CoreModules.Framework
{ {
Caps oldCaps = m_capsObjects[circuitCode]; Caps oldCaps = m_capsObjects[circuitCode];
//m_log.WarnFormat( // if (capsObjectPath == oldCaps.CapsObjectPath)
// "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", // {
// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); // m_log.WarnFormat(
// "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
// return;
// }
} }
caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
(MainServer.Instance == null) ? 0: MainServer.Instance.Port, (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.RegionInfo.RegionName); capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
// m_log.ErrorFormat("[CreateCaps]: new caps {0} ", Util.EnvironmentTickCountSubtract(ts));
m_capsObjects[circuitCode] = caps; m_capsObjects[circuitCode] = caps;
} }
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
// m_log.ErrorFormat("[CreateCaps]: end {0} ", Util.EnvironmentTickCountSubtract(ts));
} }
public void RemoveCaps(UUID agentId, uint circuitCode) public void RemoveCaps(UUID agentId, uint circuitCode)

View File

@ -430,7 +430,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// TODO: Get proper AVG Height // TODO: Get proper AVG Height
float localAVHeight = 1.56f; float localHalfAVHeight = 0.8f;
if (sp.Appearance != null)
localHalfAVHeight = sp.Appearance.AvatarHeight / 2;
float posZLimit = 22; float posZLimit = 22;
// TODO: Check other Scene HeightField // TODO: Check other Scene HeightField
@ -439,10 +442,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
} }
float newPosZ = posZLimit + localAVHeight; posZLimit += localHalfAVHeight + 0.1f;
if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
{ {
position.Z = newPosZ; position.Z = posZLimit;
} }
if (sp.Flying) if (sp.Flying)
@ -720,7 +724,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
agentCircuit.startpos = position; agentCircuit.startpos = position;
agentCircuit.child = true; agentCircuit.child = true;
agentCircuit.Appearance = sp.Appearance;
// agentCircuit.Appearance = sp.Appearance;
// agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false);
agentCircuit.Appearance = new AvatarAppearance();
agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
if (currentAgentCircuit != null) if (currentAgentCircuit != null)
{ {
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
@ -971,7 +980,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// May need to logout or other cleanup // May need to logout or other cleanup
AgentHasMovedAway(sp, logout); // AgentHasMovedAway(sp, logout);
AgentHasMovedAway(sp, true); // until logout use is checked
// Well, this is it. The agent is over there. // Well, this is it. The agent is over there.
KillEntity(sp.Scene, sp.LocalId); KillEntity(sp.Scene, sp.LocalId);
@ -1138,7 +1148,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.CloseChildAgents(newRegionX, newRegionY); sp.CloseChildAgents(newRegionX, newRegionY);
// May need to logout or other cleanup // May need to logout or other cleanup
AgentHasMovedAway(sp, logout); // AgentHasMovedAway(sp, logout);
AgentHasMovedAway(sp, true);
// Well, this is it. The agent is over there. // Well, this is it. The agent is over there.
KillEntity(sp.Scene, sp.LocalId); KillEntity(sp.Scene, sp.LocalId);
@ -1253,7 +1264,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
{ {
if (sp.Scene.AttachmentsModule != null) if (sp.Scene.AttachmentsModule != null)
sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout);
} }
protected void KillEntity(Scene scene, uint localID) protected void KillEntity(Scene scene, uint localID)
@ -1381,10 +1392,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings #region Agent Crossings
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
{
string r = String.Empty;
return GetDestination(scene, agentID, pos, out xDest, out yDest, out version, out newpos, out r);
}
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos, out string reason)
{ {
version = String.Empty; version = String.Empty;
reason = String.Empty;
newpos = pos; newpos = pos;
// m_log.DebugFormat( // m_log.DebugFormat(
@ -1499,7 +1516,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
string reason;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
{ {
if (r == null) if (r == null)
@ -1525,11 +1541,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint y; uint y;
Vector3 newpos; Vector3 newpos;
string version; string version;
string reason;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos, out reason);
if (neighbourRegion == null) if (neighbourRegion == null)
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into void"); if (reason == String.Empty)
agent.ControllingClient.SendAlertMessage("Cannot cross to region");
else
agent.ControllingClient.SendAlertMessage("Cannot cross to region: " + reason);
return false; return false;
} }
@ -1656,10 +1676,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
{ {
int ts = Util.EnvironmentTickCount();
try try
{ {
AgentData cAgent = new AgentData(); AgentData cAgent = new AgentData();
agent.CopyTo(cAgent); agent.CopyTo(cAgent);
// agent.Appearance.WearableCacheItems = null;
cAgent.Position = pos + agent.Velocity; 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;
@ -1686,6 +1711,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return false; return false;
} }
m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts));
} }
catch (Exception e) catch (Exception e)
{ {
@ -1703,6 +1730,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, string version) bool isFlying, string version)
{ {
agent.ControllingClient.RequestClientInfo(); agent.ControllingClient.RequestClientInfo();
string agentcaps; string agentcaps;
@ -1714,6 +1742,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// No turning back // No turning back
agent.IsChildAgent = true; agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
@ -1737,12 +1768,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
capsPath); capsPath);
} }
// 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);
}
// SUCCESS! // SUCCESS!
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt. // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
// this may need the attachments
agent.parcelRegionCross();
AgentHasMovedAway(agent, true);
agent.MakeChildAgent(); agent.MakeChildAgent();
// FIXME: Possibly this should occur lower down after other commands to close other agents, // FIXME: Possibly this should occur lower down after other commands to close other agents,
@ -1756,16 +1800,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// agent.SendOtherAgentsAvatarDataToMe(); // agent.SendOtherAgentsAvatarDataToMe();
// agent.SendOtherAgentsAppearanceToMe(); // agent.SendOtherAgentsAppearanceToMe();
agent.parcelRegionCross(false);
// 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. // Next, let's close the child agent connections that are too far away.
uint neighbourx; uint neighbourx;
uint neighboury; uint neighboury;
@ -1777,7 +1811,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.CloseChildAgents(neighbourx, neighboury); agent.CloseChildAgents(neighbourx, neighboury);
AgentHasMovedAway(agent, false);
// the user may change their profile information in other region, // the user may change their profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it // so the userinfo in UserProfileCache is not reliable any more, delete it
@ -1817,7 +1851,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Enable Child Agent #region Enable Child Agent
/// <summary> /// <summary>
/// This informs a single neighbouring region about agent "avatar". /// This informs a single neighbouring region about agent "avatar", and avatar about it
/// 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>
/// <param name="sp"></param> /// <param name="sp"></param>
@ -1833,8 +1867,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.startpos = new Vector3(128, 128, 70); agent.startpos = new Vector3(128, 128, 70);
agent.child = true; agent.child = true;
//agent.Appearance = sp.Appearance; agent.Appearance = new AvatarAppearance();
agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
@ -1866,6 +1900,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Id0 = currentAgentCircuit.Id0; agent.Id0 = currentAgentCircuit.Id0;
} }
Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
IPEndPoint external = region.ExternalEndPoint; IPEndPoint external = region.ExternalEndPoint;
if (external != null) if (external != null)
{ {
@ -1884,6 +1920,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <summary> /// <summary>
/// This informs all neighbouring regions about agent "avatar". /// This informs all neighbouring regions about agent "avatar".
/// and as important informs the avatar about then
/// </summary> /// </summary>
/// <param name="sp"></param> /// <param name="sp"></param>
public void EnableChildAgents(ScenePresence sp) public void EnableChildAgents(ScenePresence sp)
@ -1900,81 +1937,77 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?");
} }
/// We need to find the difference between the new regions where there are no child agents LinkedList<ulong> previousRegionNeighbourHandles;
/// and the regions where there are already child agents. We only send notification to the former.
List<ulong> neighbourHandles = NeighbourHandles(neighbours); // on this region
neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too
List<ulong> previousRegionNeighbourHandles;
if (sp.Scene.CapsModule != null)
{
previousRegionNeighbourHandles =
new List<ulong>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys);
}
else
{
previousRegionNeighbourHandles = new List<ulong>();
}
List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
// Dump("Current Neighbors", neighbourHandles);
// Dump("Previous Neighbours", previousRegionNeighbourHandles);
// Dump("New Neighbours", newRegions);
// Dump("Old Neighbours", oldRegions);
/// Update the scene presence's known regions here on this region
sp.DropOldNeighbours(oldRegions);
/// Collect as many seeds as possible
Dictionary<ulong, string> seeds; Dictionary<ulong, string> seeds;
if (sp.Scene.CapsModule != null)
seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
else
seeds = new Dictionary<ulong, string>();
//m_log.Debug(" !!! No. of seeds: " + seeds.Count); if (sp.Scene.CapsModule != null)
{
seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
previousRegionNeighbourHandles = new LinkedList<ulong>(seeds.Keys);
}
else
{
seeds = new Dictionary<ulong, string>();
previousRegionNeighbourHandles = new LinkedList<ulong>();
}
if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle))
seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath); seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
/// Create the necessary child agents AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
List<ulong> newneighbours = new List<ulong>();
List<AgentCircuitData> cagents = new List<AgentCircuitData>(); List<AgentCircuitData> cagents = new List<AgentCircuitData>();
ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
foreach (GridRegion neighbour in neighbours) foreach (GridRegion neighbour in neighbours)
{ {
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) ulong handler = neighbour.RegionHandle;
if (handler == currentRegionHandler)
continue;
AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
agent.BaseFolder = UUID.Zero;
agent.InventoryFolder = UUID.Zero;
agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
agent.child = true;
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
if (currentAgentCircuit != null)
{ {
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); agent.IPAddress = currentAgentCircuit.IPAddress;
agent.BaseFolder = UUID.Zero; agent.Viewer = currentAgentCircuit.Viewer;
agent.InventoryFolder = UUID.Zero; agent.Channel = currentAgentCircuit.Channel;
agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour); agent.Mac = currentAgentCircuit.Mac;
agent.child = true; agent.Id0 = currentAgentCircuit.Id0;
// agent.Appearance = sp.Appearance;
agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less
if (currentAgentCircuit != null)
{
agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
agent.IPAddress = currentAgentCircuit.IPAddress;
agent.Viewer = currentAgentCircuit.Viewer;
agent.Channel = currentAgentCircuit.Channel;
agent.Mac = currentAgentCircuit.Mac;
agent.Id0 = currentAgentCircuit.Id0;
}
if (newRegions.Contains(neighbour.RegionHandle))
{
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath);
seeds.Add(neighbour.RegionHandle, agent.CapsPath);
}
else
{
agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle);
}
cagents.Add(agent);
} }
if (previousRegionNeighbourHandles.Contains(handler))
{
previousRegionNeighbourHandles.Remove(handler);
agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, handler);
}
else
{
newneighbours.Add(handler);
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
sp.AddNeighbourRegion(handler, agent.CapsPath);
seeds.Add(handler, agent.CapsPath);
}
cagents.Add(agent);
}
//sp.DropOldNeighbours(previousRegionNeighbourHandles);
foreach (ulong handle in previousRegionNeighbourHandles)
{
sp.RemoveNeighbourRegion(handle);
Scene.CapsModule.DropChildSeed(sp.UUID, handle);
} }
/// Update all child agent with everyone's seeds /// Update all child agent with everyone's seeds
@ -1987,34 +2020,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds); sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
} }
sp.KnownRegions = seeds; sp.KnownRegions = seeds;
//avatar.Scene.DumpChildrenSeeds(avatar.UUID); //avatar.Scene.DumpChildrenSeeds(avatar.UUID);
//avatar.DumpKnownRegions(); //avatar.DumpKnownRegions();
bool newAgent = false; Util.FireAndForget(delegate
int count = 0;
foreach (GridRegion neighbour in neighbours)
{ {
//m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName); Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
// Don't do it if there's already an agent in that region int count = 0;
if (newRegions.Contains(neighbour.RegionHandle)) bool newagent;
newAgent = true;
else
newAgent = false;
// continue;
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) foreach (GridRegion neighbour in neighbours)
{ {
try try
{ {
// Let's put this back at sync, so that it doesn't clog newagent = newneighbours.Contains(neighbour.RegionHandle);
// the network, especially for regions in the same physical server. InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newagent);
// We're really not in a hurry here.
InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent);
//InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
//d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
// InformClientOfNeighbourCompleted,
// d);
} }
catch (ArgumentOutOfRangeException) catch (ArgumentOutOfRangeException)
@ -2022,9 +2044,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.ErrorFormat( m_log.ErrorFormat(
"[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).",
neighbour.ExternalHostName, neighbour.ExternalHostName,
neighbour.RegionHandle, neighbour.RegionHandle,
neighbour.RegionLocX, neighbour.RegionLocX,
neighbour.RegionLocY); neighbour.RegionLocY);
} }
catch (Exception e) catch (Exception e)
{ {
@ -2041,11 +2063,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes.
// throw e; // throw e;
} }
count++;
} }
count++; });
}
} }
Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
@ -2079,11 +2100,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg,
IPEndPoint endPoint, bool newAgent) IPEndPoint endPoint, bool newAgent)
{ {
// Let's wait just a little to give time to originating regions to catch up with closing child agents Scene scene = sp.Scene;
// after a cross here if (!newAgent)
Thread.Sleep(500); return;
Scene scene = sp.Scene;
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
@ -2097,6 +2116,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (regionAccepted && newAgent) if (regionAccepted && newAgent)
{ {
// give time for createAgent to finish, since it is async and does grid services access
Thread.Sleep(500);
if (m_eqModule != null) if (m_eqModule != null)
{ {
#region IP Translation for NAT #region IP Translation for NAT

View File

@ -557,6 +557,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// <param name="objectIDs"></param> /// <param name="objectIDs"></param>
public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
{ {
/*
if (m_scenePresence.IsChildAgent) if (m_scenePresence.IsChildAgent)
return; return;
@ -571,6 +572,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{ {
client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs); client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs);
}); });
*/
m_scenePresence.SendAnimPack(animations, seqs, objectIDs);
} }
public void SendAnimPackToClient(IClientAPI client) public void SendAnimPackToClient(IClientAPI client)
@ -602,7 +605,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
SendAnimPack(animIDs, sequenceNums, objectIDs); // SendAnimPack(animIDs, sequenceNums, objectIDs);
m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs);
} }
public string GetAnimName(UUID animId) public string GetAnimName(UUID animId)

View File

@ -92,6 +92,11 @@ namespace OpenSim.Region.Framework.Scenes
uint priority; uint priority;
// HACK
return GetPriorityByBestAvatarResponsiveness(client, entity);
switch (m_scene.UpdatePrioritizationScheme) switch (m_scene.UpdatePrioritizationScheme)
{ {
case UpdatePrioritizationSchemes.Time: case UpdatePrioritizationSchemes.Time:
@ -157,30 +162,31 @@ namespace OpenSim.Region.Framework.Scenes
private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
{ {
uint pqueue = ComputeDistancePriority(client,entity,false); uint pqueue = 2; // keep compiler happy
ScenePresence presence = m_scene.GetScenePresence(client.AgentId); ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
if (presence != null) if (presence != null)
{ {
if (!presence.IsChildAgent) // All avatars other than our own go into pqueue 1
if (entity is ScenePresence)
return 1;
if (entity is SceneObjectPart)
{ {
// All avatars other than our own go into pqueue 1 // Attachments are high priority,
if (entity is ScenePresence) if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 1; return 1;
if (entity is SceneObjectPart) pqueue = ComputeDistancePriority(client, entity, false);
{
// Attachments are high priority,
if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 1;
// Non physical prims are lower priority than physical prims // Non physical prims are lower priority than physical prims
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
if (physActor == null || !physActor.IsPhysical) if (physActor == null || !physActor.IsPhysical)
pqueue++; pqueue++;
}
} }
} }
else
pqueue = ComputeDistancePriority(client, entity, false);
return pqueue; return pqueue;
} }

View File

@ -1754,7 +1754,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </param> /// </param>
public void CompleteMovement(IClientAPI client, bool openChildAgents) public void CompleteMovement(IClientAPI client, bool openChildAgents)
{ {
// DateTime startTime = DateTime.Now; int ts = Util.EnvironmentTickCount();
m_log.InfoFormat( m_log.InfoFormat(
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
@ -1767,6 +1767,7 @@ namespace OpenSim.Region.Framework.Scenes
// Make sure it's not a login agent. We don't want to wait for updates during login // Make sure it's not a login agent. We don't want to wait for updates during login
if (!isNPC && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) if (!isNPC && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
{ {
// Let's wait until UpdateAgent (called by departing region) is done // Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client)) if (!WaitForUpdateAgent(client))
// The sending region never sent the UpdateAgent data, we have to refuse // The sending region never sent the UpdateAgent data, we have to refuse
@ -1786,6 +1787,9 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
} }
*/ */
m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (!MakeRootAgent(AbsolutePosition, flying)) if (!MakeRootAgent(AbsolutePosition, flying))
{ {
@ -1796,6 +1800,8 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
Vector3 look = Lookat; Vector3 look = Lookat;
if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01)) if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01))
{ {
@ -1806,6 +1812,17 @@ namespace OpenSim.Region.Framework.Scenes
look = new Vector3(0.99f, 0.042f, 0); look = new Vector3(0.99f, 0.042f, 0);
} }
if (!IsChildAgent)
{
InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (AssetType)46);
if (cof == null)
COF = UUID.Zero;
else
COF = cof.ID;
m_log.DebugFormat("[ScenePresence]: CompleteMovement COF for {0} is {1}", client.AgentId, COF);
}
// Tell the client that we're totally ready // Tell the client that we're totally ready
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
@ -1816,6 +1833,8 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); // m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!string.IsNullOrEmpty(m_callbackURI)) if (!string.IsNullOrEmpty(m_callbackURI))
{ {
// We cannot sleep here since this would hold up the inbound packet processing thread, as // We cannot sleep here since this would hold up the inbound packet processing thread, as
@ -1844,6 +1863,8 @@ namespace OpenSim.Region.Framework.Scenes
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); // client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
// } // }
m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
m_previusParcelHide = false; m_previusParcelHide = false;
m_previusParcelUUID = UUID.Zero; m_previusParcelUUID = UUID.Zero;
m_currentParcelHide = false; m_currentParcelHide = false;
@ -1856,15 +1877,12 @@ namespace OpenSim.Region.Framework.Scenes
if (!IsChildAgent) if (!IsChildAgent)
{ {
newhide = m_currentParcelHide;
m_currentParcelHide = false;
// take this region out of children Neighbours list
// possible should be done elsewhere
DropThisRootRegionFromNeighbours();
ValidateAndSendAppearanceAndAgentData(); ValidateAndSendAppearanceAndAgentData();
m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// attachments // attachments
if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0) if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
{ {
@ -1877,23 +1895,46 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
List<SceneObjectGroup> attachments = GetAttachments(); if (m_attachments.Count > 0)
if (attachments.Count > 0)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
List<uint> kk = new List<uint>();
// Resume scripts this possible should also be moved down after sending the avatar to viewer ? // Resume scripts this possible should also be moved down after sending the avatar to viewer ?
foreach (SceneObjectGroup sog in attachments) foreach (SceneObjectGroup sog in m_attachments)
{ {
sog.ScheduleGroupForFullUpdate(); foreach (SceneObjectPart part in sog.Parts)
kk.Add(part.LocalId);
sog.SendFullUpdateToClient(ControllingClient);
SendFullUpdateToClient(ControllingClient);
// sog.ScheduleGroupForFullUpdate();
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p == this)
return;
if (sog.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
p.ControllingClient.SendKillObject(kk);
sog.SendFullUpdateToClient(p.ControllingClient);
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
});
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts(); sog.ResumeScripts();
kk.Clear();
} }
} }
} }
m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// Create child agents in neighbouring regions // Create child agents in neighbouring regions
if (openChildAgents) if (openChildAgents)
{ {
@ -1903,10 +1944,14 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// send the rest of the world // send the rest of the world
if (m_teleportFlags > 0 && !isNPC) if (m_teleportFlags > 0 && !isNPC || m_currentParcelHide)
SendInitialDataToMe(); SendInitialDataToMe();
m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!IsChildAgent) if (!IsChildAgent)
{ {
// moved from makeroot missing in sendInitialDataToMe // moved from makeroot missing in sendInitialDataToMe
@ -1923,6 +1968,8 @@ namespace OpenSim.Region.Framework.Scenes
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null) if (friendsModule != null)
friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts));
} }
} }
} }
@ -1931,11 +1978,13 @@ namespace OpenSim.Region.Framework.Scenes
m_inTransit = false; m_inTransit = false;
} }
// if hide force a check // if hide force a check
if (!IsChildAgent && newhide) // if (!IsChildAgent && newhide)
{ // {
ParcelLoginCheck(m_currentParcelUUID); // ParcelLoginCheck(m_currentParcelUUID);
m_currentParcelHide = newhide; // m_currentParcelHide = newhide;
} // }
m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts));
} }
/// <summary> /// <summary>
@ -2776,34 +2825,15 @@ namespace OpenSim.Region.Framework.Scenes
if (satOnObject) if (satOnObject)
{ {
// SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0; m_requestedSitTargetID = 0;
part.RemoveSittingAvatar(UUID); part.RemoveSittingAvatar(UUID);
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
else if (PhysicsActor == null) SendAvatarDataToAllAgents();
AddToPhysicalScene(false); }
Animator.TrySetMovementAnimation("STAND"); Animator.TrySetMovementAnimation("STAND");
if (satOnObject)
{
ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X,AbsolutePosition.Y);
if (land != null)
{
UUID parcelID = land.LandData.GlobalID;
if (m_currentParcelUUID != parcelID)
currentParcelUUID = parcelID;
else
SendAvatarDataToAllAgents();
}
else
SendAvatarDataToAllAgents();
}
TriggerScenePresenceUpdated(); TriggerScenePresenceUpdated();
} }
@ -3078,11 +3108,14 @@ namespace OpenSim.Region.Framework.Scenes
ParentPart = part; ParentPart = part;
ParentID = part.LocalId; ParentID = part.LocalId;
SendAvatarDataToAllAgents();
if(status == 3) if(status == 3)
Animator.TrySetMovementAnimation("SIT_GROUND"); Animator.TrySetMovementAnimation("SIT_GROUND");
else else
Animator.TrySetMovementAnimation("SIT"); Animator.TrySetMovementAnimation("SIT");
SendAvatarDataToAllAgents();
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
} }
@ -3182,13 +3215,14 @@ namespace OpenSim.Region.Framework.Scenes
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
RemoveFromPhysicalScene(); RemoveFromPhysicalScene();
SendAvatarDataToAllAgents();
String sitAnimation = "SIT"; String sitAnimation = "SIT";
if (!String.IsNullOrEmpty(part.SitAnimation)) if (!String.IsNullOrEmpty(part.SitAnimation))
{ {
sitAnimation = part.SitAnimation; sitAnimation = part.SitAnimation;
} }
Animator.TrySetMovementAnimation(sitAnimation); Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents();
TriggerScenePresenceUpdated(); TriggerScenePresenceUpdated();
} }
} }
@ -3349,8 +3383,30 @@ namespace OpenSim.Region.Framework.Scenes
#region Update Client(s) #region Update Client(s)
public void SendUpdateToAgent(ScenePresence p)
{
IClientAPI remoteClient = p.ControllingClient;
if (remoteClient.IsActive)
{
//m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
m_scene.StatsReporter.AddAgentUpdates(1);
}
}
public void SendFullUpdateToClient(IClientAPI remoteClient)
{
if (remoteClient.IsActive)
{
//m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
m_scene.StatsReporter.AddAgentUpdates(1);
}
}
// this is diferente from SendTerseUpdateToClient // this is diferente from SendTerseUpdateToClient
// this sends bypassing ententies updates // this sends bypassing entities updates
public void SendAgentTerseUpdate(ISceneEntity p) public void SendAgentTerseUpdate(ISceneEntity p)
{ {
ControllingClient.SendAgentTerseUpdate(p); ControllingClient.SendAgentTerseUpdate(p);
@ -3377,7 +3433,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void SendTerseUpdateToAgentClient(ScenePresence p) public void SendTerseUpdateToAgent(ScenePresence p)
{ {
IClientAPI remoteClient = p.ControllingClient; IClientAPI remoteClient = p.ControllingClient;
@ -3396,6 +3452,18 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.StatsReporter.AddAgentUpdates(1); m_scene.StatsReporter.AddAgentUpdates(1);
} }
public void SendTerseUpdateToAgentNF(ScenePresence p)
{
IClientAPI remoteClient = p.ControllingClient;
if (remoteClient.IsActive)
{
//m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
m_scene.StatsReporter.AddAgentUpdates(1);
}
}
// vars to support reduced update frequency when velocity is unchanged // vars to support reduced update frequency when velocity is unchanged
private Vector3 lastVelocitySentToAllClients = Vector3.Zero; private Vector3 lastVelocitySentToAllClients = Vector3.Zero;
private Vector3 lastPositionSentToAllClients = Vector3.Zero; private Vector3 lastPositionSentToAllClients = Vector3.Zero;
@ -3437,7 +3505,7 @@ namespace OpenSim.Region.Framework.Scenes
// Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name); // Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name);
// m_scene.ForEachClient(SendTerseUpdateToClient); // m_scene.ForEachClient(SendTerseUpdateToClient);
m_scene.ForEachScenePresence(SendTerseUpdateToAgentClient); m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
} }
TriggerScenePresenceUpdated(); TriggerScenePresenceUpdated();
} }
@ -3478,8 +3546,8 @@ namespace OpenSim.Region.Framework.Scenes
landch.sendClientInitialLandInfo(ControllingClient); landch.sendClientInitialLandInfo(ControllingClient);
} }
} }
SendOtherAgentsAvatarDataToMe();
SendOtherAgentsAppearanceToMe(); SendOtherAgentsAvatarFullToMe();
EntityBase[] entities = Scene.Entities.GetEntities(); EntityBase[] entities = Scene.Entities.GetEntities();
foreach (EntityBase e in entities) foreach (EntityBase e in entities)
@ -3512,36 +3580,52 @@ namespace OpenSim.Region.Framework.Scenes
// If we aren't using a cached appearance, then clear out the baked textures // If we aren't using a cached appearance, then clear out the baked textures
if (!cachedappearance) if (!cachedappearance)
{ {
// Appearance.ResetAppearance();
// save what ????
// maybe needed so the tryretry repair works?
if (m_scene.AvatarFactory != null) if (m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(UUID); m_scene.AvatarFactory.QueueAppearanceSave(UUID);
} }
bool newhide = m_currentParcelHide;
m_currentParcelHide = false;
// This agent just became root. We are going to tell everyone about it. The process of
// getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it
// again here... this comes after the cached appearance check because the avatars
// appearance goes into the avatar update packet
SendAvatarDataToAllAgents(); SendAvatarDataToAllAgents();
// This invocation always shows up in the viewer logs as an error. Is it needed? if (newhide)
// send all information we have {
// possible not needed since viewer should ask about it ParcelLoginCheck(m_currentParcelUUID);
// least it all ask for baked m_currentParcelHide = true;
}
SendAppearanceToAgent(this); SendAppearanceToAgent(this);
// If we are using the the cached appearance then send it out to everyone // if (cachedappearance)
// send even grays // {
if (cachedappearance) SendAppearanceToAllOtherAgents();
// }
if(Animator!= null)
Animator.SendAnimPack();
}
/// <summary>
/// Send avatar full data appearance and animations for all other root agents to this agent, this agent
/// can be either a child or root
/// </summary>
public void SendOtherAgentsAvatarFullToMe()
{
int count = 0;
m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence)
{ {
// m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name); // only send information about other root agents
// If the avatars baked textures are all in the cache, then we have a if (scenePresence.UUID == UUID)
// complete appearance... send it out, if not, then we'll send it when return;
// the avatar finishes updating its appearance
SendAppearanceToAllOtherAgents(); scenePresence.SendAvatarDataToAgent(this);
} scenePresence.SendAppearanceToAgent(this);
scenePresence.SendAnimPackToAgent(this);
// for now attachments are sent with all SOG
count++;
});
m_scene.StatsReporter.AddAgentUpdates(count);
} }
/// <summary> /// <summary>
@ -3566,34 +3650,13 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
{ {
SendAvatarDataToAgent(scenePresence); SendAvatarDataToAgent(scenePresence);
count++; count++;
}); });
m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentUpdates(count);
} }
/// <summary>
/// Send avatar data for all other root agents to this agent, this agent
/// can be either a child or root
/// </summary>
public void SendOtherAgentsAvatarDataToMe()
{
int count = 0;
m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence)
{
// only send information about other root agents
if (scenePresence.UUID == UUID)
return;
scenePresence.SendAvatarDataToAgent(this);
count++;
});
m_scene.StatsReporter.AddAgentUpdates(count);
}
/// <summary> /// <summary>
/// Send avatar data to an agent. /// Send avatar data to an agent.
/// </summary> /// </summary>
@ -3604,7 +3667,11 @@ namespace OpenSim.Region.Framework.Scenes
if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
return; return;
avatar.ControllingClient.SendAvatarDataImmediate(this); avatar.ControllingClient.SendAvatarDataImmediate(this);
Animator.SendAnimPackToClient(avatar.ControllingClient); }
public void SendAvatarDataToAgentNF(ScenePresence avatar)
{
avatar.ControllingClient.SendAvatarDataImmediate(this);
} }
/// <summary> /// <summary>
@ -3638,28 +3705,6 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentUpdates(count);
} }
/// <summary>
/// Send appearance from all other root agents to this agent. this agent
/// can be either root or child
/// </summary>
public void SendOtherAgentsAppearanceToMe()
{
// m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} {1}", Name, UUID);
int count = 0;
m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence)
{
// only send information about other root agents
if (scenePresence.UUID == UUID)
return;
scenePresence.SendAppearanceToAgent(this);
count++;
});
m_scene.StatsReporter.AddAgentUpdates(count);
}
/// <summary> /// <summary>
/// Send appearance data to an agent. /// Send appearance data to an agent.
/// </summary> /// </summary>
@ -3674,6 +3719,30 @@ namespace OpenSim.Region.Framework.Scenes
UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
} }
public void SendAnimPackToAgent(ScenePresence p)
{
if (IsChildAgent || Animator == null)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
Animator.SendAnimPackToClient(p.ControllingClient);
}
public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
{
if (IsChildAgent)
return;
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
});
}
#endregion #endregion
#region Significant Movement Method #region Significant Movement Method
@ -4193,13 +4262,15 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch { } catch { }
Animator.ResetAnimations();
// FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object?
if (cAgent.Anims != null)
Animator.Animations.FromArray(cAgent.Anims);
if (cAgent.DefaultAnim != null) if (cAgent.DefaultAnim != null)
Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
if (cAgent.AnimState != null) if (cAgent.AnimState != null)
Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
if (cAgent.Anims != null)
Animator.Animations.FromArray(cAgent.Anims);
if (Scene.AttachmentsModule != null) if (Scene.AttachmentsModule != null)
Scene.AttachmentsModule.CopyAttachments(cAgent, this); Scene.AttachmentsModule.CopyAttachments(cAgent, this);
@ -4653,18 +4724,186 @@ namespace OpenSim.Region.Framework.Scenes
return validated; return validated;
} }
public void SendAttachmentsToAllAgents()
public void SendAttachmentsToClient(IClientAPI client)
{ {
lock (m_attachments) lock (m_attachments)
{ {
foreach (SceneObjectGroup gobj in m_attachments) foreach (SceneObjectGroup sog in m_attachments)
{ {
gobj.SendFullUpdateToClient(client); m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p != this && sog.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
sog.SendFullUpdateToClient(p.ControllingClient);
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
});
} }
} }
} }
// send attachments to a client without filters except for huds
// for now they are checked in several places down the line...
public void SendAttachmentsToAgentNF(ScenePresence p)
{
lock (m_attachments)
{
foreach (SceneObjectGroup sog in m_attachments)
{
if (p == this || !sog.HasPrivateAttachmentPoint)
sog.SendFullUpdateToClient(p.ControllingClient);
}
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
}
}
public void SendAttachmentsToAgentNFPK(ScenePresence p)
{
lock (m_attachments)
{
List<uint> pk = new List<uint>();
foreach (SceneObjectGroup sog in m_attachments)
{
foreach (SceneObjectPart part in sog.Parts)
pk.Add(part.LocalId);
}
p.ControllingClient.SendKillObject(pk);
foreach (SceneObjectGroup sog in m_attachments)
{
if (p == this || !sog.HasPrivateAttachmentPoint)
sog.SendFullUpdateToClient(p.ControllingClient);
}
SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path
}
}
public void SendAttachmentScheduleUpdate(SceneObjectGroup sog)
{
if (IsChildAgent)
return;
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p != this && sog.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
SceneObjectPart[] parts = sog.Parts;
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part.UpdateFlag == UpdateRequired.TERSE)
{
p.ControllingClient.SendEntityUpdate(part,
PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
| PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
part.UpdateFlag = 0;
}
else if (part.UpdateFlag == UpdateRequired.FULL)
{
p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
part.UpdateFlag = 0;
}
}
});
}
public void SendAttachmentScheduleUpdate(SceneObjectPart part)
{
if (IsChildAgent)
return;
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p != this && part.ParentGroup.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
if (part.UpdateFlag == UpdateRequired.TERSE)
{
p.ControllingClient.SendEntityUpdate(part,
PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
| PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
part.UpdateFlag = 0;
}
else if (part.UpdateFlag == UpdateRequired.FULL)
{
p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
part.UpdateFlag = 0;
}
});
}
public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag)
{
if (IsChildAgent)
return;
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p != this && sog.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
SceneObjectPart[] parts = sog.Parts;
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (UpdateFlag == UpdateRequired.TERSE)
{
p.ControllingClient.SendEntityUpdate(part,
PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
| PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
part.UpdateFlag = 0;
}
else if (UpdateFlag == UpdateRequired.FULL)
{
p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
part.UpdateFlag = 0;
}
}
});
}
public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag)
{
if (IsChildAgent)
return;
m_scene.ForEachScenePresence(delegate(ScenePresence p)
{
if (p != this && part.ParentGroup.HasPrivateAttachmentPoint)
return;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
return;
if (UpdateFlag == UpdateRequired.TERSE)
{
p.ControllingClient.SendEntityUpdate(part,
PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
| PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
part.UpdateFlag = 0;
}
else if (UpdateFlag == UpdateRequired.FULL)
{
p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
part.UpdateFlag = 0;
}
});
}
/// <summary> /// <summary>
/// Send a script event to this scene presence's attachments /// Send a script event to this scene presence's attachments
/// </summary> /// </summary>
@ -5436,12 +5675,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (p.IsChildAgent) if (p.IsChildAgent)
continue; continue;
m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname);
ControllingClient.SendAvatarDataImmediate(p); p.SendAvatarDataToAgentNF(this);
p.SendAppearanceToAgent(this); p.SendAppearanceToAgent(this);
p.SendAttachmentsToClient(ControllingClient);
if (p.Animator != null) if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient); p.Animator.SendAnimPackToClient(ControllingClient);
p.SendAttachmentsToAgentNFPK(this);
} }
} }
} }
@ -5476,7 +5715,7 @@ namespace OpenSim.Region.Framework.Scenes
private void ParcelLoginCheck(UUID currentParcelID) private void ParcelLoginCheck(UUID currentParcelID)
{ {
List<ScenePresence> killsToSendto = new List<ScenePresence>(); List<ScenePresence> killsToSendto = new List<ScenePresence>();
List<ScenePresence> killsToSendme = new List<ScenePresence>(); List<uint> killsToSendme = new List<uint>();
List<ScenePresence> viewsToSendto = new List<ScenePresence>(); List<ScenePresence> viewsToSendto = new List<ScenePresence>();
List<ScenePresence> viewsToSendme = new List<ScenePresence>(); List<ScenePresence> viewsToSendme = new List<ScenePresence>();
List<ScenePresence> allpresences = null; List<ScenePresence> allpresences = null;
@ -5492,8 +5731,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (p.GodLevel < 200) if (p.GodLevel < 200)
killsToSendto.Add(p); killsToSendto.Add(p);
if (GodLevel < 200 && p.ParcelHideThisAvatar) // if (GodLevel < 200 && p.ParcelHideThisAvatar)
killsToSendme.Add(p); // killsToSendme.Add(p.LocalId);
} }
else else
{ {
@ -5517,14 +5756,15 @@ namespace OpenSim.Region.Framework.Scenes
if (killsToSendme.Count > 0) if (killsToSendme.Count > 0)
{ {
foreach (ScenePresence p in killsToSendme) m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + killsToSendme.Count.ToString());
try
{ {
m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); ControllingClient.SendKillObject(killsToSendme);
try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
catch (NullReferenceException) { }
} }
} catch (NullReferenceException) { }
}
/*
if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc)
{ {
foreach (ScenePresence p in viewsToSendto) foreach (ScenePresence p in viewsToSendto)
@ -5552,81 +5792,46 @@ namespace OpenSim.Region.Framework.Scenes
p.Animator.SendAnimPackToClient(ControllingClient); p.Animator.SendAnimPackToClient(ControllingClient);
} }
} }
*/
} }
public void parcelRegionCross(bool abort)
public void parcelRegionCross()
{ {
if (!ParcelHideThisAvatar) if (!ParcelHideThisAvatar || GodLevel >= 200)
return; return;
List<ScenePresence> allpresences = null; List<ScenePresence> allpresences = null;
allpresences = m_scene.GetScenePresences(); allpresences = m_scene.GetScenePresences();
if (abort) List<uint> killsToSendme = new List<uint>();
foreach (ScenePresence p in allpresences)
{ {
List<ScenePresence> viewsToSendme = new List<ScenePresence>(); if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
continue;
foreach (ScenePresence p in allpresences) if (p.currentParcelUUID == m_currentParcelUUID)
{ {
if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) killsToSendme.Add(p.LocalId);
continue;
if (p.currentParcelUUID == m_currentParcelUUID)
{
viewsToSendme.Add(p);
}
}
if (viewsToSendme.Count > 0)
{
foreach (ScenePresence p in viewsToSendme)
{
if (p.IsChildAgent)
continue;
// m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname);
ControllingClient.SendAvatarDataImmediate(p);
p.SendAppearanceToAgent(this);
p.SendAttachmentsToClient(ControllingClient);
if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient);
}
} }
} }
else
if (killsToSendme.Count > 0)
{ {
if (GodLevel >= 200) try
return;
List<ScenePresence> killsToSendme = new List<ScenePresence>();
foreach (ScenePresence p in allpresences)
{ {
if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) ControllingClient.SendKillObject(killsToSendme);
continue;
if (p.currentParcelUUID == m_currentParcelUUID)
{
killsToSendme.Add(p);
}
}
if (killsToSendme.Count > 0)
{
foreach (ScenePresence p in killsToSendme)
{
m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname);
try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
catch (NullReferenceException) { }
}
} }
catch (NullReferenceException) { }
} }
} }
private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID, private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID,
bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check) bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check)
{ {
List<ScenePresence> killsToSendto = new List<ScenePresence>(); List<ScenePresence> killsToSendto = new List<ScenePresence>();
List<ScenePresence> killsToSendme = new List<ScenePresence>(); List<uint> killsToSendme = new List<uint>();
List<ScenePresence> viewsToSendto = new List<ScenePresence>(); List<ScenePresence> viewsToSendto = new List<ScenePresence>();
List<ScenePresence> viewsToSendme = new List<ScenePresence>(); List<ScenePresence> viewsToSendme = new List<ScenePresence>();
List<ScenePresence> allpresences = null; List<ScenePresence> allpresences = null;
@ -5697,7 +5902,7 @@ namespace OpenSim.Region.Framework.Scenes
if(p.GodLevel < 200) if(p.GodLevel < 200)
killsToSendto.Add(p); // they dont see me killsToSendto.Add(p); // they dont see me
if(GodLevel < 200) if(GodLevel < 200)
killsToSendme.Add(p); // i dont see them killsToSendme.Add(p.LocalId); // i dont see them
} }
// only those on new parcel need see // only those on new parcel need see
if (currentParcelID == p.currentParcelUUID) if (currentParcelID == p.currentParcelUUID)
@ -5746,7 +5951,7 @@ namespace OpenSim.Region.Framework.Scenes
// only those old parcel need receive kills // only those old parcel need receive kills
if (previusParcelID == p.currentParcelUUID && GodLevel < 200) if (previusParcelID == p.currentParcelUUID && GodLevel < 200)
{ {
killsToSendme.Add(p); // i dont see them killsToSendme.Add(p.LocalId); // i dont see them
} }
else else
{ {
@ -5771,26 +5976,26 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
if (killsToSendme.Count > 0 ) if (killsToSendme.Count > 0)
{ {
foreach (ScenePresence p in killsToSendme) m_log.Debug("[AVATAR]: killtoMe: " + Lastname + " " + killsToSendme.Count.ToString());
try
{ {
m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); ControllingClient.SendKillObject(killsToSendme);
try {ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
catch (NullReferenceException) { }
} }
catch (NullReferenceException) { }
} }
if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc)
{ {
foreach (ScenePresence p in viewsToSendto) foreach (ScenePresence p in viewsToSendto)
{ {
p.ControllingClient.SendAvatarDataImmediate(this); SendAvatarDataToAgentNF(p);
// m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname);
SendAppearanceToAgent(p); SendAppearanceToAgent(p);
SendAttachmentsToClient(p.ControllingClient);
if (Animator != null) if (Animator != null)
Animator.SendAnimPackToClient(p.ControllingClient); Animator.SendAnimPackToClient(p.ControllingClient);
SendAttachmentsToAgentNFPK(p);
} }
} }
@ -5801,11 +6006,12 @@ namespace OpenSim.Region.Framework.Scenes
if (p.IsChildAgent) if (p.IsChildAgent)
continue; continue;
// m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); // m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname);
ControllingClient.SendAvatarDataImmediate(p);
p.SendAvatarDataToAgentNF(this);
p.SendAppearanceToAgent(this); p.SendAppearanceToAgent(this);
p.SendAttachmentsToClient(ControllingClient);
if (p.Animator != null) if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient); p.Animator.SendAnimPackToClient(ControllingClient);
p.SendAttachmentsToAgentNFPK(this);
} }
} }
} }

View File

@ -58,6 +58,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public ISceneAgent SceneAgent { get; set; } public ISceneAgent SceneAgent { get; set; }
public int PingTimeMS { get { return 0; } }
private string m_username; private string m_username;
private string m_nick; private string m_nick;

View File

@ -81,6 +81,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
get { return m_scene; } get { return m_scene; }
} }
public int PingTimeMS { get { return 0; } }
public UUID OwnerID public UUID OwnerID
{ {
get { return m_ownerID; } get { return m_ownerID; }

View File

@ -379,6 +379,8 @@ namespace OpenSim.Tests.Common.Mock
get { return FirstName + " " + LastName; } get { return FirstName + " " + LastName; }
} }
public int PingTimeMS { get { return 0; } }
public bool IsActive public bool IsActive
{ {
get { return true; } get { return true; }