예제 #1
0
        private Packet mProxy_ImprovedTerseObjectUpdatePacketReceived(Packet p, IPEndPoint ep)
        {
            if (mLocalID != 0 && mProxy != null)
            {
                mProxy.RemoveDelegate(PacketType.ObjectUpdate, Direction.Incoming, mObjectUpdateListener);
            }

            ImprovedTerseObjectUpdatePacket packet = p as ImprovedTerseObjectUpdatePacket;

            /*foreach (var block in packet.ObjectData) {
             *  uint localid = Utils.BytesToUInt(block.Data, 0);
             *
             *  if (block.Data[0x5] != 0 && localid == mLocalID) {
             *      mAvatarPosition = new Vector3(block.Data, 0x16);
             *      mPositionOffset = mAvatarPosition - mFrame.Core.Position;
             *      Quaternion rotation = Quaternion.Identity;
             *
             *      // Rotation (theta)
             *      rotation = new Quaternion(
             *          Utils.UInt16ToFloat(block.Data, 0x2E, -1.0f, 1.0f),
             *          Utils.UInt16ToFloat(block.Data, 0x2E + 2, -1.0f, 1.0f),
             *          Utils.UInt16ToFloat(block.Data, 0x2E + 4, -1.0f, 1.0f),
             *          Utils.UInt16ToFloat(block.Data, 0x2E + 6, -1.0f, 1.0f));
             *
             *      mAvatarOrientation = new Rotation(rotation);
             *      //mAvatarOrientation = Frame.Core.Orientation;
             *  }
             * }*/
            objectUpdatePacketQueue.Add(packet);

            return(p);
        }
예제 #2
0
        /// <summary>
        /// Return a packet to the packet pool
        /// </summary>
        /// <param name="packet"></param>
        public void ReturnPacket(Packet packet)
        {
            if (dataBlockPoolEnabled)
            {
                switch (packet.Type)
                {
                case PacketType.ObjectUpdate:
                    ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;

                    foreach (ObjectUpdatePacket.ObjectDataBlock oupod in
                             oup.ObjectData)
                    {
                        ReturnDataBlock <ObjectUpdatePacket.ObjectDataBlock>(oupod);
                    }
                    oup.ObjectData = null;
                    break;

                case PacketType.ImprovedTerseObjectUpdate:
                    ImprovedTerseObjectUpdatePacket itoup =
                        (ImprovedTerseObjectUpdatePacket)packet;

                    foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock
                             itoupod in itoup.ObjectData)
                    {
                        ReturnDataBlock <ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
                    }
                    itoup.ObjectData = null;
                    break;
                }
            }

            if (packetPoolEnabled)
            {
                switch (packet.Type)
                {
                // List pooling packets here
                case PacketType.PacketAck:
                case PacketType.ObjectUpdate:
                case PacketType.ImprovedTerseObjectUpdate:
                    lock (pool)
                    {
                        PacketType type = packet.Type;

                        if (!pool.ContainsKey(type))
                        {
                            pool[type] = new Stack <Packet>();
                        }
                        if ((pool[type]).Count < 50)
                        {
                            (pool[type]).Push(packet);
                        }
                    }
                    break;

                // Other packets wont pool
                default:
                    return;
                }
            }
        }
예제 #3
0
파일: AvatarInfo.cs 프로젝트: zadark/par
        private Packet InImprovedTerseObjectUpdateHandler(Packet packet, IPEndPoint sim)
        {
            string simIP = sim.ToString();

            // If the sim doesn't exist, add it
            if (!SharedInfo.Aux_Simulators.ContainsKey(simIP))
            {
                SharedInfo.Aux_Simulators.Add(simIP, new PubComb.Aux_Simulator(simIP));
            }

            ImprovedTerseObjectUpdatePacket update = (ImprovedTerseObjectUpdatePacket)packet;

            foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
            {
                // Is it an avatar?
                if (block.Data[5] != 0)
                {
                    uint localid = Utils.BytesToUInt(block.Data, 0);
                    PubComb.Aux_Avatar avatar = SharedInfo.Aux_Simulators[simIP].AvatarByLocalID(localid);
                    if (avatar != null)
                    {
                        // update position
                        avatar.Position = new Vector3(block.Data, 22);
                        SharedInfo.Aux_Simulators[simIP].Avatars[avatar.UUID].Position = avatar.Position;
                        if (avatar.UUID == frame.AgentID)
                        {
                            SharedInfo.AvPosition = avatar.Position;
                        }
                        form.UpdateAvatar(avatar);
                    }
                }
            }

            return(packet);
        }
예제 #4
0
        /// <summary>
        /// Return a packet to the packet pool
        /// </summary>
        /// <param name="packet"></param>
        public void ReturnPacket(Packet packet)
        {
            if (!RecyclePackets)
            {
                return;
            }

            bool       trypool = false;
            PacketType type    = packet.Type;

            switch (type)
            {
            case PacketType.ObjectUpdate:
                ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
                oup.ObjectData = null;
                trypool        = true;
                break;

            case PacketType.ImprovedTerseObjectUpdate:
                ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
                itoup.ObjectData = null;
                trypool          = true;
                break;

            case PacketType.PacketAck:
                PacketAckPacket ackup = (PacketAckPacket)packet;
                ackup.Packets = null;
                trypool       = true;
                break;

            case PacketType.AgentUpdate:
                trypool = true;
                break;

            default:
                return;
            }

            if (!trypool)
            {
                return;
            }

            lock (pool)
            {
                if (!pool.ContainsKey(type))
                {
                    pool[type] = new Stack <Packet>();
                }

                if ((pool[type]).Count < 50)
                {
//                  m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
                    pool[type].Push(packet);
                }
            }
        }
