add more test code to make usage od compressed updates etc. Should be disable, but well many things can go wrong.

0.9.1.0-post-fixes
UbitUmarov 2019-03-23 02:18:32 +00:00
parent db191cd4e2
commit d0052c8174
12 changed files with 529 additions and 345 deletions

View File

@ -602,16 +602,26 @@ namespace OpenSim.Framework
{ {
// we are on the new one // we are on the new one
if (m_flags.HasFlag(PrimUpdateFlags.CancelKill)) if (m_flags.HasFlag(PrimUpdateFlags.CancelKill))
m_flags = PrimUpdateFlags.FullUpdatewithAnim; {
if (m_flags.HasFlag(PrimUpdateFlags.UpdateProbe))
m_flags = PrimUpdateFlags.UpdateProbe;
else
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
}
} }
public virtual void Update(EntityUpdate oldupdate) public virtual void Update(EntityUpdate oldupdate)
{ {
// we are on the new one // we are on the new one
PrimUpdateFlags updateFlags = oldupdate.Flags; PrimUpdateFlags updateFlags = oldupdate.Flags;
if (updateFlags.HasFlag(PrimUpdateFlags.UpdateProbe))
updateFlags &= ~PrimUpdateFlags.UpdateProbe;
if (m_flags.HasFlag(PrimUpdateFlags.CancelKill)) if (m_flags.HasFlag(PrimUpdateFlags.CancelKill))
{ {
m_flags = PrimUpdateFlags.FullUpdatewithAnim; if(m_flags.HasFlag(PrimUpdateFlags.UpdateProbe))
m_flags = PrimUpdateFlags.UpdateProbe;
else
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
} }
else else
m_flags |= updateFlags; m_flags |= updateFlags;
@ -679,6 +689,7 @@ namespace OpenSim.Framework
FullUpdatewithAnim = FullUpdate | Animations, FullUpdatewithAnim = FullUpdate | Animations,
UpdateProbe = 0x10000000, // 1 << 28
SendInTransit = 0x20000000, // 1 << 29 SendInTransit = 0x20000000, // 1 << 29
CancelKill = 0x40000000, // 1 << 30 CancelKill = 0x40000000, // 1 << 30
Kill = 0x80000000 // 1 << 31 Kill = 0x80000000 // 1 << 31
@ -805,7 +816,7 @@ namespace OpenSim.Framework
event TeleportCancel OnTeleportCancel; event TeleportCancel OnTeleportCancel;
event DeRezObject OnDeRezObject; event DeRezObject OnDeRezObject;
event RezRestoreToWorld OnRezRestoreToWorld; event RezRestoreToWorld OnRezRestoreToWorld;
event Action<IClientAPI> OnRegionHandShakeReply; event Action<IClientAPI, uint> OnRegionHandShakeReply;
event GenericCall1 OnRequestWearables; event GenericCall1 OnRequestWearables;
event Action<IClientAPI, bool> OnCompleteMovementToRegion; event Action<IClientAPI, bool> OnCompleteMovementToRegion;

View File

@ -80,7 +80,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event Action<IClientAPI> OnRegionHandShakeReply; public event Action<IClientAPI, uint> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
@ -392,6 +392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected IAssetService m_assetService; protected IAssetService m_assetService;
protected bool m_supportViewerCache = false;
#endregion Class Members #endregion Class Members
#region Properties #region Properties
@ -552,6 +553,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString()); string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString());
m_asyncPacketProcess = new JobEngine(name, name, 10000); m_asyncPacketProcess = new JobEngine(name, name, 10000);
IsActive = true; IsActive = true;
m_supportViewerCache = m_udpServer.SupportViewerObjectsCache;
} }
#region Client Methods #region Client Methods
@ -4777,6 +4780,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
13 // ID (high frequency) 13 // ID (high frequency)
}; };
static private readonly byte[] ObjectUpdateCachedHeader = new byte[] {
Helpers.MSG_RELIABLE,
0, 0, 0, 0, // sequence number
0, // extra
14 // ID (high frequency)
};
private void ProcessEntityUpdates(int maxUpdatesBytes) private void ProcessEntityUpdates(int maxUpdatesBytes)
{ {
if (!IsActive) if (!IsActive)
@ -4786,8 +4796,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (mysp == null) if (mysp == null)
return; return;
List<EntityUpdate> objectUpdates = null; List<EntityUpdate> objectUpdates = null;
//List<EntityUpdate> compressedUpdates = null; List<EntityUpdate> objectUpdateProbes = null;
List<EntityUpdate> compressedUpdates = null;
List<EntityUpdate> terseUpdates = null; List<EntityUpdate> terseUpdates = null;
List<SceneObjectPart> ObjectAnimationUpdates = null; List<SceneObjectPart> ObjectAnimationUpdates = null;
@ -4799,6 +4811,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
EntityUpdate update; EntityUpdate update;
bool viewerCache = m_supportViewerCache && (m_viewerHandShakeFlags & 1) != 0 && mysp.IsChildAgent; // only on child agents
bool doCulling = m_scene.ObjectsCullingByDistance; bool doCulling = m_scene.ObjectsCullingByDistance;
float cullingrange = 64.0f; float cullingrange = 64.0f;
Vector3 mypos = Vector3.Zero; Vector3 mypos = Vector3.Zero;
@ -4807,7 +4820,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bool orderedDequeue = false; // temporary off bool orderedDequeue = false; // temporary off
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
bool useCompressUpdate = false;
if (doCulling) if (doCulling)
{ {
@ -4834,15 +4847,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; PrimUpdateFlags updateFlags = update.Flags;
if(updateFlags.HasFlag(PrimUpdateFlags.Kill)) if (updateFlags.HasFlag(PrimUpdateFlags.Kill))
{ {
m_killRecord.Add(update.Entity.LocalId); m_killRecord.Add(update.Entity.LocalId);
maxUpdatesBytes -= 30; maxUpdatesBytes -= 30;
continue; continue;
} }
useCompressUpdate = false;
if (update.Entity is SceneObjectPart) if (update.Entity is SceneObjectPart)
{ {
SceneObjectPart part = (SceneObjectPart)update.Entity; SceneObjectPart part = (SceneObjectPart)update.Entity;
@ -4928,10 +4943,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (dpos > maxview * maxview) if (dpos > maxview * maxview)
continue; continue;
GroupsNeedFullUpdate.Add(grp); if (!viewerCache || !updateFlags.HasFlag(PrimUpdateFlags.UpdateProbe))
continue; {
GroupsNeedFullUpdate.Add(grp);
continue;
}
} }
} }
if (updateFlags.HasFlag(PrimUpdateFlags.UpdateProbe))
{
if (objectUpdateProbes == null)
{
objectUpdateProbes = new List<EntityUpdate>();
maxUpdatesBytes -= 18;
}
objectUpdateProbes.Add(update);
maxUpdatesBytes -= 12;
continue;
}
if (m_SupportObjectAnimations && updateFlags.HasFlag(PrimUpdateFlags.Animations))
{
if (part.Animations != null)
{
if (ObjectAnimationUpdates == null)
ObjectAnimationUpdates = new List<SceneObjectPart>();
ObjectAnimationUpdates.Add(part);
maxUpdatesBytes -= 20 * part.Animations.Count + 24;
}
}
if(viewerCache)
useCompressUpdate = grp.IsViewerCachable;
} }
else if (update.Entity is ScenePresence) else if (update.Entity is ScenePresence)
{ {
@ -4951,27 +4994,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region UpdateFlags to packet type conversion #region UpdateFlags to packet type conversion
// bool canUseCompressed = true;
if (update.Entity is SceneObjectPart)
{
if (m_SupportObjectAnimations && updateFlags.HasFlag(PrimUpdateFlags.Animations))
{
SceneObjectPart sop = (SceneObjectPart)update.Entity;
if ( sop.Animations != null)
{
if(ObjectAnimationUpdates == null)
ObjectAnimationUpdates = new List<SceneObjectPart>();
ObjectAnimationUpdates.Add(sop);
maxUpdatesBytes -= 20 * sop.Animations.Count + 24;
}
}
}
else
{
// canUseCompressed = false;
}
updateFlags &= PrimUpdateFlags.FullUpdate; // clear other control bits already handled updateFlags &= PrimUpdateFlags.FullUpdate; // clear other control bits already handled
if(updateFlags == PrimUpdateFlags.None) if(updateFlags == PrimUpdateFlags.None)
continue; continue;
@ -5025,23 +5047,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
SceneObjectPart part = (SceneObjectPart)update.Entity; if (useCompressUpdate)
SceneObjectGroup grp = part.ParentGroup;
// minimal compress conditions, not enough ?
//if (grp.UsesPhysics || part.Velocity.LengthSquared() > 1e-8f || part.Acceleration.LengthSquared() > 1e-6f)
{
maxUpdatesBytes -= 150; // crude estimation
if (objectUpdates == null)
{
objectUpdates = new List<EntityUpdate>();
maxUpdatesBytes -= 18;
}
objectUpdates.Add(update);
}
//compress still disabled
/*
else
{ {
maxUpdatesBytes -= 150; // crude estimation maxUpdatesBytes -= 150; // crude estimation
@ -5052,7 +5058,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
compressedUpdates.Add(update); compressedUpdates.Add(update);
} }
*/ else
{
maxUpdatesBytes -= 150; // crude estimation
if (objectUpdates == null)
{
objectUpdates = new List<EntityUpdate>();
maxUpdatesBytes -= 18;
}
objectUpdates.Add(update);
}
} }
} }
@ -5147,7 +5163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
} }
} }
/*
if(compressedUpdates != null) if(compressedUpdates != null)
{ {
List<EntityUpdate> tau = new List<EntityUpdate>(30); List<EntityUpdate> tau = new List<EntityUpdate>(30);
@ -5168,8 +5184,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int count = 0; int count = 0;
foreach (EntityUpdate eu in compressedUpdates) foreach (EntityUpdate eu in compressedUpdates)
{ {
SceneObjectPart sop = (SceneObjectPart)eu.Entity;
if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
continue;
lastpos = pos; lastpos = pos;
CreateCompressedUpdateBlock((SceneObjectPart)eu.Entity, mysp, data, ref pos); CreateCompressedUpdateBlock(sop, mysp, data, ref pos);
if (pos < LLUDPServer.MAXPAYLOAD) if (pos < LLUDPServer.MAXPAYLOAD)
{ {
tau.Add(eu); tau.Add(eu);
@ -5207,7 +5226,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
} }
} }
*/
if (objectUpdateProbes != null)
{
UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
byte[] data = buf.Data;
Buffer.BlockCopy(ObjectUpdateCachedHeader, 0, data, 0, 7);
Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, data, 7); // 15
Utils.UInt16ToBytes(timeDilation, data, 15); // 17
int countposition = 17; // blocks count position
int pos = 18;
int count = 0;
foreach (EntityUpdate eu in objectUpdateProbes)
{
SceneObjectPart sop = (SceneObjectPart)eu.Entity;
if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
continue;
uint primflags = m_scene.Permissions.GenerateClientFlags(sop, mysp);
if (mysp.UUID != sop.OwnerID)
primflags &= ~(uint)PrimFlags.CreateSelected;
else
{
if (sop.CreateSelected)
primflags |= (uint)PrimFlags.CreateSelected;
else
primflags &= ~(uint)PrimFlags.CreateSelected;
}
Utils.UIntToBytes(sop.LocalId, data, pos); pos += 4;
Utils.UIntToBytes((uint)sop.ParentGroup.PseudoCRC, data, pos); pos += 4; //WRONG
Utils.UIntToBytes(primflags, data, pos); pos += 4;
if (pos < (LLUDPServer.MAXPAYLOAD - 12))
++count;
else
{
// we need more packets
UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
buf.Data[countposition] = (byte)count;
buf.DataLength = pos;
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, false);
buf = newbuf;
data = buf.Data;
pos = 18;
count = 0;
}
}
if (count > 0)
{
buf.Data[countposition] = (byte)count;
buf.DataLength = pos;
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, false);
}
}
if (terseUpdates != null) if (terseUpdates != null)
{ {
int blocks = terseUpdates.Count; int blocks = terseUpdates.Count;
@ -5329,8 +5409,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
lock (GroupsInView) lock (GroupsInView)
GroupsInView.Add(grp); GroupsInView.Add(grp);
PrimUpdateFlags flags = PrimUpdateFlags.CancelKill;
if(viewerCache && grp.IsViewerCachable)
flags |= PrimUpdateFlags.UpdateProbe;
foreach (SceneObjectPart p in grp.Parts) foreach (SceneObjectPart p in grp.Parts)
SendEntityUpdate(p, PrimUpdateFlags.CancelKill); SendEntityUpdate(p, flags);
} }
} }
@ -5461,10 +5544,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if(GroupsNeedFullUpdate.Count > 0) if(GroupsNeedFullUpdate.Count > 0)
{ {
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) bool viewerCache = m_supportViewerCache && (m_viewerHandShakeFlags & 1) != 0 && mysp.IsChildAgent;
foreach (SceneObjectGroup grp in GroupsNeedFullUpdate)
{ {
foreach(SceneObjectPart p in grp.Parts) PrimUpdateFlags flags = PrimUpdateFlags.CancelKill;
SendEntityUpdate(p, PrimUpdateFlags.CancelKill); if (viewerCache && grp.IsViewerCachable)
flags |= PrimUpdateFlags.UpdateProbe;
foreach (SceneObjectPart p in grp.Parts)
SendEntityUpdate(p, flags);
} }
} }
@ -7173,7 +7260,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
dest[pos++] = state; dest[pos++] = state;
///**** temp hack ///**** temp hack
Utils.UIntToBytesSafepos((uint)rnd.Next(), dest, pos); pos += 4; //CRC needs fix or things will get crazy for now avoid caching Utils.UIntToBytesSafepos((uint)part.ParentGroup.PseudoCRC, dest, pos); pos += 4;
dest[pos++] = part.Material; dest[pos++] = part.Material;
dest[pos++] = part.ClickAction; dest[pos++] = part.ClickAction;
part.Shape.Scale.ToBytes(dest, pos); pos += 12; part.Shape.Scale.ToBytes(dest, pos); pos += 12;
@ -8407,13 +8494,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
public uint m_viewerHandShakeFlags = 0;
private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack) private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack)
{ {
Action<IClientAPI> handlerRegionHandShakeReply = OnRegionHandShakeReply; Action<IClientAPI, uint> handlerRegionHandShakeReply = OnRegionHandShakeReply;
if (handlerRegionHandShakeReply != null) if (handlerRegionHandShakeReply == null)
{ return true; // silence the warning
handlerRegionHandShakeReply(this);
} RegionHandshakeReplyPacket rsrpkt = (RegionHandshakeReplyPacket)Pack;
if(rsrpkt.AgentData.AgentID != m_agentId || rsrpkt.AgentData.SessionID != m_sessionId)
return false;
// regionHandSHake is a protocol message, but it is also seems to be the only way to update terrain textures
// in last case this should be ignored.
OnRegionHandShakeReply = null;
if(m_supportViewerCache)
m_viewerHandShakeFlags = rsrpkt.RegionInfo.Flags;
else
m_viewerHandShakeFlags = 0;
handlerRegionHandShakeReply(this, m_viewerHandShakeFlags);
return true; return true;
} }
@ -8657,19 +8758,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack) private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack)
{ {
m_log.DebugFormat("[LLClientView] HandleCompleteAgentMovement"); //m_log.DebugFormat("[LLClientView] HandleCompleteAgentMovement");
Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion; Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion;
if (handlerCompleteMovementToRegion != null) if (handlerCompleteMovementToRegion == null)
{ return false;
handlerCompleteMovementToRegion(sender, true);
}
else
m_log.Debug("HandleCompleteAgentMovement NULL handler");
handlerCompleteMovementToRegion = null; CompleteAgentMovementPacket cmp = (CompleteAgentMovementPacket)Pack;
if(cmp.AgentData.AgentID != m_agentId || cmp.AgentData.SessionID != m_sessionId || cmp.AgentData.CircuitCode != m_circuitCode)
return false;
handlerCompleteMovementToRegion(sender, true);
return true; return true;
} }
@ -9141,6 +9242,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleRequestMultipleObjects(IClientAPI sender, Packet Pack) private bool HandleRequestMultipleObjects(IClientAPI sender, Packet Pack)
{ {
ObjectRequest handlerObjectRequest = OnObjectRequest;
if (handlerObjectRequest == null)
return false;
RequestMultipleObjectsPacket incomingRequest = (RequestMultipleObjectsPacket)Pack; RequestMultipleObjectsPacket incomingRequest = (RequestMultipleObjectsPacket)Pack;
#region Packet Session and User Check #region Packet Session and User Check
@ -9149,16 +9254,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
#endregion #endregion
ObjectRequest handlerObjectRequest = null;
for (int i = 0; i < incomingRequest.ObjectData.Length; i++) for (int i = 0; i < incomingRequest.ObjectData.Length; i++)
{
handlerObjectRequest = OnObjectRequest;
if (handlerObjectRequest != null)
{
handlerObjectRequest(incomingRequest.ObjectData[i].ID, this); handlerObjectRequest(incomingRequest.ObjectData[i].ID, this);
}
}
return true; return true;
} }

