Example #1
0
        /// <summary>
        /// This function should only be triggered when an update update is received (i.e.
        /// triggered by remote update instead of local update).
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="property"></param>
        private void SetPropertyValue(ScenePresence sp, SyncedProperty syncedProperty)
        {
            if (sp == null)
            {
                return;
            }

            SyncableProperties.Type property = syncedProperty.Property;

            if (syncedProperty == null)
            {
                DebugLog.ErrorFormat("{0}: SetPropertyValue: property {1} not in sync cache for uuid {2}. ", LogHeader, property, UUID);
                return;
            }

            SetPropertyValue(sp, property, syncedProperty);
        }
Example #2
0
        // Constructor used for initializing SyncInfo from remote (OSDMap) data before syncing it locally
        /// <param name="id">UUID of the scene presence</param>
        /// <param name="syncInfoData">Initial sync data</param>
        /// <param name="scene">The local scene</param>
        public SyncInfoPresence(UUID id, OSDArray properties, Scene scene)
        {
            // DebugLog.WarnFormat("[SYNC INFO PRESENCE] Constructing SyncInfoPresence (from map) for uuid {0}", id);

            UUID  = id;
            Scene = scene;

            lock (m_syncLock)
            {
                // Decode syncInfoData into CurrentlySyncedProperties
                CurrentlySyncedProperties = new Dictionary <SyncableProperties.Type, SyncedProperty>();
                foreach (OSD property in properties)
                {
                    // Parse each property from the key in the map we received
                    SyncedProperty syncedProperty = new SyncedProperty((OSDArray)property);
                    CurrentlySyncedProperties.Add(syncedProperty.Property, syncedProperty);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Compare the local timestamp with that in pSyncInfo. If the one in
        /// pSyncInfo is newer, copy its members to the local record.
        /// </summary>
        /// <param name="pSyncInfo"></param>
        /// <returns>'true' if the received sync value was accepted and the sync cache was updated with the received value</returns>
        public bool CompareAndUpdateSyncInfoBySync(SyncedProperty pSyncInfo, long recvTS)
        {
            // KLUDGE!!! THIS TRIES TO FORCE THE SCRIPT SETTING OF ANIMATIONS VS DEFAULT ANIMATIONS.
            // Unconditionally accept an animation update if the received update has extended animations
            //     and the existing animation is a default animation. This case is most often
            //     from a script setting a sit or animation override.
            if (RegionSyncModule.ShouldUnconditionallyAcceptAnimationOverrides && Property == SyncableProperties.Type.Animations)
            {
                OSDArray receivedAnimations = pSyncInfo.LastUpdateValue as OSDArray;
                OSDArray existingAnimations = LastUpdateValue as OSDArray;
                if (receivedAnimations != null && existingAnimations != null)
                {
                    /*
                     * // If going from default animation to something better, always accept it
                     * if (receivedAnimations.Count > 2 && existingAnimations.Count <= 2)
                     * {
                     *  // The new animation has more info than the existing so accept it.
                     *  // DebugLog.DebugFormat("{0} SyncedProperty.CompareAndUpdateSyncInfoBySync: forcing. receivedCnt={1}, existingCnt={2}",    // DEBUG DEBUG
                     *  //         "[DSG SYNCED PROPERTY]", receivedAnimations.Count, existingAnimations.Count);    // DEBUG DEBUG
                     *  UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                     *  return true;
                     * }
                     */
                    // For the moment, just accept received animations
                    UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                    return(true);
                }
            }

            // If update timestamp is later, or we do some tie breaking, then update
            if ((pSyncInfo.LastUpdateTimeStamp > LastUpdateTimeStamp) ||
                ((pSyncInfo.LastUpdateTimeStamp == LastUpdateTimeStamp) &&
                 (!LastUpdateSyncID.Equals(pSyncInfo.LastUpdateSyncID)) &&
                 (SyncIDTieBreak(LastUpdateSyncID, pSyncInfo.LastUpdateSyncID).Equals(pSyncInfo.LastUpdateSyncID))))
            {
                UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                return(true);
            }
            return(false);
        }
Example #4
0
        //In SOP's implementation, GroupPosition and SOP.PhysActor.Position are
        //correlated. We need to make sure that they are both properly synced.
        private bool CompareAndUpdateSOPGroupPositionByLocal(SceneObjectPart part, long lastUpdateByLocalTS, string syncID)
        {
            if (part.ParentGroup.IsAttachment)
                return false;

            SyncedProperty groupPositionProperty;
            SyncedProperty positionProperty;
            CurrentlySyncedProperties.TryGetValue(SyncableProperties.Type.GroupPosition, out groupPositionProperty);
            if (groupPositionProperty == null)
            {
                DebugLog.WarnFormat("{0}: CompareAndUpdateSOPGroupPosition for uuid {1}. GroupPosition is not in CurrentlySyncedProperties!", LogHeader, part.UUID);
                return false;
            }
            // DebugLog.WarnFormat("[SYNC INFO PRIM] CompareAndUpdateSOPGroupPositionByLocal");
            if (!part.GroupPosition.ApproxEquals((Vector3)groupPositionProperty.LastUpdateValue, (float)0.001))
            {
                CurrentlySyncedProperties.TryGetValue(SyncableProperties.Type.Position, out positionProperty);
                if (lastUpdateByLocalTS >= groupPositionProperty.LastUpdateTimeStamp)
                {
                    //Update cached value with SOP.GroupPosition
                    groupPositionProperty.UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, (Object)part.GroupPosition);

                    //Also may need to cached PhysActor.Position
                    if (part.PhysActor != null)
                    {
                        if (positionProperty == null)
                        {
                            Object initValue = GetPropertyValue(part, SyncableProperties.Type.Position);
                            positionProperty = new SyncedProperty(SyncableProperties.Type.Position, initValue, lastUpdateByLocalTS, syncID);
                            CurrentlySyncedProperties.Add(SyncableProperties.Type.Position, positionProperty);
                        }
                        else
                        {
                            if (!part.PhysActor.Position.Equals(positionProperty.LastUpdateValue))
                            {
                                positionProperty.UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, (Object)part.PhysActor.Position);
                            }
                        }
                    }
                    return true;
                }
                else if (lastUpdateByLocalTS < groupPositionProperty.LastUpdateTimeStamp)
                {
                    //overwrite SOP's data, set function of GroupPosition updates PhysActor.Position as well
                    part.GroupPosition = (Vector3)groupPositionProperty.LastUpdateValue;

                    //PhysActor.Position is just updated by setting GroupPosition
                    //above, so need to update the cached value of Position here.
                    if (part.PhysActor != null)
                    {
                        //Set the timestamp and syncID to be the same with GroupPosition
                        long lastUpdateTimestamp = groupPositionProperty.LastUpdateTimeStamp;
                        string lastUpdateSyncID = groupPositionProperty.LastUpdateSyncID;

                        if (positionProperty == null)
                        {
                            Object initValue = GetPropertyValue(part, SyncableProperties.Type.Position);
                            positionProperty = new SyncedProperty(SyncableProperties.Type.Position, initValue, lastUpdateTimestamp, lastUpdateSyncID);
                            CurrentlySyncedProperties.Add(SyncableProperties.Type.Position, positionProperty);
                        }
                        else
                        {
                            if (!part.PhysActor.Position.Equals(positionProperty.LastUpdateValue))
                            {
                                //Set the timestamp and syncID to be the same with GroupPosition
                                //long lastUpdateTimestamp = CurrentlySyncedProperties[SyncableProperties.Type.GroupPosition].LastUpdateTimeStamp;
                                //string lastUpdateSyncID = CurrentlySyncedProperties[SyncableProperties.Type.GroupPosition].LastUpdateSyncID;
                                positionProperty.UpdateSyncInfoByLocal(lastUpdateTimestamp, lastUpdateSyncID, (Object)part.PhysActor.Position);
                            }
                        }
                    }
                }
            }
            return false;
        }
Example #5
0
 public override void SetPropertyValue(SyncedProperty pSyncInfo)
 {
     SceneObjectPart part = (SceneObjectPart)SceneThing;
     // DebugLog.WarnFormat("[SYNC INFO PRIM] SetPropertyValue(property={0})", property.ToString());
     SetPropertyValue(part, pSyncInfo);
     part.ParentGroup.HasGroupChanged = true;
 }
Example #6
0
        private void SetSOPAbsolutePosition(SceneObjectPart part, SyncedProperty pSyncInfo)
        {
            // DebugLog.WarnFormat("[SYNC INFO PRIM] SetSOPAbsolutePosition");
            if (part.ParentGroup != null)
            {
                part.ParentGroup.AbsolutePosition = (Vector3)pSyncInfo.LastUpdateValue;
                if (part.ParentGroup.IsAttachment)
                    return;

                SyncedProperty syncedProperty;
                CurrentlySyncedProperties.TryGetValue(SyncableProperties.Type.GroupPosition, out syncedProperty);
                if (syncedProperty == null)
                {
                    CurrentlySyncedProperties.Add(SyncableProperties.Type.GroupPosition, new SyncedProperty(SyncableProperties.Type.GroupPosition,
                        part.GroupPosition, pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID));
                }
                else
                {
                    syncedProperty.UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, part.GroupPosition, pSyncInfo.LastSyncUpdateRecvTime);
                }

                if (part.PhysActor != null)
                {
                    CurrentlySyncedProperties.TryGetValue(SyncableProperties.Type.Position, out syncedProperty);
                    if(syncedProperty == null)
                    {
                        CurrentlySyncedProperties.Add(SyncableProperties.Type.Position, new SyncedProperty(SyncableProperties.Type.Position,
                            part.PhysActor.Position, pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID));
                    }
                    else
                    {
                        syncedProperty.UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, part.PhysActor.Position, pSyncInfo.LastSyncUpdateRecvTime);
                    }
                }
                //the above operation may change GroupPosition and PhysActor.Postiion
                //as well. so update their values
            }
        }