예제 #5
0
        public override void update()
        {
            LLVector3 pos2 = new LLVector3(0, 0, 0);

            if (this._physActor != null && this.physicsEnabled)
            {
                PhysicsVector pPos = this._physActor.Position;
                pos2 = new LLVector3(pPos.X, pPos.Y, pPos.Z);
            }
            if (this.newPrimFlag)
            {
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(OurPacket);
                }
                this.newPrimFlag = false;
            }
            else if (this.updateFlag)
            {
                ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                terse.RegionData.TimeDilation = 64096;
                terse.ObjectData    = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                terse.ObjectData[0] = this.CreateImprovedBlock();
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(terse);
                }
                this.updateFlag = false;
            }
            else if (this.dirtyFlag)
            {
                foreach (SimClient client in m_clientThreads.Values)
                {
                    UpdateClient(client);
                }
                this.dirtyFlag = false;
            }
            else
            {
                if (this._physActor != null && this.physicsEnabled)
                {
                    if (pos2 != this.positionLastFrame)
                    {
                        ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                        terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                        terse.RegionData.TimeDilation = 64096;
                        terse.ObjectData    = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                        terse.ObjectData[0] = this.CreateImprovedBlock();
                        foreach (SimClient client in m_clientThreads.Values)
                        {
                            client.OutPacket(terse);
                        }
                    }
                    this.positionLastFrame = pos2;
                }
            }

            if (this.physicstest)
            {
                LLVector3 pos = this.Pos;
                pos.Z += 0.0001f;
                this.UpdatePosition(pos);
                this.physicstest = false;
            }
        }
예제 #6
0
        /// <summary>
        /// Return a packet to the packet pool
        /// </summary>
        /// <param name="packet"></param>
        public void ReturnPacket(Packet packet)
        {
            if (RecycleDataBlocks)
            {
                switch (packet.Type)
                {
                case PacketType.ObjectUpdate:
                    ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;

                    foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
                    {
                        ReturnDataBlock <ObjectUpdatePacket.ObjectDataBlock>(oupod);
                    }

                    oup.ObjectData = null;
                    break;

                case PacketType.ImprovedTerseObjectUpdate:
                    ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;

                    foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
                    {
                        ReturnDataBlock <ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
                    }

                    itoup.ObjectData = null;
                    break;
                }
            }

            if (RecyclePackets)
            {
                switch (packet.Type)
                {
                // List pooling packets here
                case PacketType.AgentUpdate:
                case PacketType.PacketAck:
                case PacketType.ObjectUpdate:
                case PacketType.ImprovedTerseObjectUpdate:
                    lock (pool)
                    {
                        PacketType type = packet.Type;

                        if (!pool.ContainsKey(type))
                        {
                            pool[type] = new Stack <Packet>();
                        }

                        if ((pool[type]).Count < 50)
                        {
//                                m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);

                            pool[type].Push(packet);
                        }
                    }
                    break;

                // Other packets wont pool
                default:
                    return;
                }
            }
        }
