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
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
/* then lets remove
if (Appearance.Texture != null)
{
byte[] rawtextures = Appearance.Texture.GetBytes();
@ -459,7 +461,7 @@ namespace OpenSim.Framework
args["attachments"] = attachs;
}
// End of code to remove
*/
if ((Controllers != null) && (Controllers.Length > 0))
{
OSDArray controls = new OSDArray(Controllers.Length);
@ -647,6 +649,18 @@ namespace OpenSim.Framework
// AgentTextures[i++] = o.AsUUID();
//}
// packed_appearence should contain all appearance information
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
{
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
}
else
{
// if missing try the old pack method
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method");
Appearance = new AvatarAppearance();
// The code to unpack textures, visuals, wearables and attachments
@ -655,7 +669,7 @@ namespace OpenSim.Framework
if (args["texture_entry"] != null)
{
byte[] rawtextures = args["texture_entry"].AsBinary();
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
Appearance.SetTextureEntries(textures);
}
@ -673,7 +687,7 @@ namespace OpenSim.Framework
for (int i = 0; i < count / 2; i++)
{
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
Appearance.SetWearable(i,awear);
Appearance.SetWearable(i, awear);
}
}
@ -687,18 +701,19 @@ namespace OpenSim.Framework
// 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);
// 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)
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
else
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
*/
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{
OSDArray controls = (OSDArray)(args["controllers"]);

View File

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

View File

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

View File

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

View File

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

View File

@ -163,6 +163,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_maxRTO = 60000;
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>
/// This is the percentage of the udp texture queue to add to the task queue since
/// 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
TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
m_pingMS = (int)(3.0 * server.TickCountResolution); // so filter doesnt start at 0;
}
/// <summary>

View File

@ -293,6 +293,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Flag to signal when clients should send pings</summary>
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>>();
/// <summary>
@ -369,16 +384,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Measure the resolution of Environment.TickCount
TickCountResolution = 0f;
for (int i = 0; i < 5; i++)
for (int i = 0; i < 10; i++)
{
int start = Environment.TickCount;
int now = start;
while (now == start)
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);
m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
#endregion Environment.TickCount Measurement
@ -386,6 +401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int sceneThrottleBps = 0;
bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
{
@ -435,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
Random rnd = new Random(Util.EnvironmentTickCount());
m_animationSequenceNumber = rnd.Next(11474826);
if (usePools)
EnablePools();
}
@ -1128,6 +1148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
pc.PingID.OldestUnacked = 0;
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
}
public void CompletePing(LLUDPClient udpClient, byte pingID)
@ -1577,7 +1598,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
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;
}

View File

@ -120,10 +120,16 @@ namespace OpenSim.Region.CoreModules.Framework
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);
m_log.ErrorFormat("[CreateCaps]: banCheck {0} ", Util.EnvironmentTickCountSubtract(ts));
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
return;
*/
Caps caps;
String capsObjectPath = GetCapsPath(agentId);
@ -133,18 +139,26 @@ namespace OpenSim.Region.CoreModules.Framework
{
Caps oldCaps = m_capsObjects[circuitCode];
//m_log.WarnFormat(
// "[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);
// if (capsObjectPath == oldCaps.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,
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
// m_log.ErrorFormat("[CreateCaps]: new caps {0} ", Util.EnvironmentTickCountSubtract(ts));
m_capsObjects[circuitCode] = caps;
}
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
// m_log.ErrorFormat("[CreateCaps]: end {0} ", Util.EnvironmentTickCountSubtract(ts));
}
public void RemoveCaps(UUID agentId, uint circuitCode)

View File