Example #7
0
        // Constructor used for initializing SyncInfo from remote (OSDMap) data before syncing it locally
        public SyncInfoPrim(UUID id, OSDArray properties, Scene scene)
        {
            UUID = id;
            Scene = scene;

            // Create an SOP based on the set of decoded properties
            // The SOP will be stored internally and someone will add it to the scene later
            SceneThing = new SceneObjectPart();
            ((SceneObjectPart)SceneThing).UUID = UUID;

            //DebugLog.WarnFormat("{0}: Constructing SyncInfoPrim (from map) for uuid {1}", LogHeader, UUID);

            lock (m_syncLock)
            {
                // Decode syncInfoData into CurrentlySyncedProperties
                CurrentlySyncedProperties = new Dictionary<SyncableProperties.Type, SyncedProperty>();
                foreach(OSDArray property in properties)
                {
                    // Parse each property from the key in the map we received
                    SyncedProperty syncedProperty = new SyncedProperty(property);
                    CurrentlySyncedProperties.Add(syncedProperty.Property, syncedProperty);
                    try
                    {
                        SetPropertyValue((SceneObjectPart)SceneThing, syncedProperty);
                    }
                    catch (Exception e)
                    {
                        DebugLog.ErrorFormat("{0}: Error setting SOP property {1}: {2}", LogHeader, property, e.Message);
                    }
                }
            }
        }