예제 #7
0
        private void TerseUpdateHandler(Packet packet, Simulator simulator)
        {
            float        x, y, z, w;
            uint         localid;
            LLVector4    CollisionPlane = null;
            LLVector3    Position;
            LLVector3    Velocity;
            LLVector3    Acceleration;
            LLQuaternion Rotation;
            LLVector3    RotationVelocity;

            ImprovedTerseObjectUpdatePacket update = (ImprovedTerseObjectUpdatePacket)packet;

            foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
            {
                int  i = 0;
                bool avatar;

                localid = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                                 (block.Data[i++] << 16) + (block.Data[i++] << 24));

                byte state = block.Data[i++];

                avatar = Convert.ToBoolean(block.Data[i++]);

                if (avatar)
                {
                    if (OnAvatarMoved == null)
                    {
                        return;
                    }

                    CollisionPlane = new LLVector4(block.Data, i);
                    i += 16;
                }
                else
                {
                    if (OnPrimMoved == null)
                    {
                        return;
                    }
                }

                // Position
                Position = new LLVector3(block.Data, i);
                i       += 12;
                // Velocity
                x        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                y        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                z        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                Velocity = new LLVector3(x, y, z);
                // Acceleration
                x            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                y            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                z            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                Acceleration = new LLVector3(x, y, z);
                // Rotation
                x        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                y        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                z        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                w        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                Rotation = new LLQuaternion(x, y, z, w);
                // Rotation velocity
                x  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                y  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                z  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                RotationVelocity = new LLVector3(x, y, z);

                if (avatar)
                {
                    if (localid == Client.Self.LocalID)
                    {
                        Client.Self.Position = Position;
                        Client.Self.Rotation = Rotation;
                    }

                    AvatarUpdate avupdate = new AvatarUpdate();
                    avupdate.LocalID          = localid;
                    avupdate.State            = state;
                    avupdate.Position         = Position;
                    avupdate.CollisionPlane   = CollisionPlane;
                    avupdate.Velocity         = Velocity;
                    avupdate.Acceleration     = Acceleration;
                    avupdate.Rotation         = Rotation;
                    avupdate.RotationVelocity = RotationVelocity;

                    if (OnAvatarMoved != null)
                    {
                        OnAvatarMoved(simulator, avupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
                else
                {
                    // TODO: Is there an easy way to distinguish prims from trees in this packet,
                    // or would the client have to do it's own lookup to determine whether it's a
                    // prim or a tree? If the latter, we should rename this update to something
                    // less prim specific

                    PrimUpdate primupdate = new PrimUpdate();
                    primupdate.LocalID          = localid;
                    primupdate.State            = state;
                    primupdate.Position         = Position;
                    primupdate.Velocity         = Velocity;
                    primupdate.Acceleration     = Acceleration;
                    primupdate.Rotation         = Rotation;
                    primupdate.RotationVelocity = RotationVelocity;

                    if (OnPrimMoved != null)
                    {
                        OnPrimMoved(simulator, primupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
            }
        }
예제 #8
0
 public void AddTerseUpdateToViewersList(ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock)
 {
 }
예제 #9
0
        public override void update()
        {
            if (this._physActor == null)
            {
                //HACKHACK: Note to work out why this entity does not have a physics actor
                //          and prehaps create one.
                return;
            }
            libsecondlife.LLVector3 pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
            if (this.updateflag)
            {
                //need to send movement info
                //so create the improvedterseobjectupdate packet
                //use CreateTerseBlock()
                ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
                ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                terse.RegionData.TimeDilation = 64096;
                terse.ObjectData    = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                terse.ObjectData[0] = terseBlock;
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(terse);
                }

                updateflag = false;
                //this._updateCount = 0;
            }
            else
            {
                if ((pos2 != this.positionLastFrame) || (this.movementflag == 16))
                {
                    _updateCount++;
                    if (((!PhysicsEngineFlying) && (_updateCount > 3)) || (PhysicsEngineFlying) && (_updateCount > 0))
                    {
                        //It has been a while since last update was sent so lets send one.
                        ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
                        ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                        terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                        terse.RegionData.TimeDilation = 64096;
                        terse.ObjectData    = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                        terse.ObjectData[0] = terseBlock;
                        foreach (SimClient client in m_clientThreads.Values)
                        {
                            client.OutPacket(terse);
                        }
                        _updateCount = 0;
                    }

                    if (this.movementflag == 16)
                    {
                        movementflag = 0;
                    }
                }
            }
            this.positionLastFrame = pos2;

            if (!this.ControllingClient.m_sandboxMode)
            {
                if (pos2.X < 0)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.Y < 0)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.X > 255)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.Y > 255)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }
            }
        }