View File

@ -369,6 +369,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
public int IncomingOrphanedPacketCount { get; protected set; } public int IncomingOrphanedPacketCount { get; protected set; }
public bool SupportViewerObjectsCache = false;
/// <summary> /// <summary>
/// Run queue empty processing within a single persistent thread. /// Run queue empty processing within a single persistent thread.
/// </summary> /// </summary>
@ -433,6 +434,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_disableFacelights = config.GetBoolean("DisableFacelights", false); m_disableFacelights = config.GetBoolean("DisableFacelights", false);
m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60); m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60);
m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300); m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300);
SupportViewerObjectsCache = config.GetBoolean("SupportViewerObjectsCache", SupportViewerObjectsCache);
} }
else else
{ {
@ -1724,14 +1726,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (client != null) if (client != null)
{ {
client.SendRegionHandshake(); client.SendRegionHandshake();
client.CheckViewerCaps(); client.CheckViewerCaps();
// We only want to send initial data to new clients, not ones which are being converted from child to root.
bool tp = (aCircuit.teleportFlags > 0);
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
if (!tp)
client.SceneAgent.SendInitialDataToMe();
} }
} }
else else

View File

@ -574,7 +574,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
Scene.RegionInfo.RegionSettings.Save(); Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange(); TriggerRegionInfoChange();
sendRegionHandshakeToAll(); sendRegionHandshakeToAll();
sendRegionInfoPacketToAll(); // sendRegionInfoPacketToAll();
} }
private void handleCommitEstateTerrainTextureRequest(IClientAPI remoteClient) private void handleCommitEstateTerrainTextureRequest(IClientAPI remoteClient)