Example #8
0
 // When this is called, the SyncInfo should already have a reference to the scene object it will be updating
 public abstract void SetPropertyValue(SyncedProperty syncedProperty);
Example #9
0
        /// <summary>
        /// Set the property's value based on the value maintained in SyncInfoManager.
        /// Assumption: caller will call ScheduleFullUpdate to enqueue updates properly to
        /// update viewers.
        /// This function should only be triggered when a prim update is received (i.e. 
        /// triggered by remote update instead of local update).
        /// </summary>
        /// <param name="part"></param>
        /// <param name="property"></param>
        /// 
        /*
        private void SetPropertyValue(SceneObjectPart part, SyncedProperty syncedProperty)
        {
            //DebugLog.WarnFormat("[SYNC INFO PRIM] SetPropertyValue(part={0}, property={1})", part.UUID, property.ToString());

            if (part == null)
                return;

            SyncableProperties.Type property = syncedProperty.Property;

            // If this is a physical property but the part's PhysActor is null, then we can't set it.
            if (SyncableProperties.PhysActorProperties.Contains(property) && syncedProperty == null && part.PhysActor == null)
            {
                // DebugLog.WarnFormat("{0}: SetPropertyValue: property {1} not in record.", LogHeader, property.ToString());
                //For phantom prims, they don't have physActor properties, so for those properties, simply return
                return;
            }

            if (syncedProperty == null)
            {
                DebugLog.ErrorFormat("{0}: SetPropertyValue: property {1} not in sync cache for uuid {2}. CSP.Count={3} ", LogHeader, property, UUID, CurrentlySyncedProperties.Count);
                return;
            }
            SetPropertyValue(part, property, syncedProperty);
        }
        */
        private void SetPropertyValue(SceneObjectPart part, SyncedProperty pSyncInfo)
        {
            if (part == null || pSyncInfo == null)
                return;

            SyncableProperties.Type property = pSyncInfo.Property;
            Object LastUpdateValue = pSyncInfo.LastUpdateValue;

            // Do not generate undo information for this update
            part.IgnoreUndoUpdate = true;

            switch (property)
            {
                ///////////////////////
                //SOP properties
                ///////////////////////
                case SyncableProperties.Type.AggregateScriptEvents:
                    part.AggregateScriptEvents = (scriptEvents)(int)LastUpdateValue;
                    //DebugLog.DebugFormat("set {0} value to be {1}", property.ToString(), part.AggregateScriptEvents);
                    // Have the part process the new values for collision events.
                    part.SubscribeForCollisionEvents();
                    break;

                case SyncableProperties.Type.AllowedDrop:
                    part.AllowedDrop = (bool)LastUpdateValue;
                    break;

                case SyncableProperties.Type.AngularVelocity:
                    part.AngularVelocity = (Vector3)LastUpdateValue;
                    break;

                case SyncableProperties.Type.AttachedAvatar:
                    //part.AttachedAvatar = (UUID)LastUpdateValue;
                    UUID attachedAvatar = (UUID)LastUpdateValue;
                    if (part.ParentGroup != null && !part.ParentGroup.AttachedAvatar.Equals(attachedAvatar))
                    {
                        part.ParentGroup.AttachedAvatar = attachedAvatar;
                        if (attachedAvatar != UUID.Zero)
                        {
                            ScenePresence avatar = Scene.GetScenePresence(attachedAvatar);
                            //It is possible that the avatar has not been fully
                            //created locally when attachment objects are sync'ed.
                            //So we need to check if the avatar already exists.
                            //If not, handling of NewPresence will evetually trigger
                            //calling of SetParentLocalId.
                            if (avatar != null)
                            {
                                if (part.ParentGroup != null)
                                {
                                    part.ParentGroup.RootPart.SetParentLocalId(avatar.LocalId);
                                }
                                else
                                {
                                    //If this SOP is not a part of group yet, record the
                                    //avatar's localID for now. If this SOP is rootpart of
                                    //the group, then the localID is the right setting;
                                    //otherwise, this SOP will be linked to the SOG it belongs
                                    //to later, and that will rewrite the parent localID.
                                    part.SetParentLocalId(avatar.LocalId);
                                }
                            }
                        }
                        else
                        {
                            part.SetParentLocalId(0);
                        }

                    }
                    break;
                case SyncableProperties.Type.AttachedPos:
                    part.AttachedPos = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.AttachmentPoint:
                    //part.AttachmentPoint = (uint)LastUpdateValue;
                    //part.SetAttachmentPoint((uint)LastUpdateValue);
                    if (part.ParentGroup != null)
                        part.ParentGroup.AttachmentPoint = ((uint)LastUpdateValue);
                    break;
                case SyncableProperties.Type.BaseMask:
                    part.BaseMask = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Category:
                    part.Category = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.ClickAction:
                    part.ClickAction = (byte)LastUpdateValue;
                    break;
                case SyncableProperties.Type.CollisionSound:
                    SetSOPCollisionSound(part, (UUID)LastUpdateValue);
                    break;
                case SyncableProperties.Type.CollisionSoundVolume:
                    part.CollisionSoundVolume = (float)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Color:
                    part.Color = PropertySerializer.DeSerializeColor((string)LastUpdateValue);
                    break;
                case SyncableProperties.Type.CreationDate:
                    part.CreationDate = (int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.CreatorData:
                    part.CreatorData = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.CreatorID:
                    part.CreatorID = (UUID)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Description:
                    part.Description = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.EveryoneMask:
                    part.EveryoneMask = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Flags:
                    SetSOPFlags(part, (PrimFlags)(int)LastUpdateValue);
                    break;
                case SyncableProperties.Type.FolderID:
                    part.FolderID = (UUID)LastUpdateValue;
                    break;
                //Skip SyncableProperties.FullUpdate, which should be handled seperatedly
                case SyncableProperties.Type.GroupID:
                    part.GroupID = (UUID)LastUpdateValue;
                    break;
                case SyncableProperties.Type.GroupMask:
                    part.GroupMask = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.GroupPosition:
                    part.GroupPosition = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.InventorySerial:
                    part.InventorySerial = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.IsAttachment:
                    if (part.ParentGroup != null)
                        part.ParentGroup.IsAttachment = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.LastOwnerID:
                    part.LastOwnerID = (UUID)LastUpdateValue;
                    break;
                case SyncableProperties.Type.LinkNum:
                    part.LinkNum = (int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.LocalFlags:
                    part.LocalFlags = (PrimFlags)(int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.LocalId:
                    part.LocalId = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Material:
                    part.Material = (byte)LastUpdateValue;
                    break;
                case SyncableProperties.Type.MediaUrl:
                    part.MediaUrl = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Name:
                    part.Name = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.NextOwnerMask:
                    part.NextOwnerMask = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.ObjectSaleType:
                    part.ObjectSaleType = (byte)LastUpdateValue;
                    break;
                case SyncableProperties.Type.OffsetPosition:
                    part.OffsetPosition = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.OwnerID:
                    part.OwnerID = (UUID)LastUpdateValue;
                    break;
                case SyncableProperties.Type.OwnerMask:
                    part.OwnerMask = (uint)LastUpdateValue;
                    break;
                case SyncableProperties.Type.OwnershipCost:
                    part.OwnershipCost = (int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.ParticleSystem:
                    //byte[], return a cloned copy
                    //byte[] pValue = (byte[])LastUpdateValue;
                    //part.ParticleSystem = (byte[])pValue.Clone();
                    part.ParticleSystem = (byte[])LastUpdateValue;
                    break;
                case SyncableProperties.Type.PassTouches:
                    part.PassTouches = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.RotationOffset:
                    part.RotationOffset = (Quaternion)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SalePrice:
                    part.SalePrice = (int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Scale:
                    part.Scale = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.ScriptAccessPin:
                    part.ScriptAccessPin = (int)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Shape:
                    PrimitiveBaseShape shapeVal = PropertySerializer.DeSerializeShape((string)LastUpdateValue);
                    // Scale and State are actually synchronized as part properties so existing values
                    // should be preserved when updating a shape
                    if (part.Shape != null)
                    {
                        shapeVal.Scale = part.Shape.Scale;
                        shapeVal.State = part.Shape.State;
                    }
                    part.Shape = shapeVal;
                    break;
                case SyncableProperties.Type.SitName:
                    part.SitName = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SitTargetOrientation:
                    part.SitTargetOrientation = (Quaternion)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SitTargetOrientationLL:
                    part.SitTargetOrientationLL = (Quaternion)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SitTargetPosition:
                    part.SitTargetPosition = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SitTargetPositionLL:
                    part.SitTargetPositionLL = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.SOP_Acceleration:
                    part.Acceleration = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Sound:
                    part.Sound = (UUID)LastUpdateValue;
                    break;
                case SyncableProperties.Type.TaskInventory:
                    TaskInventoryDictionary taskVal = PropertySerializer.DeSerializeTaskInventory((string)LastUpdateValue);
                    if (taskVal != null)
                    {
                        part.TaskInventory = taskVal;
                        //Mark the inventory as has changed, for proper backup
                        part.Inventory.ForceInventoryPersistence();
                    }
                    break;
                case SyncableProperties.Type.Text:
                    part.Text = (string)LastUpdateValue;
                    break;
                case SyncableProperties.Type.TextureAnimation:
                    //byte[], return a cloned copy
                    //byte[] tValue = (byte[])LastUpdateValue;
                    //part.TextureAnimation = (byte[])tValue.Clone();
                    part.TextureAnimation = (byte[])LastUpdateValue;
                    break;
                case SyncableProperties.Type.TouchName:
                    part.TouchName = (string)LastUpdateValue;
                    break;
                /*
                case SyncableProperties.Type.UpdateFlag:
                    part.UpdateFlag = (UpdateRequired)LastUpdateValue;
                    break;
                */
                case SyncableProperties.Type.Velocity:
                    part.Velocity = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.VolumeDetectActive:
                    //part.ParentGroup.UpdatePrimFlagsBySync(part.LocalId, part., IsTemporary, IsPhantom, part.VolumeDetectActive);
                    bool isVD = (bool)LastUpdateValue;
                    //VD DEBUG
                    //DebugLog.DebugFormat("VolumeDetectActive updated on SOP {0}, to {1}", part.Name, isVD);
                    if (part.ParentGroup != null)
                    {
                        //VD DEBUG
                        //DebugLog.DebugFormat("calling ScriptSetVolumeDetectBySync");
                        //DSL part.ParentGroup.ScriptSetVolumeDetectBySync(isVD);
                    }
                    part.VolumeDetectActive = isVD;
                    //DSL part.aggregateScriptEventSubscriptions();
                    break;

                ///////////////////////
                //PhysActor properties
                ///////////////////////
                case SyncableProperties.Type.Buoyancy:
                    if (part.PhysActor != null)
                        part.PhysActor.Buoyancy = (float)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Flying:
                    if (part.PhysActor != null)
                        part.PhysActor.Flying = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Force:
                    if (part.PhysActor != null)
                        part.PhysActor.Force = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.IsColliding:
                    if (part.PhysActor != null)
                        part.PhysActor.IsColliding = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.CollidingGround:
                    if (part.PhysActor != null)
                        part.PhysActor.CollidingGround = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Kinematic:
                    if (part.PhysActor != null)
                        part.PhysActor.Kinematic = (bool)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Orientation:
                    if (part.PhysActor != null)
                        part.PhysActor.Orientation = (Quaternion)LastUpdateValue;
                    break;
                case SyncableProperties.Type.PA_Acceleration:
                    if (part.PhysActor != null)
                        part.PhysActor.Acceleration = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.PA_Velocity:
                    if (part.PhysActor != null)
                        part.PhysActor.Velocity = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.PA_TargetVelocity:
                    if (part.PhysActor != null)
                        part.PhysActor.TargetVelocity = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Position:
                    if (part.PhysActor != null)
                        part.PhysActor.Position = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.RotationalVelocity:
                    if (part.PhysActor != null)
                        part.PhysActor.RotationalVelocity = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Size:
                    if (part.PhysActor != null)
                        part.PhysActor.Size = (Vector3)LastUpdateValue;
                    break;
                case SyncableProperties.Type.Torque:
                    if (part.PhysActor != null)
                        part.PhysActor.Torque = (Vector3)LastUpdateValue;
                    break;

                ///////////////////////
                //SOG properties
                ///////////////////////
                case SyncableProperties.Type.AbsolutePosition:
                    SetSOPAbsolutePosition(part, pSyncInfo);
                    break;
                case SyncableProperties.Type.IsSelected:
                    if (part.ParentGroup != null)
                        part.ParentGroup.IsSelected = (bool)LastUpdateValue;
                    break;
            }

            // Do not generate undo information for this update
            part.IgnoreUndoUpdate = false;

            //Calling ScheduleFullUpdate to trigger enqueuing updates for sync'ing (relay sync nodes need to do so)
            //part.ScheduleFullUpdate(new List<SyncableProperties.Type>() { property });
        }
 public override void SetPropertyValue(SyncedProperty syncedPropertyValue)
 {
     ScenePresence sp = (ScenePresence)SceneThing;
     SetPropertyValue(sp, syncedPropertyValue);
 }
        // Constructor used for initializing SyncInfo from remote (OSDMap) data before syncing it locally
        /// <param name="id">UUID of the scene presence</param>
        /// <param name="syncInfoData">Initial sync data</param>
        /// <param name="scene">The local scene</param>
        public SyncInfoPresence(UUID id, OSDArray properties, Scene scene)
        {
            // DebugLog.WarnFormat("[SYNC INFO PRESENCE] Constructing SyncInfoPresence (from map) for uuid {0}", id);

            UUID = id;
            Scene = scene;

            lock (m_syncLock)
            {
                // Decode syncInfoData into CurrentlySyncedProperties
                CurrentlySyncedProperties = new Dictionary<SyncableProperties.Type, SyncedProperty>();
                foreach (OSD property in properties)
                {
                    // Parse each property from the key in the map we received
                    SyncedProperty syncedProperty = new SyncedProperty((OSDArray)property);
                    CurrentlySyncedProperties.Add(syncedProperty.Property, syncedProperty);
                }
            }
        }
Example #12
0
        /// <summary>
        /// Compare the local timestamp with that in pSyncInfo. If the one in
        /// pSyncInfo is newer, copy its members to the local record.
        /// </summary>
        /// <param name="pSyncInfo"></param>
        /// <returns>'true' if the received sync value was accepted and the sync cache was updated with the received value</returns>
        public bool CompareAndUpdateSyncInfoBySync(SyncedProperty pSyncInfo, long recvTS)
        {
            // KLUDGE!!! THIS TRIES TO FORCE THE SCRIPT SETTING OF ANIMATIONS VS DEFAULT ANIMATIONS.
            // Unconditionally accept an animation update if the received update has extended animations
            //     and the existing animation is a default animation. This case is most often
            //     from a script setting a sit or animation override.
            if (RegionSyncModule.ShouldUnconditionallyAcceptAnimationOverrides && Property == SyncableProperties.Type.Animations)
            {
                OSDArray receivedAnimations = pSyncInfo.LastUpdateValue as OSDArray;
                OSDArray existingAnimations = LastUpdateValue as OSDArray;
                if (receivedAnimations != null && existingAnimations != null)
                {
                    /*
                    // If going from default animation to something better, always accept it
                    if (receivedAnimations.Count > 2 && existingAnimations.Count <= 2)
                    {
                        // The new animation has more info than the existing so accept it.
                        // DebugLog.DebugFormat("{0} SyncedProperty.CompareAndUpdateSyncInfoBySync: forcing. receivedCnt={1}, existingCnt={2}",    // DEBUG DEBUG
                        //         "[DSG SYNCED PROPERTY]", receivedAnimations.Count, existingAnimations.Count);    // DEBUG DEBUG
                        UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                        return true;
                    }
                    */
                    // For the moment, just accept received animations
                    UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                    return true;
                }
            }

            // If update timestamp is later, or we do some tie breaking, then update
            if ((pSyncInfo.LastUpdateTimeStamp > LastUpdateTimeStamp) ||
                ((pSyncInfo.LastUpdateTimeStamp == LastUpdateTimeStamp) &&
                 (!LastUpdateSyncID.Equals(pSyncInfo.LastUpdateSyncID)) &&
                 (SyncIDTieBreak(LastUpdateSyncID, pSyncInfo.LastUpdateSyncID).Equals(pSyncInfo.LastUpdateSyncID))))
            {
                UpdateSyncInfoBySync(pSyncInfo.LastUpdateTimeStamp, pSyncInfo.LastUpdateSyncID, pSyncInfo.LastUpdateValue, recvTS);
                return true;
            }
            return false;
        }
Example #13
0
        private void SetPropertyValue(ScenePresence sp, SyncableProperties.Type property, SyncedProperty pSyncInfo)
        {
            if (sp == null || pSyncInfo == null)
            {
                return;
            }

            Object pValue = pSyncInfo.LastUpdateValue;

            switch (property)
            {
            case SyncableProperties.Type.LocalId:
                sp.LocalId = (uint)pValue;
                break;

            case SyncableProperties.Type.AbsolutePosition:
                sp.AbsolutePosition = (Vector3)pValue;
                break;

            case SyncableProperties.Type.AgentCircuitData:
                DebugLog.WarnFormat("{0}: Received updated AgentCircuitData. Not implemented", LogHeader);
                break;

            case SyncableProperties.Type.ParentId:
                uint localID = (uint)pValue;
                if (localID == 0)
                {
                    // DebugLog.DebugFormat("{0}: SetPropertyValue:ParentID. Standup. Input={1}", LogHeader, localID); // DEBUG DEBUG
                    sp.StandUp();
                }
                else
                {
                    SceneObjectPart parentPart = Scene.GetSceneObjectPart(localID);
                    if (parentPart != null)     // TODO ??
                    {
                        sp.HandleAgentRequestSit(sp.ControllingClient, sp.ControllingClient.AgentId, parentPart.UUID, Vector3.Zero);
                        // DebugLog.DebugFormat("{0}: SetPropertyValue:ParentID. SitRequest. Input={1},sp={2},newParentID={3}",
                        //                 LogHeader, localID, (string)(sp == null ? "NULL" : sp.Name), sp.ParentID); // DEBUG DEBUG
                    }
                }
                //sp.ParentID = (uint)pValue;
                break;

            case SyncableProperties.Type.AgentControlFlags:
                sp.AgentControlFlags = (uint)pValue;
                break;

            case SyncableProperties.Type.AllowMovement:
                sp.AllowMovement = (bool)pValue;
                break;

            case SyncableProperties.Type.AvatarAppearance:
                sp.Appearance.Unpack((OSDMap)pValue);
                sp.SendAppearanceToAllOtherAgents();
                DebugLog.DebugFormat("{0} Received updated AvatarAppearance for uuid {1}.", LogHeader, sp.UUID);
                break;

            case SyncableProperties.Type.Animations:
                UpdateAvatarAnimations(sp, (OSDArray)pValue);
                break;

            case SyncableProperties.Type.Rotation:
                sp.Rotation = (Quaternion)pValue;
                break;

            case SyncableProperties.Type.PA_Velocity:
                if (sp.PhysicsActor != null)
                {
                    sp.PhysicsActor.Velocity = (Vector3)pValue;
                }
                break;

            case SyncableProperties.Type.RealRegion:
                ////// NOP //////
                break;

            case SyncableProperties.Type.PA_TargetVelocity:
                if (sp.PhysicsActor != null)
                {
                    sp.PhysicsActor.TargetVelocity = (Vector3)pValue;
                }
                break;

            case SyncableProperties.Type.Flying:
                sp.Flying = (bool)pValue;
                break;

            case SyncableProperties.Type.PresenceType:
                DebugLog.WarnFormat("{0} Received updated PresenceType for uuid {1}. Not implemented", LogHeader, sp.UUID);
                break;

            case SyncableProperties.Type.IsColliding:
                if (sp.PhysicsActor != null)
                {
                    sp.IsColliding = (bool)pValue;
                }
                break;
            }

            // When presence values are changed, we tell the simulator with an event
            GenerateAgentUpdated(sp);
        }
Example #14
0
        /// <summary>
        /// Compare the value (not "reference") of the given property. 
        /// Assumption: the caller has already checked if PhysActor exists
        /// if there are physics properties updated.
        /// If the value maintained here is different from that in SOP data,
        /// synchronize the two: 
        /// (1) if the value here has a timestamp newer than lastUpdateByLocalTS 
        /// (e.g. due to clock drifts among different sync nodes, a remote
        /// write might have a newer timestamp than the local write), 
        /// overwrite the SOP's property with the value here (effectively 
        /// disvalidate the local write operation that just happened). 
        /// (2) otherwise, copy SOP's data and update timestamp and syncID 
        /// as indicated by "lastUpdateByLocalTS" and "syncID".
        /// </summary>
        /// <param name="part"></param>
        /// <param name="property"></param>
        /// <param name="lastUpdateByLocalTS"></param>
        /// <param name="syncID"></param>
        /// <returns>Return true if the property's value maintained in this SyncInfoPrim is replaced by SOP's data.</returns>
        private bool CompareValue_UpdateByLocal(SceneObjectPart part, SyncableProperties.Type property, long lastUpdateByLocalTS, string syncID, out bool resetSceneValue)
        {
            resetSceneValue = false;

            //DebugLog.WarnFormat("[SYNC INFO PRIM] CompareValue_UpdateByLocal: Updating property {0} on part {1}", property.ToString(), part.UUID);

            SyncedProperty syncedProperty;
            CurrentlySyncedProperties.TryGetValue(property, out syncedProperty);

            // If the property does not exist yet then add it.
            if (syncedProperty == null)
            {
                Object initValue = GetPropertyValue(part, property);
                SyncedProperty syncInfo = new SyncedProperty(property, initValue, lastUpdateByLocalTS, syncID);
                CurrentlySyncedProperties.Add(property, syncInfo);
                return true;
            }

            // First, check if the value maintained here is different from that in SOP's.
            // If different, next check if the timestamp in SyncInfo is newer than lastUpdateByLocalTS;
            // if so (although ideally should not happen, but due to things likc clock not so perfectly
            // sync'ed, it might happen), overwrite SOP's value with what's maintained
            // in SyncInfo; otherwise, copy SOP's data to SyncInfo.

            switch (property)
            {
                case SyncableProperties.Type.GroupPosition:
                    return CompareAndUpdateSOPGroupPositionByLocal(part, lastUpdateByLocalTS, syncID);

                default:
                    Object value = GetPropertyValue(part, property);

                    // If both null, no update needed
                    if (syncedProperty.LastUpdateValue == null && value == null)
                        return false;

                    // If one is null and the other is not, or if they are not equal, the property was changed.
                    if ((value == null && syncedProperty.LastUpdateValue != null) ||
                        (value != null && syncedProperty.LastUpdateValue == null) ||
                        (!value.Equals(syncedProperty.LastUpdateValue)))
                    {
                        if (value != null)
                        {
                            switch (property)
                            {
                                case SyncableProperties.Type.Velocity:
                                case SyncableProperties.Type.PA_Velocity:
                                case SyncableProperties.Type.PA_TargetVelocity:
                                case SyncableProperties.Type.RotationalVelocity:
                                case SyncableProperties.Type.AngularVelocity:
                                    {
                                        Vector3 partVal = (Vector3)value;
                                        Vector3 lastVal = (Vector3)syncedProperty.LastUpdateValue;
                                        // If velocity difference is small but not zero, don't update
                                        if (partVal.ApproxEquals(lastVal, VELOCITY_TOLERANCE) && !partVal.Equals(Vector3.Zero))
                                            return false;
                                        break;
                                    }
                                case SyncableProperties.Type.RotationOffset:
                                case SyncableProperties.Type.Orientation:
                                    {
                                        Quaternion partVal = (Quaternion)value;
                                        Quaternion lastVal = (Quaternion)syncedProperty.LastUpdateValue;
                                        if (partVal.ApproxEquals(lastVal, ROTATION_TOLERANCE))
                                            return false;
                                        break;
                                    }
                                case SyncableProperties.Type.OffsetPosition:
                                case SyncableProperties.Type.AbsolutePosition:
                                case SyncableProperties.Type.Position:
                                case SyncableProperties.Type.GroupPosition:
                                    {
                                        Vector3 partVal = (Vector3)value;
                                        Vector3 lastVal = (Vector3)syncedProperty.LastUpdateValue;
                                        if (partVal.ApproxEquals(lastVal, POSITION_TOLERANCE))
                                            return false;
                                        break;
                                    }
                            }
                        }
                        if (property == SyncableProperties.Type.Shape)
                        {
                            //DebugLog.WarnFormat("[SYNC INFO PRIM]: SHAPES DIFFER {0} {1}", (string)value, (string)syncedProperty.LastUpdateValue);
                        }
                        // DebugLog.WarnFormat("[SYNC INFO PRIM] CompareValue_UpdateByLocal (property={0}): value != syncedProperty.LastUpdateValue", property.ToString());
                        if (lastUpdateByLocalTS >= syncedProperty.LastUpdateTimeStamp)
                        {
                            // DebugLog.WarnFormat("[SYNC INFO PRIM] CompareValue_UpdateByLocal (property={0}): TS >= lastTS (updating SyncInfo)", property.ToString());
                            syncedProperty.UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, value);

                            // Updating either absolute position or position also requires checking for updates to group position
                            if (property == SyncableProperties.Type.AbsolutePosition || property == SyncableProperties.Type.Position)
                            {
                                CompareValue_UpdateByLocal(part, SyncableProperties.Type.GroupPosition, lastUpdateByLocalTS, syncID, out resetSceneValue);
                                resetSceneValue = false;
                            }

                            return true;
                        }
                        // DebugLog.WarnFormat("[SYNC INFO PRIM] CompareValue_UpdateByLocal (property={0}): TS < lastTS (updating SOP)", property.ToString());

                        //We'll reset the property value outside of CompareValue_UpdateByLocal
                        //SetPropertyValue(property);
                        resetSceneValue = true;
                    }
                    break;
            }
            return false;
        }
        /// <summary>
        /// This function should only be triggered when an update update is received (i.e. 
        /// triggered by remote update instead of local update).
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="property"></param>
        private void SetPropertyValue(ScenePresence sp, SyncedProperty syncedProperty)
        {
            if (sp == null) return;

            SyncableProperties.Type property = syncedProperty.Property;

            if (syncedProperty == null)
            {
                DebugLog.ErrorFormat("{0}: SetPropertyValue: property {1} not in sync cache for uuid {2}. ", LogHeader, property, UUID);
                return;
            }

            SetPropertyValue(sp, property, syncedProperty);
        }
Example #16
0
        // Constructor used for initializing SyncInfo from local (SceneObjectPart) data before syncing it out
        /// <param name="sop">Part to use for initial synced property values</param>
        /// <param name="initUpdateTimestamp">Initial update timestamp</param>
        /// <param name="syncID"></param>
        /// <param name="scene"></param>
        public SyncInfoPrim(SceneObjectPart sop, long initUpdateTimestamp, string syncID, Scene scene)
        {
            UUID = sop.UUID;
            Scene = scene;
            SceneThing = sop;

            //DebugLog.WarnFormat("{0}: Constructing SyncInfoPrim (from scene) for uuid {1}", LogHeader, UUID);

            // If the part does not have a PhysActor then don't store physical property initial values
            HashSet<SyncableProperties.Type> initialProperties = sop.PhysActor == null ?
                new HashSet<SyncableProperties.Type>(SyncableProperties.NonPhysActorProperties) :
                new HashSet<SyncableProperties.Type>(SyncableProperties.FullUpdateProperties);
            lock (m_syncLock)
            {
                CurrentlySyncedProperties = new Dictionary<SyncableProperties.Type, SyncedProperty>();
                foreach (SyncableProperties.Type property in initialProperties)
                {
                    Object initValue = GetPropertyValue(sop, property);
                    SyncedProperty syncInfo = new SyncedProperty(property, initValue, initUpdateTimestamp, syncID);
                    CurrentlySyncedProperties.Add(property, syncInfo);
                }
            }
        }
        private void SetPropertyValue(ScenePresence sp, SyncableProperties.Type property, SyncedProperty pSyncInfo)
        {
            if (sp == null || pSyncInfo == null) return;

            Object pValue = pSyncInfo.LastUpdateValue;
            switch (property)
            {
                case SyncableProperties.Type.LocalId:
                    sp.LocalId = (uint)pValue;
                    break;
                case SyncableProperties.Type.AbsolutePosition:
                    sp.AbsolutePosition = (Vector3)pValue;
                    break;
                case SyncableProperties.Type.AgentCircuitData:
                    DebugLog.WarnFormat("{0}: Received updated AgentCircuitData. Not implemented", LogHeader);
                    break;
                case SyncableProperties.Type.ParentId:
                    uint localID = (uint)pValue;
                    if (localID == 0)
                    {
                        // DebugLog.DebugFormat("{0}: SetPropertyValue:ParentID. Standup. Input={1}", LogHeader, localID); // DEBUG DEBUG
                        sp.StandUp();
                    }
                    else
                    {
                        SceneObjectPart parentPart = Scene.GetSceneObjectPart(localID);
                        if (parentPart != null) // TODO ??
                        {
                            sp.HandleAgentRequestSit(sp.ControllingClient, sp.ControllingClient.AgentId, parentPart.UUID, Vector3.Zero);
                            // DebugLog.DebugFormat("{0}: SetPropertyValue:ParentID. SitRequest. Input={1},sp={2},newParentID={3}",
                            //                 LogHeader, localID, (string)(sp == null ? "NULL" : sp.Name), sp.ParentID); // DEBUG DEBUG
                        }
                    }
                    //sp.ParentID = (uint)pValue;
                    break;
                case SyncableProperties.Type.AgentControlFlags:
                    sp.AgentControlFlags = (uint)pValue;
                    break;
                case SyncableProperties.Type.AllowMovement:
                    sp.AllowMovement = (bool)pValue;
                    break;
                case SyncableProperties.Type.AvatarAppearance:
                    sp.Appearance.Unpack((OSDMap)pValue);
                    sp.SendAppearanceToAllOtherAgents();
                    DebugLog.DebugFormat("{0} Received updated AvatarAppearance for uuid {1}.", LogHeader, sp.UUID);
                    break;
                case SyncableProperties.Type.Animations:
                    UpdateAvatarAnimations(sp, (OSDArray)pValue);
                    break;
                case SyncableProperties.Type.Rotation:
                    sp.Rotation = (Quaternion)pValue;
                    break;
                case SyncableProperties.Type.PA_Velocity:
                    if (sp.PhysicsActor != null)
                        sp.PhysicsActor.Velocity = (Vector3)pValue;
                    break;
                case SyncableProperties.Type.RealRegion:
                    ////// NOP //////
                    break;
                case SyncableProperties.Type.PA_TargetVelocity:
                    if(sp.PhysicsActor != null)
                        sp.PhysicsActor.TargetVelocity = (Vector3)pValue;
                     break;
                case SyncableProperties.Type.Flying:
                    sp.Flying = (bool)pValue;
                    break;
                case SyncableProperties.Type.PresenceType:
                    DebugLog.WarnFormat("{0} Received updated PresenceType for uuid {1}. Not implemented", LogHeader, sp.UUID);
                    break;
                case SyncableProperties.Type.IsColliding:
                    if(sp.PhysicsActor != null)
                        sp.IsColliding = (bool)pValue;
                    break;
            }

            // When presence values are changed, we tell the simulator with an event
            GenerateAgentUpdated(sp);
        }
Example #18
0
 // When this is called, the SyncInfo should already have a reference to the scene object it will be updating
 public abstract void SetPropertyValue(SyncedProperty syncedProperty);
Example #19
0
        public override void SetPropertyValue(SyncedProperty syncedPropertyValue)
        {
            ScenePresence sp = (ScenePresence)SceneThing;

            SetPropertyValue(sp, syncedPropertyValue);
        }