예제 #10
0
        private void SendEntityPackets(QueuedInterestListEvent[] eventDatas, IScenePresence presence)
        {
            if (!(presence is LLAgent) || presence.InterestList == null)
                return;
            LLAgent agent = (LLAgent)presence;

            Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
            Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
            Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();

            for (int i = 0; i < eventDatas.Length; i++)
            {
                EntityAddOrUpdateArgs e = (EntityAddOrUpdateArgs)eventDatas[i].Event.State;
                ISceneEntity entity = e.Entity;

                #region UpdateFlags to packet type conversion

                UpdateFlags updateFlags = e.UpdateFlags;
                LLUpdateFlags llUpdateFlags = (LLUpdateFlags)e.ExtraFlags;

                bool canUseImproved = true;

                if (updateFlags.HasFlag(UpdateFlags.FullUpdate) ||
                    updateFlags.HasFlag(UpdateFlags.Parent) ||
                    updateFlags.HasFlag(UpdateFlags.Scale) ||
                    updateFlags.HasFlag(UpdateFlags.Shape) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.PrimFlags) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Text) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.NameValue) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.ExtraData) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.TextureAnim) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Sound) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Particles) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Material) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.ClickAction) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.MediaURL) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Joint))
                {
                    canUseImproved = false;
                }

                #endregion UpdateFlags to packet type conversion

                #region Block Construction

                if (!canUseImproved)
                {
                    if (entity is IScenePresence)
                        objectUpdateBlocks.Value.Add(CreateAvatarObjectUpdateBlock((IScenePresence)entity, presence));
                    else
                        objectUpdateBlocks.Value.Add(CreateObjectUpdateBlock(entity, presence));
                }
                else
                {
                    terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, llUpdateFlags.HasFlag(LLUpdateFlags.Textures)));
                }

                #endregion Block Construction

                // Unset CreateSelected after it has been sent once
                if (entity is LLPrimitive)
                {
                    LLPrimitive prim = (LLPrimitive)entity;
                    prim.Prim.Flags &= ~PrimFlags.CreateSelected;
                }
            }

            #region Packet Sending

            ushort timeDilation = (m_physics != null) ?
                Utils.FloatToUInt16(m_physics.TimeDilation, 0.0f, 1.0f) :
                UInt16.MaxValue;

            if (objectUpdateBlocks.IsValueCreated)
            {
                List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;

                ObjectUpdatePacket packet = new ObjectUpdatePacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            if (compressedUpdateBlocks.IsValueCreated)
            {
                List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;

                ObjectUpdateCompressedPacket packet = new ObjectUpdateCompressedPacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            if (terseUpdateBlocks.IsValueCreated)
            {
                List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;

                ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            #endregion Packet Sending
        }
예제 #11
0
파일: CliInt.cs 프로젝트: zadark/par
        /// <summary>
        /// A terse object update, used when a transformation matrix or
        /// velocity/acceleration for an object changes but nothing else
        /// (scale/position/rotation/acceleration/velocity). (From OpenMetaverse, with edits)
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="simulator"></param>
        private Packet TerseUpdateHandler(Packet packet, IPEndPoint simulator)
        {
            ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)packet;

            //UpdateDilation(simulator, terse.RegionData.TimeDilation);

            for (int i = 0; i < terse.ObjectData.Length; i++)
            {
                ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = terse.ObjectData[i];

                try
                {
                    int  pos     = 4;
                    uint localid = Utils.BytesToUInt(block.Data, 0);

                    // Check if we are interested in this update
                    //if (!Client.Settings.ALWAYS_DECODE_OBJECTS && localid != Client.Self.localID && OnObjectUpdated == null)
                    //continue;

                    #region Decode update data

                    ObjectUpdate update = new ObjectUpdate();

                    // LocalID
                    update.LocalID = localid;
                    // State
                    update.State = block.Data[pos++];
                    // Avatar boolean
                    update.Avatar = (block.Data[pos++] != 0);
                    // Collision normal for avatar
                    if (update.Avatar)
                    {
                        update.CollisionPlane = new Vector4(block.Data, pos);
                        pos += 16;
                    }
                    // Position
                    update.Position = new Vector3(block.Data, pos);
                    pos            += 12;
                    // Velocity
                    update.Velocity = new Vector3(
                        Utils.UInt16ToFloat(block.Data, pos, -128.0f, 128.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 2, -128.0f, 128.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 4, -128.0f, 128.0f));
                    pos += 6;
                    // Acceleration
                    update.Acceleration = new Vector3(
                        Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f));
                    pos += 6;
                    // Rotation (theta)
                    update.Rotation = new Quaternion(
                        Utils.UInt16ToFloat(block.Data, pos, -1.0f, 1.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 2, -1.0f, 1.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 4, -1.0f, 1.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 6, -1.0f, 1.0f));
                    pos += 8;
                    // Angular velocity
                    update.AngularVelocity = new Vector3(
                        Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f),
                        Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f));
                    pos += 6;

                    // Textures
                    // FIXME: Why are we ignoring the first four bytes here?
                    if (block.TextureEntry.Length != 0)
                    {
                        update.Textures = new Primitive.TextureEntry(block.TextureEntry, 4, block.TextureEntry.Length - 4);
                    }

                    #endregion Decode update data

                    //Primitive obj = (update.Avatar) ?
                    //(Primitive)GetAvatar(simulator, update.LocalID, UUID.Zero) :
                    //(Primitive)GetPrimitive(simulator, update.LocalID, UUID.Zero);

                    #region Update Client.Self

                    /*
                     * if (update.LocalID == Client.Self.localID)
                     * {
                     *  Client.Self.collisionPlane = update.CollisionPlane;
                     *  Client.Self.relativePosition = update.Position;
                     *  Client.Self.velocity = update.Velocity;
                     *  Client.Self.acceleration = update.Acceleration;
                     *  Client.Self.relativeRotation = update.Rotation;
                     *  Client.Self.angularVelocity = update.AngularVelocity;
                     * }
                     * */
                    #endregion Update Client.Self
                    if (update.LocalID == mid)
                    {
                        mpos = update.Position;
                    }
                    else
                    {
                        ObjectWithVel(update.Position, update.Velocity);
                    }
                }
                catch
                {
                    //Logger.Log(e.Message, Helpers.LogLevel.Warning, Client, e);
                }
            }
            return(packet);
        }
예제 #12
0
        public override void update()
        {
            LLVector3 pos2 = new LLVector3(0, 0, 0);
            if (this._physActor != null && this.physicsEnabled)
            {

                PhysicsVector pPos = this._physActor.Position;
                pos2 = new LLVector3(pPos.X, pPos.Y, pPos.Z);
            }
            if (this.newPrimFlag)
            {
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(OurPacket);
                }
                this.newPrimFlag = false;
            }
            else if (this.updateFlag)
            {
                ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                terse.RegionData.TimeDilation = 64096;
                terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                terse.ObjectData[0] = this.CreateImprovedBlock();
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(terse);
                }
                this.updateFlag = false;
            }
            else if (this.dirtyFlag)
            {
                foreach (SimClient client in m_clientThreads.Values)
                {
                    UpdateClient(client);
                }
                this.dirtyFlag = false;
            }
            else
            {
                if (this._physActor != null && this.physicsEnabled)
                {
                    if (pos2 != this.positionLastFrame)
                    {
                        ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                        terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                        terse.RegionData.TimeDilation = 64096;
                        terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                        terse.ObjectData[0] = this.CreateImprovedBlock();
                        foreach (SimClient client in m_clientThreads.Values)
                        {
                            client.OutPacket(terse);
                        }
                    }
                    this.positionLastFrame = pos2;
                }
            }

            if (this.physicstest)
            {
                LLVector3 pos = this.Pos;
                pos.Z += 0.0001f;
                this.UpdatePosition(pos);
                this.physicstest = false;
            }
        }
