/// <summary> /// Invoked when the client selects a prim. /// </summary> /// <param name="primLocalID"></param> /// <param name="remoteClient"></param> public void SelectPrim(List <uint> primIDs, IClientAPI remoteClient) { foreach (uint primLocalID in primIDs) { SceneObjectPart part = GetSceneObjectPart(primLocalID); if (part == null) { continue; } SceneObjectGroup sog = part.ParentGroup; if (sog == null) { continue; } // waste of time because properties do not send prim flags as they should // if a friend got or lost edit rights after login, a full update is needed if (sog.OwnerID != remoteClient.AgentId) { part.SendFullUpdate(remoteClient); } // A prim is only tainted if it's allowed to be edited by the person clicking it. if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) { part.IsSelected = true; EventManager.TriggerParcelPrimCountTainted(); } part.SendPropertiesToClient(remoteClient); } }
/// <summary> /// Invoked when the client selects a prim. /// </summary> /// <param name="primLocalID"></param> /// <param name="remoteClient"></param> public void SelectPrim(uint primLocalID, IClientAPI remoteClient) { /* * SceneObjectPart part = GetSceneObjectPart(primLocalID); * * if (null == part) * return; * * if (part.IsRoot) * { * SceneObjectGroup sog = part.ParentGroup; * sog.SendPropertiesToClient(remoteClient); * * // A prim is only tainted if it's allowed to be edited by the person clicking it. * if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) || { || sog.IsSelected = true; || EventManager.TriggerParcelPrimCountTainted(); || } || } || else || { || part.SendPropertiesToClient(remoteClient); || } */ SceneObjectPart part = GetSceneObjectPart(primLocalID); if (null == part) { return; } SceneObjectGroup sog = part.ParentGroup; if (sog == null) { return; } part.SendPropertiesToClient(remoteClient); // waste of time because properties do not send prim flags as they should // if a friend got or lost edit rights after login, a full update is needed if (sog.OwnerID != remoteClient.AgentId) { part.SendFullUpdate(remoteClient); } // A prim is only tainted if it's allowed to be edited by the person clicking it. if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) { part.IsSelected = true; EventManager.TriggerParcelPrimCountTainted(); } }
public void SendPrimUpdates() { if (m_pendingObjects == null) { if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) { m_pendingObjects = new Queue <SceneObjectGroup>(); lock (m_pendingObjects) { foreach (EntityBase e in m_presence.Scene.Entities) { if (e != null && e is SceneObjectGroup) { m_pendingObjects.Enqueue((SceneObjectGroup)e); } } } } } lock (m_pendingObjects) { while (m_pendingObjects != null && m_pendingObjects.Count > 0) { SceneObjectGroup g = m_pendingObjects.Dequeue(); // Yes, this can really happen if (g == null) { continue; } // This is where we should check for draw distance // do culling and stuff. Problem with that is that until // we recheck in movement, that won't work right. // So it's not implemented now. // // Don't even queue if we have sent this one // if (!m_updateTimes.ContainsKey(g.UUID)) { g.ScheduleFullUpdateToAvatar(m_presence); } } while (m_partsUpdateQueue.Count > 0) { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); if (part.ParentGroup == null || part.ParentGroup.IsDeleted) { continue; } if (m_updateTimes.ContainsKey(part.UUID)) { ScenePartUpdate update = m_updateTimes[part.UUID]; // We deal with the possibility that two updates occur at // the same unix time at the update point itself. if ((update.LastFullUpdateTime < part.TimeStampFull) || part.IsAttachment) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampFull); part.SendFullUpdate(m_presence.ControllingClient, m_presence.GenerateClientFlags(part.UUID)); // We'll update to the part's timestamp rather than // the current time to avoid the race condition // whereby the next tick occurs while we are doing // this update. If this happened, then subsequent // updates which occurred on the same tick or the // next tick of the last update would be ignored. update.LastFullUpdateTime = part.TimeStampFull; } else if (update.LastTerseUpdateTime <= part.TimeStampTerse) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampTerse); part.SendTerseUpdateToClient(m_presence.ControllingClient); update.LastTerseUpdateTime = part.TimeStampTerse; } } else { //never been sent to client before so do full update ScenePartUpdate update = new ScenePartUpdate(); update.FullID = part.UUID; update.LastFullUpdateTime = part.TimeStampFull; m_updateTimes.Add(part.UUID, update); // Attachment handling // if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) { if (part != part.ParentGroup.RootPart) { continue; } part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); continue; } part.SendFullUpdate(m_presence.ControllingClient, m_presence.GenerateClientFlags(part.UUID)); } } } }
public void SendPartUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags) { ScenePartUpdate update = null; int partFullUpdateCounter = part.FullUpdateCounter; int partTerseUpdateCounter = part.TerseUpdateCounter; bool sendFullUpdate = false, sendFullInitialUpdate = false, sendTerseUpdate = false; lock (m_updateTimes) { if (m_updateTimes.TryGetValue(part.LocalId, out update)) { if ((update.LastFullUpdateTime != partFullUpdateCounter) || part.ParentGroup.IsAttachment) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampFull); update.LastFullUpdateTime = partFullUpdateCounter; update.LastFullUpdateTimeRequested = partFullUpdateCounter; //also cancel any pending terses since the full covers it update.LastTerseUpdateTime = partTerseUpdateCounter; update.LastTerseUpdateTimeRequested = partTerseUpdateCounter; sendFullUpdate = true; } else if (update.LastTerseUpdateTime != partTerseUpdateCounter) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampTerse); update.LastTerseUpdateTime = partTerseUpdateCounter; update.LastTerseUpdateTimeRequested = partTerseUpdateCounter; sendTerseUpdate = true; } } else { //never been sent to client before so do full update ScenePartUpdate newUpdate = new ScenePartUpdate(); newUpdate.FullID = part.UUID; newUpdate.LastFullUpdateTime = partFullUpdateCounter; newUpdate.LastFullUpdateTimeRequested = partFullUpdateCounter; m_updateTimes.Add(part.LocalId, newUpdate); sendFullInitialUpdate = true; } } if (sendFullUpdate) { part.SendFullUpdate(m_presence.ControllingClient, m_presence.GenerateClientFlags(part.UUID), updateFlags); } else if (sendTerseUpdate) { part.SendTerseUpdateToClient(m_presence.ControllingClient); } else if (sendFullInitialUpdate) { // Attachment handling // if (part.ParentGroup.IsAttachment) { if (part != part.ParentGroup.RootPart) { return; } part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient, PrimUpdateFlags.FullUpdate); return; } part.SendFullUpdate(m_presence.ControllingClient, m_presence.GenerateClientFlags(part.UUID), PrimUpdateFlags.FullUpdate); } }