@ -430,7 +430,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// 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;
// 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];
}
float newPosZ = posZLimit + localAVHeight;
if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
posZLimit += localHalfAVHeight + 0.1f;
if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
{
position.Z = newPosZ;
position.Z = posZLimit;
}
if (sp.Flying)
@ -720,7 +724,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
agentCircuit.startpos = position;
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)
{
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
@ -971,7 +980,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// 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.
KillEntity(sp.Scene, sp.LocalId);
@ -1138,7 +1148,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.CloseChildAgents(newRegionX, newRegionY);
// 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.
KillEntity(sp.Scene, sp.LocalId);
@ -1253,7 +1264,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
{
if (sp.Scene.AttachmentsModule != null)
sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout);
}
protected void KillEntity(Scene scene, uint localID)
@ -1381,10 +1392,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings
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;
reason = String.Empty;
newpos = pos;
// 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);
string reason;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
{
if (r == null)
@ -1525,11 +1541,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint y;
Vector3 newpos;
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)
{
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;
}
@ -1656,10 +1676,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
{
int ts = Util.EnvironmentTickCount();
try
{
AgentData cAgent = new AgentData();
agent.CopyTo(cAgent);
// agent.Appearance.WearableCacheItems = null;
cAgent.Position = pos + agent.Velocity;
if (isFlying)
cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@ -1686,6 +1711,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return false;
}
m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts));
}
catch (Exception e)
{
@ -1703,6 +1730,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
bool isFlying, string version)
{
agent.ControllingClient.RequestClientInfo();
string agentcaps;
@ -1714,6 +1742,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// No turning back
agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
@ -1737,12 +1768,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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!
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);
// this may need the attachments
agent.parcelRegionCross();
AgentHasMovedAway(agent, true);
agent.MakeChildAgent();
// 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.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.
uint neighbourx;
uint neighboury;
@ -1777,7 +1811,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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
@ -1817,7 +1851,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Enable Child Agent
/// <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.
/// </summary>
/// <param name="sp"></param>
@ -1833,8 +1867,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.startpos = new Vector3(128, 128, 70);
agent.child = true;
//agent.Appearance = sp.Appearance;
agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
@ -1866,6 +1900,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Id0 = currentAgentCircuit.Id0;
}
Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
IPEndPoint external = region.ExternalEndPoint;
if (external != null)
{
@ -1884,6 +1920,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <summary>
/// This informs all neighbouring regions about agent "avatar".
/// and as important informs the avatar about then
/// </summary>
/// <param name="sp"></param>
public void EnableChildAgents(ScenePresence sp)
@ -1900,58 +1937,46 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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
/// 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;
LinkedList<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;
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))
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>();
ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
foreach (GridRegion neighbour in neighbours)
{
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
{
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
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 = sp.Appearance;
agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
if (currentAgentCircuit != null)
{
agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@ -1962,19 +1987,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Id0 = currentAgentCircuit.Id0;
}
if (newRegions.Contains(neighbour.RegionHandle))
if (previousRegionNeighbourHandles.Contains(handler))
{
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath);
seeds.Add(neighbour.RegionHandle, agent.CapsPath);
previousRegionNeighbourHandles.Remove(handler);
agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, handler);
}
else
{
agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle);
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
@ -1987,34 +2020,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
}
sp.KnownRegions = seeds;
//avatar.Scene.DumpChildrenSeeds(avatar.UUID);
//avatar.DumpKnownRegions();
bool newAgent = false;
int count = 0;
foreach (GridRegion neighbour in neighbours)
Util.FireAndForget(delegate
{
//m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName);
// Don't do it if there's already an agent in that region
if (newRegions.Contains(neighbour.RegionHandle))
newAgent = true;
else
newAgent = false;
// continue;
Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
int count = 0;
bool newagent;
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
foreach (GridRegion neighbour in neighbours)
{
try
{
// Let's put this back at sync, so that it doesn't clog
// the network, especially for regions in the same physical server.
// 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);
newagent = newneighbours.Contains(neighbour.RegionHandle);
InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newagent);
}
catch (ArgumentOutOfRangeException)
@ -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.
// throw e;
}
}
count++;
}
});
}
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,
IPEndPoint endPoint, bool newAgent)
{
// Let's wait just a little to give time to originating regions to catch up with closing child agents
// after a cross here
Thread.Sleep(500);
Scene scene = sp.Scene;
if (!newAgent)
return;
m_log.DebugFormat(
"[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)
{
// give time for createAgent to finish, since it is async and does grid services access
Thread.Sleep(500);
if (m_eqModule != null)
{
#region IP Translation for NAT

View File

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

View File

@ -92,6 +92,11 @@ namespace OpenSim.Region.Framework.Scenes
uint priority;
// HACK
return GetPriorityByBestAvatarResponsiveness(client, entity);
switch (m_scene.UpdatePrioritizationScheme)
{
case UpdatePrioritizationSchemes.Time:
@ -157,12 +162,10 @@ namespace OpenSim.Region.Framework.Scenes
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);
if (presence != null)
{
if (!presence.IsChildAgent)
{
// All avatars other than our own go into pqueue 1
if (entity is ScenePresence)
@ -174,13 +177,16 @@ namespace OpenSim.Region.Framework.Scenes
if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 1;
pqueue = ComputeDistancePriority(client, entity, false);
// Non physical prims are lower priority than physical prims
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
if (physActor == null || !physActor.IsPhysical)
pqueue++;
}
}
}
else
pqueue = ComputeDistancePriority(client, entity, false);
return pqueue;
}

View File

@ -1754,7 +1754,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </param>
public void CompleteMovement(IClientAPI client, bool openChildAgents)
{
// DateTime startTime = DateTime.Now;
int ts = Util.EnvironmentTickCount();
m_log.InfoFormat(
"[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
if (!isNPC && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
{
// Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client))
// The sending region never sent the UpdateAgent data, we have to refuse
@ -1786,6 +1787,9 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos;
}
*/
m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (!MakeRootAgent(AbsolutePosition, flying))
{
@ -1796,6 +1800,8 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
Vector3 look = Lookat;
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);
}
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
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("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!string.IsNullOrEmpty(m_callbackURI))
{
// 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);
// }
m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
m_previusParcelHide = false;
m_previusParcelUUID = UUID.Zero;
m_currentParcelHide = false;
@ -1856,15 +1877,12 @@ namespace OpenSim.Region.Framework.Scenes
if (!IsChildAgent)
{
newhide = m_currentParcelHide;
m_currentParcelHide = false;
// take this region out of children Neighbours list
// possible should be done elsewhere
DropThisRootRegionFromNeighbours();
ValidateAndSendAppearanceAndAgentData();
m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// attachments
if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
{
@ -1877,23 +1895,46 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
List<SceneObjectGroup> attachments = GetAttachments();
if (attachments.Count > 0)
if (m_attachments.Count > 0)
{
m_log.DebugFormat(
"[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 ?
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.ResumeScripts();
kk.Clear();
}
}
}
m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// Create child agents in neighbouring regions
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
if (m_teleportFlags > 0 && !isNPC)
if (m_teleportFlags > 0 && !isNPC || m_currentParcelHide)
SendInitialDataToMe();
m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!IsChildAgent)
{
// moved from makeroot missing in sendInitialDataToMe
@ -1923,6 +1968,8 @@ namespace OpenSim.Region.Framework.Scenes
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null)
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;
}
// if hide force a check
if (!IsChildAgent && newhide)
{
ParcelLoginCheck(m_currentParcelUUID);
m_currentParcelHide = newhide;
}
// if (!IsChildAgent && newhide)
// {
// ParcelLoginCheck(m_currentParcelUUID);
// m_currentParcelHide = newhide;
// }
m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
/// <summary>
@ -2776,34 +2825,15 @@ namespace OpenSim.Region.Framework.Scenes
if (satOnObject)
{
// SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0;
part.RemoveSittingAvatar(UUID);
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
else if (PhysicsActor == null)
AddToPhysicalScene(false);
SendAvatarDataToAllAgents();
}
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();
}
@ -3078,11 +3108,14 @@ namespace OpenSim.Region.Framework.Scenes
ParentPart = part;
ParentID = part.LocalId;
SendAvatarDataToAllAgents();
if(status == 3)
Animator.TrySetMovementAnimation("SIT_GROUND");
else
Animator.TrySetMovementAnimation("SIT");
SendAvatarDataToAllAgents();
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
@ -3182,13 +3215,14 @@ namespace OpenSim.Region.Framework.Scenes
Velocity = Vector3.Zero;
RemoveFromPhysicalScene();
SendAvatarDataToAllAgents();
String sitAnimation = "SIT";
if (!String.IsNullOrEmpty(part.SitAnimation))
{
sitAnimation = part.SitAnimation;
}
Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents();
TriggerScenePresenceUpdated();
}
}
@ -3349,8 +3383,30 @@ namespace OpenSim.Region.Framework.Scenes
#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 sends bypassing ententies updates
// this sends bypassing entities updates
public void SendAgentTerseUpdate(ISceneEntity 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;
@ -3396,6 +3452,18 @@ namespace OpenSim.Region.Framework.Scenes
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
private Vector3 lastVelocitySentToAllClients = 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);
// m_scene.ForEachClient(SendTerseUpdateToClient);
m_scene.ForEachScenePresence(SendTerseUpdateToAgentClient);
m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
}
TriggerScenePresenceUpdated();
}
@ -3478,8 +3546,8 @@ namespace OpenSim.Region.Framework.Scenes
landch.sendClientInitialLandInfo(ControllingClient);
}
}
SendOtherAgentsAvatarDataToMe();
SendOtherAgentsAppearanceToMe();
SendOtherAgentsAvatarFullToMe();
EntityBase[] entities = Scene.Entities.GetEntities();
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 (!cachedappearance)
{
// Appearance.ResetAppearance();
// save what ????
// maybe needed so the tryretry repair works?
if (m_scene.AvatarFactory != null)
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();
// This invocation always shows up in the viewer logs as an error. Is it needed?
// send all information we have
// possible not needed since viewer should ask about it
// least it all ask for baked
if (newhide)
{
ParcelLoginCheck(m_currentParcelUUID);
m_currentParcelHide = true;
}
SendAppearanceToAgent(this);
// If we are using the the cached appearance then send it out to everyone
// send even grays
if (cachedappearance)
{
// m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name);
// If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when
// the avatar finishes updating its appearance
// 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)
{
// only send information about other root agents
if (scenePresence.UUID == UUID)
return;
scenePresence.SendAvatarDataToAgent(this);
scenePresence.SendAppearanceToAgent(this);
scenePresence.SendAnimPackToAgent(this);
// for now attachments are sent with all SOG
count++;
});
m_scene.StatsReporter.AddAgentUpdates(count);
}
/// <summary>
@ -3573,27 +3657,6 @@ namespace OpenSim.Region.Framework.Scenes
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>
/// Send avatar data to an agent.
/// </summary>
@ -3604,7 +3667,11 @@ namespace OpenSim.Region.Framework.Scenes
if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
return;
avatar.ControllingClient.SendAvatarDataImmediate(this);
Animator.SendAnimPackToClient(avatar.ControllingClient);
}
public void SendAvatarDataToAgentNF(ScenePresence avatar)
{
avatar.ControllingClient.SendAvatarDataImmediate(this);
}
/// <summary>
@ -3638,28 +3705,6 @@ namespace OpenSim.Region.Framework.Scenes
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>
/// Send appearance data to an agent.
/// </summary>
@ -3674,6 +3719,30 @@ namespace OpenSim.Region.Framework.Scenes
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
#region Significant Movement Method
@ -4193,13 +4262,15 @@ namespace OpenSim.Region.Framework.Scenes
}
catch { }
Animator.ResetAnimations();
// 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)
Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
if (cAgent.AnimState != null)
Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
if (cAgent.Anims != null)
Animator.Animations.FromArray(cAgent.Anims);
if (Scene.AttachmentsModule != null)
Scene.AttachmentsModule.CopyAttachments(cAgent, this);
@ -4653,18 +4724,186 @@ namespace OpenSim.Region.Framework.Scenes
return validated;
}
public void SendAttachmentsToClient(IClientAPI client)
public void SendAttachmentsToAllAgents()
{
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>
/// Send a script event to this scene presence's attachments
/// </summary>
@ -5436,12 +5675,12 @@ namespace OpenSim.Region.Framework.Scenes
{
if (p.IsChildAgent)
continue;
m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname);
ControllingClient.SendAvatarDataImmediate(p);
p.SendAvatarDataToAgentNF(this);
p.SendAppearanceToAgent(this);
p.SendAttachmentsToClient(ControllingClient);
if (p.Animator != null)
p.Animator.SendAnimPackToClient(ControllingClient);
p.SendAttachmentsToAgentNFPK(this);
}
}
}
@ -5476,7 +5715,7 @@ namespace OpenSim.Region.Framework.Scenes
private void ParcelLoginCheck(UUID currentParcelID)
{
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> viewsToSendme = new List<ScenePresence>();
List<ScenePresence> allpresences = null;
@ -5492,8 +5731,8 @@ namespace OpenSim.Region.Framework.Scenes
{
if (p.GodLevel < 200)
killsToSendto.Add(p);
if (GodLevel < 200 && p.ParcelHideThisAvatar)
killsToSendme.Add(p);
// if (GodLevel < 200 && p.ParcelHideThisAvatar)
// killsToSendme.Add(p.LocalId);
}
else
{
@ -5517,14 +5756,15 @@ namespace OpenSim.Region.Framework.Scenes
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);
try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
ControllingClient.SendKillObject(killsToSendme);
}
catch (NullReferenceException) { }
}
}
}
/*
if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc)
{
foreach (ScenePresence p in viewsToSendto)
@ -5552,19 +5792,19 @@ namespace OpenSim.Region.Framework.Scenes
p.Animator.SendAnimPackToClient(ControllingClient);
}
}
*/
}
public void parcelRegionCross(bool abort)
public void parcelRegionCross()
{
if (!ParcelHideThisAvatar)
if (!ParcelHideThisAvatar || GodLevel >= 200)
return;
List<ScenePresence> allpresences = null;
allpresences = m_scene.GetScenePresences();
if (abort)
{
List<ScenePresence> viewsToSendme = new List<ScenePresence>();
List<uint> killsToSendme = new List<uint>();
foreach (ScenePresence p in allpresences)
{
@ -5573,60 +5813,25 @@ namespace OpenSim.Region.Framework.Scenes
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 (GodLevel >= 200)
return;
List<ScenePresence> killsToSendme = new List<ScenePresence>();
foreach (ScenePresence p in allpresences)
{
if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
continue;
if (p.currentParcelUUID == m_currentParcelUUID)
{
killsToSendme.Add(p);
killsToSendme.Add(p.LocalId);
}
}
if (killsToSendme.Count > 0)
{
foreach (ScenePresence p in killsToSendme)
try
{
m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname);
try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
ControllingClient.SendKillObject(killsToSendme);
}
catch (NullReferenceException) { }
}
}
}
}
private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID,
bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check)
{
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> viewsToSendme = new List<ScenePresence>();
List<ScenePresence> allpresences = null;
@ -5697,7 +5902,7 @@ namespace OpenSim.Region.Framework.Scenes
if(p.GodLevel < 200)
killsToSendto.Add(p); // they dont see me
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
if (currentParcelID == p.currentParcelUUID)
@ -5746,7 +5951,7 @@ namespace OpenSim.Region.Framework.Scenes
// only those old parcel need receive kills
if (previusParcelID == p.currentParcelUUID && GodLevel < 200)
{
killsToSendme.Add(p); // i dont see them
killsToSendme.Add(p.LocalId); // i dont see them
}
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);
try {ControllingClient.SendKillObject(new List<uint> { p.LocalId }); }
catch (NullReferenceException) { }
ControllingClient.SendKillObject(killsToSendme);
}
catch (NullReferenceException) { }
}
if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc)
{
foreach (ScenePresence p in viewsToSendto)
{
p.ControllingClient.SendAvatarDataImmediate(this);
// m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname);
SendAvatarDataToAgentNF(p);
SendAppearanceToAgent(p);
SendAttachmentsToClient(p.ControllingClient);
if (Animator != null)
Animator.SendAnimPackToClient(p.ControllingClient);
SendAttachmentsToAgentNFPK(p);
}
}
@ -5801,11 +6006,12 @@ namespace OpenSim.Region.Framework.Scenes
if (p.IsChildAgent)
continue;
// m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname);
ControllingClient.SendAvatarDataImmediate(p);
p.SendAvatarDataToAgentNF(this);
p.SendAppearanceToAgent(this);
p.SendAttachmentsToClient(ControllingClient);
if (p.Animator != null)
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 int PingTimeMS { get { return 0; } }
private string m_username;
private string m_nick;

View File

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

View File

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