View File

@ -153,10 +153,23 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void RequestPrim(uint primLocalID, IClientAPI remoteClient) public void RequestPrim(uint primLocalID, IClientAPI remoteClient)
{ {
SceneObjectGroup sog = GetGroupByPrim(primLocalID); SceneObjectPart part = GetSceneObjectPart(primLocalID);
if (part != null)
{
SceneObjectGroup sog = part.ParentGroup;
if(!sog.IsDeleted)
{
PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
if (sog.RootPart.Shape.MeshFlagEntry)
update = PrimUpdateFlags.FullUpdatewithAnim;
part.SendUpdate(remoteClient, update);
}
}
if (sog != null) //SceneObjectGroup sog = GetGroupByPrim(primLocalID);
sog.SendFullAnimUpdateToClient(remoteClient);
//if (sog != null)
//sog.SendFullAnimUpdateToClient(remoteClient);
} }
/// <summary> /// <summary>

View File

@ -170,8 +170,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
private bool m_scripts_enabled; private bool m_scripts_enabled;
public SynchronizeSceneHandler SynchronizeScene;
public bool ClampNegativeZ public bool ClampNegativeZ
{ {
get { return m_clampNegativeZ; } get { return m_clampNegativeZ; }
@ -1006,11 +1004,9 @@ namespace OpenSim.Region.Framework.Scenes
m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete); m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
m_dontPersistBefore = m_dontPersistBefore = startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
m_dontPersistBefore *= 10000000; m_dontPersistBefore *= 10000000;
m_persistAfter = m_persistAfter = startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
m_persistAfter *= 10000000; m_persistAfter *= 10000000;
m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
@ -1695,9 +1691,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (PhysicsEnabled) if (PhysicsEnabled)
physicsFPS = m_sceneGraph.UpdatePhysics(FrameTime); physicsFPS = m_sceneGraph.UpdatePhysics(FrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
} }
tmpMS2 = Util.GetTimeStampMS(); tmpMS2 = Util.GetTimeStampMS();
@ -1775,30 +1768,6 @@ namespace OpenSim.Region.Framework.Scenes
// Region ready should always be set // Region ready should always be set
Ready = true; Ready = true;
IConfig restartConfig = m_config.Configs["RestartModule"];
if (restartConfig != null)
{
string markerPath = restartConfig.GetString("MarkerPath", String.Empty);
if (markerPath != String.Empty)
{
string path = Path.Combine(markerPath, RegionInfo.RegionID.ToString() + ".ready");
try
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
FileStream fs = File.Create(path);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
Byte[] buf = enc.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
fs.Close();
}
catch (Exception)
{
}
}
}
} }
else else
{ {

View File

@ -119,6 +119,21 @@ namespace OpenSim.Region.Framework.Scenes
// private PrimCountTaintedDelegate handlerPrimCountTainted = null; // private PrimCountTaintedDelegate handlerPrimCountTainted = null;
public bool IsViewerCachable
{
get
{
// needs more exclusion ?
return(Backup && !IsTemporary && !inTransit && !IsSelected && !UsesPhysics && !IsAttachmentCheckFull() &&
!RootPart.Shape.MeshFlagEntry && // animations are not sent correctly for now
RootPart.KeyframeMotion == null &&
(DateTime.UtcNow.Ticks - timeLastChanged > 36000000000) && //36000000000 is one hour
RootPart.Velocity.LengthSquared() < 1e8f && // should not be needed
RootPart.Acceleration.LengthSquared() < 1e4f // should not be needed
);
}
}
/// <summary> /// <summary>
/// Signal whether the non-inventory attributes of any prims in the group have changed /// Signal whether the non-inventory attributes of any prims in the group have changed
/// since the group's last persistent backup /// since the group's last persistent backup
@ -128,7 +143,8 @@ namespace OpenSim.Region.Framework.Scenes
private long timeLastChanged = 0; private long timeLastChanged = 0;
private long m_maxPersistTime = 0; private long m_maxPersistTime = 0;
private long m_minPersistTime = 0; private long m_minPersistTime = 0;
// private Random m_rand;
public int PseudoCRC;
/// <summary> /// <summary>
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@ -145,40 +161,26 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (value) if (value)
{ {
if (Backup) if (Backup)
{
m_scene.SceneGraph.FireChangeBackup(this); m_scene.SceneGraph.FireChangeBackup(this);
}
PseudoCRC = (int)(DateTime.UtcNow.Ticks); ;
timeLastChanged = DateTime.UtcNow.Ticks; timeLastChanged = DateTime.UtcNow.Ticks;
if (!m_hasGroupChanged) if (!m_hasGroupChanged)
timeFirstChanged = DateTime.UtcNow.Ticks; timeFirstChanged = timeLastChanged;
if (m_rootPart != null && m_scene != null) if (m_rootPart != null && m_scene != null)
{ {
/*
if (m_rand == null)
{
byte[] val = new byte[16];
m_rootPart.UUID.ToBytes(val, 0);
m_rand = new Random(BitConverter.ToInt32(val, 0));
}
*/
if (m_scene.GetRootAgentCount() == 0) if (m_scene.GetRootAgentCount() == 0)
{ {
//If the region is empty, this change has been made by an automated process //If the region is empty, this change has been made by an automated process
//and thus we delay the persist time by a random amount between 1.5 and 2.5. //and thus we delay the persist time by a random amount between 1.5 and 2.5.
// float factor = 1.5f + (float)(m_rand.NextDouble());
float factor = 2.0f; float factor = 2.0f;
m_maxPersistTime = (long)((float)m_scene.m_persistAfter * factor); m_maxPersistTime = (long)(m_scene.m_persistAfter * factor);
m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * factor); m_minPersistTime = (long)(m_scene.m_dontPersistBefore * factor);
} }
else else
{ {
//If the region is not empty, we want to obey the minimum and maximum persist times
//but add a random factor so we stagger the object persistance a little
// m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5
// m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0
m_maxPersistTime = m_scene.m_persistAfter; m_maxPersistTime = m_scene.m_persistAfter;
m_minPersistTime = m_scene.m_dontPersistBefore; m_minPersistTime = m_scene.m_dontPersistBefore;
} }
@ -1330,6 +1332,7 @@ namespace OpenSim.Region.Framework.Scenes
public SceneObjectGroup() public SceneObjectGroup()
{ {
m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0; m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0;
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
} }
/// <summary> /// <summary>
@ -2441,6 +2444,21 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void SendUpdateProbes(IClientAPI remoteClient)
{
PrimUpdateFlags update = PrimUpdateFlags.UpdateProbe;
RootPart.SendUpdate(remoteClient, update);
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part != RootPart)
part.SendUpdate(remoteClient, update);
}
}
#region Copying #region Copying
/// <summary> /// <summary>
@ -2516,6 +2534,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
dupe.InvalidatePartsLinkMaps(); dupe.InvalidatePartsLinkMaps();
dupe.PseudoCRC = (int)(DateTime.UtcNow.Ticks);
m_dupeInProgress = false; m_dupeInProgress = false;
return dupe; return dupe;
} }
@ -2769,6 +2788,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
rpart.ScheduleFullUpdate(); rpart.ScheduleFullUpdate();
} }
@ -2808,6 +2828,7 @@ namespace OpenSim.Region.Framework.Scenes
part.ResetIDs(part.LinkNum); // Don't change link nums part.ResetIDs(part.LinkNum); // Don't change link nums
m_parts.Add(part.UUID, part); m_parts.Add(part.UUID, part);
} }
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
} }
} }
@ -3117,7 +3138,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// 'linkPart' == the root of the group being linked into this group // 'linkPart' == the root of the group being linked into this group
SceneObjectPart linkPart = objectGroup.m_rootPart; SceneObjectPart linkPart = objectGroup.m_rootPart;
@ -3160,7 +3180,6 @@ namespace OpenSim.Region.Framework.Scenes
axPos *= Quaternion.Conjugate(parentRot); axPos *= Quaternion.Conjugate(parentRot);
linkPart.OffsetPosition = axPos; linkPart.OffsetPosition = axPos;
// If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset. // If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset.
// Now that we know this SOG has at least two SOPs in it, the new root // Now that we know this SOG has at least two SOPs in it, the new root
// SOP becomes the first in the linkset. // SOP becomes the first in the linkset.
@ -3193,8 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.CreateSelected = true; linkPart.CreateSelected = true;
// let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive || RootPart.VolumeDetectActive, true);
linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive, true);
// If the added SOP is physical, also tell the physics engine about the link relationship. // If the added SOP is physical, also tell the physics engine about the link relationship.
if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)