예제 #13
0
        void SendObjectPacket(SimulationObject obj, bool canUseCompressed, bool canUseImproved, PrimFlags creatorFlags, UpdateFlags updateFlags)
        {
            if (!canUseImproved && !canUseCompressed)
            {
                #region ObjectUpdate

                Logger.DebugLog("Sending ObjectUpdate");

                if (sceneAgents.ContainsKey(obj.Prim.OwnerID))
                {
                    // Send an update out to the creator
                    ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket();
                    updateToOwner.RegionData.RegionHandle = regionHandle;
                    updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
                    updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
                    updateToOwner.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim,
                        obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner, obj.CRC);

                    udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State);
                }

                // Send an update out to everyone else
                ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket();
                updateToOthers.RegionData.RegionHandle = regionHandle;
                updateToOthers.RegionData.TimeDilation = UInt16.MaxValue;
                updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
                updateToOthers.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim,
                    obj.Prim.Flags, obj.CRC);

                ForEachAgent(
                    delegate(Agent recipient)
                    {
                        if (recipient.ID != obj.Prim.OwnerID)
                            udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State);
                    }
                );

                #endregion ObjectUpdate
            }
            else if (!canUseImproved)
            {
                #region ObjectUpdateCompressed

                #region Size calculation and field serialization

                CompressedFlags flags = 0;
                int size = 84;
                byte[] textBytes = null;
                byte[] mediaURLBytes = null;
                byte[] particleBytes = null;
                byte[] extraParamBytes = null;
                byte[] nameValueBytes = null;
                byte[] textureBytes = null;
                byte[] textureAnimBytes = null;

                if ((updateFlags & UpdateFlags.AngularVelocity) != 0)
                {
                    flags |= CompressedFlags.HasAngularVelocity;
                    size += 12;
                }
                if ((updateFlags & UpdateFlags.ParentID) != 0)
                {
                    flags |= CompressedFlags.HasParent;
                    size += 4;
                }
                if ((updateFlags & UpdateFlags.ScratchPad) != 0)
                {
                    switch (obj.Prim.PrimData.PCode)
                    {
                        case PCode.Grass:
                        case PCode.Tree:
                        case PCode.NewTree:
                            flags |= CompressedFlags.Tree;
                            size += 2; // Size byte plus one byte
                            break;
                        default:
                            flags |= CompressedFlags.ScratchPad;
                            size += 1 + obj.Prim.ScratchPad.Length; // Size byte plus bytes
                            break;
                    }
                }
                if ((updateFlags & UpdateFlags.Text) != 0)
                {
                    flags |= CompressedFlags.HasText;
                    textBytes = Utils.StringToBytes(obj.Prim.Text);
                    size += textBytes.Length; // Null-terminated, no size byte
                    size += 4; // Text color
                }
                if ((updateFlags & UpdateFlags.MediaURL) != 0)
                {
                    flags |= CompressedFlags.MediaURL;
                    mediaURLBytes = Utils.StringToBytes(obj.Prim.MediaURL);
                    size += mediaURLBytes.Length; // Null-terminated, no size byte
                }
                if ((updateFlags & UpdateFlags.Particles) != 0)
                {
                    flags |= CompressedFlags.HasParticles;
                    particleBytes = obj.Prim.ParticleSys.GetBytes();
                    size += particleBytes.Length; // Should be exactly 86 bytes
                }

                // Extra Params
                extraParamBytes = obj.Prim.GetExtraParamsBytes();
                size += extraParamBytes.Length;

                if ((updateFlags & UpdateFlags.Sound) != 0)
                {
                    flags |= CompressedFlags.HasSound;
                    size += 25; // SoundID, SoundGain, SoundFlags, SoundRadius
                }
                if ((updateFlags & UpdateFlags.NameValue) != 0)
                {
                    flags |= CompressedFlags.HasNameValues;
                    nameValueBytes = Utils.StringToBytes(NameValue.NameValuesToString(obj.Prim.NameValues));
                    size += nameValueBytes.Length; // Null-terminated, no size byte
                }

                size += 23; // PrimData
                size += 4; // Texture Length
                textureBytes = obj.Prim.Textures.GetBytes();
                size += textureBytes.Length; // Texture Entry

                if ((updateFlags & UpdateFlags.TextureAnim) != 0)
                {
                    flags |= CompressedFlags.TextureAnimation;
                    size += 4; // TextureAnim Length
                    textureAnimBytes = obj.Prim.TextureAnim.GetBytes();
                    size += textureAnimBytes.Length; // TextureAnim
                }

                #endregion Size calculation and field serialization

                #region Packet serialization

                int pos = 0;
                byte[] data = new byte[size];

                // UUID
                obj.Prim.ID.ToBytes(data, 0);
                pos += 16;
                // LocalID
                Utils.UIntToBytes(obj.Prim.LocalID, data, pos);
                pos += 4;
                // PCode
                data[pos++] = (byte)obj.Prim.PrimData.PCode;
                // State
                data[pos++] = obj.Prim.PrimData.State;
                // CRC
                Utils.UIntToBytes(obj.CRC, data, pos);
                pos += 4;
                // Material
                data[pos++] = (byte)obj.Prim.PrimData.Material;
                // ClickAction
                data[pos++] = (byte)obj.Prim.ClickAction;
                // Scale
                obj.Prim.Scale.ToBytes(data, pos);
                pos += 12;
                // Position
                obj.Prim.Position.ToBytes(data, pos);
                pos += 12;
                // Rotation
                obj.Prim.Rotation.ToBytes(data, pos);
                pos += 12;
                // Compressed Flags
                Utils.UIntToBytes((uint)flags, data, pos);
                pos += 4;
                // OwnerID
                obj.Prim.OwnerID.ToBytes(data, pos);
                pos += 16;

                if ((flags & CompressedFlags.HasAngularVelocity) != 0)
                {
                    obj.Prim.AngularVelocity.ToBytes(data, pos);
                    pos += 12;
                }
                if ((flags & CompressedFlags.HasParent) != 0)
                {
                    Utils.UIntToBytes(obj.Prim.ParentID, data, pos);
                    pos += 4;
                }
                if ((flags & CompressedFlags.ScratchPad) != 0)
                {
                    data[pos++] = (byte)obj.Prim.ScratchPad.Length;
                    Buffer.BlockCopy(obj.Prim.ScratchPad, 0, data, pos, obj.Prim.ScratchPad.Length);
                    pos += obj.Prim.ScratchPad.Length;
                }
                else if ((flags & CompressedFlags.Tree) != 0)
                {
                    data[pos++] = 1;
                    data[pos++] = (byte)obj.Prim.TreeSpecies;
                }
                if ((flags & CompressedFlags.HasText) != 0)
                {
                    Buffer.BlockCopy(textBytes, 0, data, pos, textBytes.Length);
                    pos += textBytes.Length;
                    obj.Prim.TextColor.ToBytes(data, pos, false);
                    pos += 4;
                }
                if ((flags & CompressedFlags.MediaURL) != 0)
                {
                    Buffer.BlockCopy(mediaURLBytes, 0, data, pos, mediaURLBytes.Length);
                    pos += mediaURLBytes.Length;
                }
                if ((flags & CompressedFlags.HasParticles) != 0)
                {
                    Buffer.BlockCopy(particleBytes, 0, data, pos, particleBytes.Length);
                    pos += particleBytes.Length;
                }

                // Extra Params
                Buffer.BlockCopy(extraParamBytes, 0, data, pos, extraParamBytes.Length);
                pos += extraParamBytes.Length;

                if ((flags & CompressedFlags.HasSound) != 0)
                {
                    obj.Prim.Sound.ToBytes(data, pos);
                    pos += 16;
                    Utils.FloatToBytes(obj.Prim.SoundGain, data, pos);
                    pos += 4;
                    data[pos++] = (byte)obj.Prim.SoundFlags;
                    Utils.FloatToBytes(obj.Prim.SoundRadius, data, pos);
                    pos += 4;
                }
                if ((flags & CompressedFlags.HasNameValues) != 0)
                {
                    Buffer.BlockCopy(nameValueBytes, 0, data, pos, nameValueBytes.Length);
                    pos += nameValueBytes.Length;
                }

                // Path PrimData
                data[pos++] = (byte)obj.Prim.PrimData.PathCurve;
                Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.PathBegin), data, pos); pos += 2;
                Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.PathEnd), data, pos); pos += 2;
                data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleX);
                data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleY);
                data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearX);
                data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearY);
                data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwist);
                data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwistBegin);
                data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathRadiusOffset);
                data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperX);
                data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperY);
                data[pos++] = Primitive.PackPathRevolutions(obj.Prim.PrimData.PathRevolutions);
                data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathSkew);
                // Profile PrimData
                data[pos++] = obj.Prim.PrimData.profileCurve;
                Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.ProfileBegin), data, pos); pos += 2;
                Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.ProfileEnd), data, pos); pos += 2;
                Utils.UInt16ToBytes(Primitive.PackProfileHollow(obj.Prim.PrimData.ProfileHollow), data, pos); pos += 2;

                // Texture Length
                Utils.UIntToBytes((uint)textureBytes.Length, data, pos);
                pos += 4;
                // Texture Entry
                Buffer.BlockCopy(textureBytes, 0, data, pos, textureBytes.Length);
                pos += textureBytes.Length;

                if ((flags & CompressedFlags.TextureAnimation) != 0)
                {
                    Utils.UIntToBytes((uint)textureAnimBytes.Length, data, pos);
                    pos += 4;
                    Buffer.BlockCopy(textureAnimBytes, 0, data, pos, textureAnimBytes.Length);
                    pos += textureAnimBytes.Length;
                }

                #endregion Packet serialization

                #region Packet sending

                //Logger.DebugLog("Sending ObjectUpdateCompressed with " + flags.ToString());

                if (sceneAgents.ContainsKey(obj.Prim.OwnerID))
                {
                    // Send an update out to the creator
                    ObjectUpdateCompressedPacket updateToOwner = new ObjectUpdateCompressedPacket();
                    updateToOwner.RegionData.RegionHandle = regionHandle;
                    updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
                    updateToOwner.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1];
                    updateToOwner.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock();
                    updateToOwner.ObjectData[0].UpdateFlags = (uint)(obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner);
                    updateToOwner.ObjectData[0].Data = data;

                    udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State);
                }

                // Send an update out to everyone else
                ObjectUpdateCompressedPacket updateToOthers = new ObjectUpdateCompressedPacket();
                updateToOthers.RegionData.RegionHandle = regionHandle;
                updateToOthers.RegionData.TimeDilation = UInt16.MaxValue;
                updateToOthers.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1];
                updateToOthers.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock();
                updateToOthers.ObjectData[0].UpdateFlags = (uint)obj.Prim.Flags;
                updateToOthers.ObjectData[0].Data = data;

                ForEachAgent(
                    delegate(Agent recipient)
                    {
                        if (recipient.ID != obj.Prim.OwnerID)
                            udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State);
                    }
                );

                #endregion Packet sending

                #endregion ObjectUpdateCompressed
            }
            else
            {
                #region ImprovedTerseObjectUpdate

                //Logger.DebugLog("Sending ImprovedTerseObjectUpdate");

                int pos = 0;
                byte[] data = new byte[(obj.Prim is Avatar ? 60 : 44)];

                // LocalID
                Utils.UIntToBytes(obj.Prim.LocalID, data, pos);
                pos += 4;
                // Avatar/CollisionPlane
                data[pos++] = obj.Prim.PrimData.State;
                if (obj.Prim is Avatar)
                {
                    data[pos++] = 1;
                    obj.Prim.CollisionPlane.ToBytes(data, pos);
                    pos += 16;
                }
                else
                {
                    ++pos;
                }
                // Position
                obj.Prim.Position.ToBytes(data, pos);
                pos += 12;

                // Velocity
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
                // Acceleration
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
                // Rotation
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.X, -1.0f, 1.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Y, -1.0f, 1.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Z, -1.0f, 1.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
                // Angular Velocity
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
                Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;

                ImprovedTerseObjectUpdatePacket update = new ImprovedTerseObjectUpdatePacket();
                update.RegionData.RegionHandle = RegionHandle;
                update.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
                update.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                update.ObjectData[0] = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
                update.ObjectData[0].Data = data;

                if ((updateFlags & UpdateFlags.Textures) != 0)
                {
                    byte[] textureBytes = obj.Prim.Textures.GetBytes();
                    byte[] textureEntry = new byte[textureBytes.Length + 4];

                    // Texture Length
                    Utils.IntToBytes(textureBytes.Length, textureEntry, 0);
                    // Texture
                    Buffer.BlockCopy(textureBytes, 0, textureEntry, 4, textureBytes.Length);

                    update.ObjectData[0].TextureEntry = textureEntry;
                }
                else
                {
                    update.ObjectData[0].TextureEntry = Utils.EmptyBytes;
                }

                udp.BroadcastPacket(update, PacketCategory.State);

                #endregion ImprovedTerseObjectUpdate
            }
        }