View File

@ -1179,9 +1179,10 @@ namespace OpenSim.Region.Framework.Scenes
set set
{ {
string old = m_mediaUrl;
m_mediaUrl = value; m_mediaUrl = value;
if (ParentGroup != null) if (ParentGroup != null && old != m_mediaUrl)
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
} }
} }
@ -1385,13 +1386,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
[XmlIgnore]
public bool IsOccupied // KF If an av is sittingon this prim
{
get { return m_occupied; }
set { m_occupied = value; }
}
/// <summary> /// <summary>
/// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero
/// </summary> /// </summary>
@ -2472,12 +2466,6 @@ namespace OpenSim.Region.Framework.Scenes
public uint GetEffectiveObjectFlags() public uint GetEffectiveObjectFlags()
{ {
// Commenting this section of code out since it doesn't actually do anything, as enums are handled by
// value rather than reference
// PrimFlags f = _flags;
// if (m_parentGroup == null || m_parentGroup.RootPart == this)
// f &= ~(PrimFlags.Touch | PrimFlags.Money);
uint eff = (uint)Flags | (uint)LocalFlags; uint eff = (uint)Flags | (uint)LocalFlags;
if(m_inventory == null || m_inventory.Count == 0) if(m_inventory == null || m_inventory.Count == 0)
eff |= (uint)PrimFlags.InventoryEmpty; eff |= (uint)PrimFlags.InventoryEmpty;

View File

@ -1212,7 +1212,9 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
ControllingClient.OnAutoPilotGo += MoveToTargetHandle; ControllingClient.OnAutoPilotGo += MoveToTargetHandle;
ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles; ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
// ControllingClient.OnAgentFOV += HandleAgentFOV; ControllingClient.OnRegionHandShakeReply += RegionHandShakeReply;
// ControllingClient.OnAgentFOV += HandleAgentFOV;
// ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
// ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@ -1232,7 +1234,9 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls; ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls;
ControllingClient.OnAutoPilotGo -= MoveToTargetHandle; ControllingClient.OnAutoPilotGo -= MoveToTargetHandle;
ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles; ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles;
// ControllingClient.OnAgentFOV += HandleAgentFOV; ControllingClient.OnRegionHandShakeReply -= RegionHandShakeReply;
// ControllingClient.OnAgentFOV += HandleAgentFOV;
} }
private void SetDirectionVectors() private void SetDirectionVectors()
@ -2126,56 +2130,54 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
if(IsChildAgent)
{
return; // how?
}
//m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if(!haveGroupInformation && !IsChildAgent && !IsNPC) if (!IsNPC)
{ {
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); if (!haveGroupInformation && !IsNPC)
if (gm != null) {
Grouptitle = gm.GetGroupTitle(m_uuid); IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
if (gm != null)
Grouptitle = gm.GetGroupTitle(m_uuid);
//m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts));
InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46); InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46);
if (cof == null) if (cof == null)
COF = UUID.Zero; COF = UUID.Zero;
else else
COF = cof.ID; COF = cof.ID;
m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF); m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF);
}
if (!string.IsNullOrEmpty(m_callbackURI))
{
// We cannot sleep here since this would hold up the inbound packet processing thread, as
// CompleteMovement() is executed synchronously. However, it might be better to delay the release
// here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
// is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
// region as the current region, meaning that a close sent before then will fail the teleport.
// System.Threading.Thread.Sleep(2000);
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_callbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {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
// CompleteMovement() is executed synchronously. However, it might be better to delay the release
// here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
// is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
// region as the current region, meaning that a close sent before then will fail the teleport.
// System.Threading.Thread.Sleep(2000);
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_callbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
// else
// {
// m_log.DebugFormat(
// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
// }
// 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);
//m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts));
@ -2187,33 +2189,30 @@ namespace OpenSim.Region.Framework.Scenes
int delayctnr = Util.EnvironmentTickCount(); int delayctnr = Util.EnvironmentTickCount();
if (!IsChildAgent) if( ParentPart != null && !IsNPC && (crossingFlags & 0x08) != 0)
{ {
if( ParentPart != null && !IsNPC && (crossingFlags & 0x08) != 0) ParentPart.ParentGroup.SendFullAnimUpdateToClient(ControllingClient);
{
ParentPart.ParentGroup.SendFullAnimUpdateToClient(ControllingClient);
}
// verify baked textures and cache
bool cachedbaked = false;
if (IsNPC)
cachedbaked = true;
else
{
if (m_scene.AvatarFactory != null && !isHGTP)
cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this);
// not sure we need this
if (!cachedbaked)
{
if (m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(UUID);
}
}
//m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts));
} }
// verify baked textures and cache
bool cachedbaked = false;
if (IsNPC)
cachedbaked = true;
else
{
if (m_scene.AvatarFactory != null && !isHGTP)
cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this);
// not sure we need this
if (!cachedbaked)
{
if (m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(UUID);
}
}
//m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if(m_teleportFlags > 0) if(m_teleportFlags > 0)
{ {
gotCrossUpdate = false; // sanity check gotCrossUpdate = false; // sanity check
@ -2251,104 +2250,103 @@ namespace OpenSim.Region.Framework.Scenes
landch.sendClientInitialLandInfo(client, !gotCrossUpdate); landch.sendClientInitialLandInfo(client, !gotCrossUpdate);
} }
if (!IsChildAgent) List<ScenePresence> allpresences = m_scene.GetScenePresences();
// send avatar object to all presences including us, so they cross it into region
// then hide if necessary
SendInitialAvatarDataToAllAgents(allpresences);
// send this look
SendAppearanceToAgent(this);
// send this animations
UUID[] animIDs = null;
int[] animseqs = null;
UUID[] animsobjs = null;
if (Animator != null)
Animator.GetArrays(out animIDs, out animseqs, out animsobjs);
bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null);
if (haveAnims)
SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
// we should be able to receive updates, etc
// so release them
m_inTransit = false;
// send look and animations to others
// if not cached we send greys
// uncomented if will wait till avatar does baking
//if (cachedbaked)
{ {
List<ScenePresence> allpresences = m_scene.GetScenePresences(); foreach (ScenePresence p in allpresences)
// send avatar object to all presences including us, so they cross it into region
// then hide if necessary
SendInitialAvatarDataToAllAgents(allpresences);
// send this look
SendAppearanceToAgent(this);
// send this animations
UUID[] animIDs = null;
int[] animseqs = null;
UUID[] animsobjs = null;
if (Animator != null)
Animator.GetArrays(out animIDs, out animseqs, out animsobjs);
bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null);
if (haveAnims)
SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
// we should be able to receive updates, etc
// so release them
m_inTransit = false;
// send look and animations to others
// if not cached we send greys
// uncomented if will wait till avatar does baking
//if (cachedbaked)
{ {
if (p == this)
continue;
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
continue;
SendAppearanceToAgentNF(p);
if (haveAnims)
SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs);
}
} // greys if
//m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// attachments
if (IsNPC || IsRealLogin(m_teleportFlags))
{
if (Scene.AttachmentsModule != null)
// Util.FireAndForget(
// o =>
// {
if (!IsNPC)
Scene.AttachmentsModule.RezAttachments(this);
else
Util.FireAndForget(x =>
{
Scene.AttachmentsModule.RezAttachments(this);
});
// });
}
else
{
if (m_attachments.Count > 0)
{
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
foreach (SceneObjectGroup sog in m_attachments)
{
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
}
foreach (ScenePresence p in allpresences) foreach (ScenePresence p in allpresences)
{ {
if (p == this) if (p == this)
{
SendAttachmentsToAgentNF(this);
continue; continue;
}
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
continue; continue;
SendAppearanceToAgentNF(p); SendAttachmentsToAgentNF(p);
if (haveAnims)
SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs);
}
} // greys if
//m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// attachments
if (IsNPC || IsRealLogin(m_teleportFlags))
{
if (Scene.AttachmentsModule != null)
// Util.FireAndForget(
// o =>
// {
if (!IsNPC)
Scene.AttachmentsModule.RezAttachments(this);
else
Util.FireAndForget(x =>
{
Scene.AttachmentsModule.RezAttachments(this);
});
// });
}
else
{
if (m_attachments.Count > 0)
{
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
foreach (SceneObjectGroup sog in m_attachments)
{
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
}
foreach (ScenePresence p in allpresences)
{
if (p == this)
{
SendAttachmentsToAgentNF(this);
continue;
}
if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
continue;
SendAttachmentsToAgentNF(p);
}
} }
} }
}
if(!IsNPC)
{
//m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (openChildAgents) if (openChildAgents)
{ {
@ -2366,34 +2364,33 @@ namespace OpenSim.Region.Framework.Scenes
m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel; m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
m_childUpdatesBusy = false; // allow them m_childUpdatesBusy = false; // allow them
}
//m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //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 || m_currentParcelHide) if (m_teleportFlags > 0 | m_currentParcelHide)
SendInitialDataToMe(); SendInitialDataToMe();
// priority uses avatar position only // priority uses avatar position only
// m_reprioritizationLastPosition = AbsolutePosition; // m_reprioritizationLastPosition = AbsolutePosition;
// m_reprioritizationLastDrawDistance = DrawDistance; // m_reprioritizationLastDrawDistance = DrawDistance;
// m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it // m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
// m_reprioritizationBusy = false; // m_reprioritizationBusy = false;
//m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!IsChildAgent && openChildAgents) if (openChildAgents)
{
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null)
{ {
if(gotCrossUpdate) IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
friendsModule.IsNowRoot(this); if (friendsModule != null)
else {
friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); if(gotCrossUpdate)
friendsModule.IsNowRoot(this);
else
friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
}
//m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts));
} }
//m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts));
} }
} }
finally finally
@ -4024,10 +4021,100 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
} }
public void RegionHandShakeReply (IClientAPI client, uint flags)
{
if(IsNPC)
return;
bool selfappearance = (flags & 4) != 0;
bool cacheCulling = (flags & 1) != 0;
bool cacheEmpty;
if(cacheCulling)
cacheEmpty = (flags & 2) != 0;
else
cacheEmpty = true;
if (m_teleportFlags > 0) // only doing for child for now
return;
lock (m_completeMovementLock)
{
if (SentInitialData)
return;
SentInitialData = true;
}
Util.FireAndForget(delegate
{
Scene.SendLayerData(ControllingClient);
ILandChannel landch = m_scene.LandChannel;
if (landch != null)
landch.sendClientInitialLandInfo(ControllingClient, true);
// recheck to reduce timing issues
ControllingClient.CheckViewerCaps();
SendOtherAgentsAvatarFullToMe();
/*
if (m_scene.ObjectsCullingByDistance && cacheCulling)
{
m_reprioritizationBusy = true;
m_reprioritizationLastPosition = AbsolutePosition;
m_reprioritizationLastDrawDistance = DrawDistance;
ControllingClient.ReprioritizeUpdates();
m_reprioritizationLastTime = Util.EnvironmentTickCount();
m_reprioritizationBusy = false;
return;
}
*/
EntityBase[] entities = Scene.Entities.GetEntities();
if(cacheEmpty)
{
foreach (EntityBase e in entities)
{
if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
((SceneObjectGroup)e).SendFullAnimUpdateToClient(ControllingClient);
}
}
else
{
foreach (EntityBase e in entities)
{
if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
{
SceneObjectGroup grp = e as SceneObjectGroup;
if(grp.IsViewerCachable)
grp.SendUpdateProbes(ControllingClient);
else
grp.SendFullAnimUpdateToClient(ControllingClient);
}
}
}
m_reprioritizationLastPosition = AbsolutePosition;
m_reprioritizationLastDrawDistance = DrawDistance;
m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
m_reprioritizationBusy = false;
});
}
public void SendInitialDataToMe() public void SendInitialDataToMe()
{ {
// Send all scene object to the new client // Send all scene object to the new client
SentInitialData = true; lock (m_completeMovementLock)
{
if (SentInitialData)
return;
SentInitialData = true;
}
Util.FireAndForget(delegate Util.FireAndForget(delegate
{ {
// we created a new ScenePresence (a new child agent) in a fresh region. // we created a new ScenePresence (a new child agent) in a fresh region.
@ -4280,7 +4367,13 @@ namespace OpenSim.Region.Framework.Scenes
if(IsDeleted || !ControllingClient.IsActive) if(IsDeleted || !ControllingClient.IsActive)
return; return;
if(!SentInitialData) bool needsendinitial = false;
lock(m_completeMovementLock)
{
needsendinitial = SentInitialData;
}
if(!needsendinitial)
{ {
SendInitialDataToMe(); SendInitialDataToMe();
return; return;

View File

@ -699,7 +699,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event TeleportCancel OnTeleportCancel; public event TeleportCancel OnTeleportCancel;
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI> OnRegionHandShakeReply; public event Action<IClientAPI, uint> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -938,7 +938,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this); OnRegionHandShakeReply(this, 0);
} }
if (OnCompleteMovementToRegion != null) if (OnCompleteMovementToRegion != null)

View File

@ -319,7 +319,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI> OnRegionHandShakeReply; public event Action<IClientAPI, uint> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -928,7 +928,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this); OnRegionHandShakeReply(this, 0);
} }
} }

View File

@ -119,7 +119,7 @@ namespace OpenSim.Tests.Common
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI> OnRegionHandShakeReply; public event Action<IClientAPI, uint> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -880,7 +880,7 @@ namespace OpenSim.Tests.Common
{ {
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this); OnRegionHandShakeReply(this, 0);
} }
} }