예제 #14
0
        public override void update()
        {
            if (this._physActor == null)
            {
                //HACKHACK: Note to work out why this entity does not have a physics actor
                //          and prehaps create one.
                return;
            }
            libsecondlife.LLVector3 pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
            if (this.updateflag)
            {
                //need to send movement info
                //so create the improvedterseobjectupdate packet
                //use CreateTerseBlock()
                ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
                ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                terse.RegionData.TimeDilation = 64096;
                terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                terse.ObjectData[0] = terseBlock;
                foreach (SimClient client in m_clientThreads.Values)
                {
                    client.OutPacket(terse);
                }

                updateflag = false;
                //this._updateCount = 0;
            }
            else
            {

                if ((pos2 != this.positionLastFrame) || (this.movementflag == 16))
                {
                    _updateCount++;
                    if (((!PhysicsEngineFlying) && (_updateCount > 3)) || (PhysicsEngineFlying) && (_updateCount > 0))
                    {
                        //It has been a while since last update was sent so lets send one.
                        ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
                        ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
                        terse.RegionData.RegionHandle = m_regionHandle; // FIXME
                        terse.RegionData.TimeDilation = 64096;
                        terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
                        terse.ObjectData[0] = terseBlock;
                        foreach (SimClient client in m_clientThreads.Values)
                        {
                            client.OutPacket(terse);
                        }
                        _updateCount = 0;
                    }

                    if (this.movementflag == 16)
                    {
                        movementflag = 0;
                    }
                }

            }
            this.positionLastFrame = pos2;

            if (!this.ControllingClient.m_sandboxMode)
            {
                if (pos2.X < 0)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.Y < 0)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.X > 255)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }

                if (pos2.Y > 255)
                {
                    ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
                }
            }
        }
예제 #15
0
파일: Objects.cs 프로젝트: thoys/simian
        private void SendEntityPackets(QueuedInterestListEvent[] eventDatas, IScenePresence presence)
        {
            if (!(presence is LLAgent) || presence.InterestList == null)
                return;
            LLAgent agent = (LLAgent)presence;

            Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
            Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
            Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
            Lazy<List<ObjectUpdateCachedPacket.ObjectDataBlock>> cachedUpdateBlocks = new Lazy<List<ObjectUpdateCachedPacket.ObjectDataBlock>>();

            for (int i = 0; i < eventDatas.Length; i++)
            {
                EntityAddOrUpdateArgs e = (EntityAddOrUpdateArgs)eventDatas[i].Event.State;
                ISceneEntity entity = e.Entity;

                #region Determine packet type

                UpdateFlags updateFlags = e.UpdateFlags;
                LLUpdateFlags llUpdateFlags = (LLUpdateFlags)e.ExtraFlags;
                LLPrimitive prim = entity as LLPrimitive;

                bool canUseCached = false;
                bool canUseTerse = true;
                DateTime lastSeen;

                if (CACHE_CHECK_ENABLED &&
                    prim != null &&
                    updateFlags.HasFlag(UpdateFlags.FullUpdate) &&
                    !llUpdateFlags.HasFlag(LLUpdateFlags.NoCachedUpdate) &&
                    m_recentAvatars.TryGetValue(presence.ID, out lastSeen) &&
                    lastSeen > prim.LastUpdated)
                {
                    // This avatar was marked as leaving the same later than the last update
                    // timestamp of this prim. Send a cache check
                    canUseCached = true;
                }
                else if (updateFlags.HasFlag(UpdateFlags.FullUpdate) ||
                    updateFlags.HasFlag(UpdateFlags.Parent) ||
                    updateFlags.HasFlag(UpdateFlags.Scale) ||
                    updateFlags.HasFlag(UpdateFlags.Shape) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.PrimFlags) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Text) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.NameValue) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.ExtraData) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.TextureAnim) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Sound) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Particles) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Material) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.ClickAction) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.MediaURL) ||
                    llUpdateFlags.HasFlag(LLUpdateFlags.Joint))
                {
                    canUseTerse = false;
                }

                #endregion Determine packet type

                #region Block Construction

                if (canUseCached && prim != null)
                {
                    cachedUpdateBlocks.Value.Add(new ObjectUpdateCachedPacket.ObjectDataBlock
                        { CRC = prim.GetCrc(), ID = prim.LocalID });
                }
                else if (!canUseTerse)
                {
                    if (entity is IScenePresence)
                    {
                        IScenePresence thisPresence = (IScenePresence)entity;
                        ObjectUpdatePacket.ObjectDataBlock block = CreateAvatarObjectUpdateBlock(thisPresence);
                        block.UpdateFlags = (uint)GetUpdateFlags(thisPresence, presence);
                        objectUpdateBlocks.Value.Add(block);
                    }
                    else if (prim != null)
                    {
                        ObjectUpdateCompressedPacket.ObjectDataBlock block = CreateCompressedObjectUpdateBlock(prim, prim.GetCrc());
                        block.UpdateFlags = (uint)GetUpdateFlags(prim, presence, m_permissions);
                        compressedUpdateBlocks.Value.Add(block);

                        // ObjectUpdateCompressed doesn't carry velocity or acceleration fields, so
                        // we need to send a separate terse packet if this prim has a non-zero
                        // velocity or acceleration
                        if (prim.Velocity != Vector3.Zero || prim.Acceleration != Vector3.Zero)
                            terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, false));

                        //ObjectUpdatePacket.ObjectDataBlock block = CreateObjectUpdateBlock(prim);
                        //block.UpdateFlags = (uint)GetUpdateFlags(prim, presence, m_permissions);
                        //block.CRC = prim.GetCrc();
                        //objectUpdateBlocks.Value.Add(block);
                    }
                    else
                    {
                        // TODO: Create a generic representation for non-LLPrimitive entities?
                        continue;
                    }
                }
                else
                {
                    terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, llUpdateFlags.HasFlag(LLUpdateFlags.Textures)));
                }

                #endregion Block Construction

                // Unset CreateSelected after it has been sent once
                if (prim != null)
                    prim.Prim.Flags &= ~PrimFlags.CreateSelected;
            }

            #region Packet Sending

            ushort timeDilation = (m_physics != null) ?
                Utils.FloatToUInt16(m_physics.TimeDilation, 0.0f, 1.0f) :
                UInt16.MaxValue;

            if (objectUpdateBlocks.IsValueCreated)
            {
                List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;

                ObjectUpdatePacket packet = new ObjectUpdatePacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            if (compressedUpdateBlocks.IsValueCreated)
            {
                List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;

                ObjectUpdateCompressedPacket packet = new ObjectUpdateCompressedPacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            if (terseUpdateBlocks.IsValueCreated)
            {
                List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;

                ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            if (cachedUpdateBlocks.IsValueCreated)
            {
                List<ObjectUpdateCachedPacket.ObjectDataBlock> blocks = cachedUpdateBlocks.Value;

                ObjectUpdateCachedPacket packet = new ObjectUpdateCachedPacket();
                packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition);
                packet.RegionData.TimeDilation = timeDilation;
                packet.ObjectData = new ObjectUpdateCachedPacket.ObjectDataBlock[blocks.Count];

                for (int i = 0; i < blocks.Count; i++)
                    packet.ObjectData[i] = blocks[i];

                m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true);
            }

            #endregion Packet Sending
        }