Ejemplo n.º 1
0
        private void CompressedUpdateHandler(Packet packet, Simulator simulator)
        {
            ObjectUpdateCompressedPacket update = (ObjectUpdateCompressedPacket)packet;
            PrimObject prim;

            foreach (ObjectUpdateCompressedPacket.ObjectDataBlock block in update.ObjectData)
            {
                int i = 0;
                prim = new PrimObject(Client);

                try
                {
                    prim.ID      = new LLUUID(block.Data, 0);
                    i           += 16;
                    prim.LocalID = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                                          (block.Data[i++] << 16) + (block.Data[i++] << 24));

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

                    if (pcode == (byte)PCode.Prim)
                    {
                        #region PrimRegion
                        prim.State    = (uint)block.Data[i++];
                        i            += 4; // CRC
                        prim.Material = (uint)block.Data[i++];
                        i++;               // TODO: ClickAction

                        prim.Scale    = new LLVector3(block.Data, i);
                        i            += 12;
                        prim.Position = new LLVector3(block.Data, i);
                        i            += 12;
                        prim.Rotation = new LLQuaternion(block.Data, i, true);
                        i            += 12;

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

                        if ((flags & 0x02) != 0)
                        {
                            byte TreeData = block.Data[i++];

                            // TODO: Unknown byte
                            i++;

                            if (OnNewPrim != null)
                            {
                                OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                            }
                            continue;
                        }

                        if ((flags & 0x20) != 0)
                        {
                            prim.ParentID = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                                                   (block.Data[i++] << 16) + (block.Data[i++] << 24));
                        }
                        else
                        {
                            prim.ParentID = 0;
                        }

                        if ((flags & 0x80) != 0)
                        {
                            // TODO: Use this. What is it?
                            LLVector3 Omega = new LLVector3(block.Data, i);
                            i += 12;
                        }

                        if ((flags & 0x04) != 0)
                        {
                            string text = "";
                            while (block.Data[i] != 0)
                            {
                                text += (char)block.Data[i];
                                i++;
                            }
                            prim.Text = text;
                            i++;

                            // Text color
                            i += 4;
                        }
                        else
                        {
                            prim.Text = "";
                        }

                        if ((flags & 0x08) != 0)
                        {
                            prim.ParticleSys = new ParticleSystem(block.Data, i);
                            i += 86;
                        }

                        i += prim.SetExtraParamsFromBytes(block.Data, i);

                        //Sound data
                        if ((flags & 0x10) != 0)
                        {
                            //TODO: use this data
                            LLUUID SoundUUID = new LLUUID(block.Data, i);
                            i += 16;
                            LLUUID OwnerUUID = new LLUUID(block.Data, i);
                            i += 16;

                            if (!BitConverter.IsLittleEndian)
                            {
                                Array.Reverse(block.Data, i, 4);
                                Array.Reverse(block.Data, i + 5, 4);
                            }

                            float SoundGain = BitConverter.ToSingle(block.Data, i);
                            i += 4;
                            byte  SoundFlags  = block.Data[i++];
                            float SoundRadius = BitConverter.ToSingle(block.Data, i);
                            i += 4;
                        }

                        //Indicates that this is an attachment?
                        if ((flags & 0x100) != 0)
                        {
                            //A string
                            //Example: "AttachItemID STRING RW SV fa9a5ab8-1bad-b449-9873-cf5b803e664e"
                            while (block.Data[i] != 0)
                            {
                                i++;
                            }
                            i++;
                        }

                        prim.PathCurve        = (uint)block.Data[i++];
                        prim.PathBegin        = PrimObject.PathBeginFloat(block.Data[i++]);
                        prim.PathEnd          = PrimObject.PathEndFloat(block.Data[i++]);
                        prim.PathTaperX       = PrimObject.PathScaleFloat(block.Data[i++]);
                        prim.PathTaperY       = PrimObject.PathScaleFloat(block.Data[i++]);
                        prim.PathShearX       = PrimObject.PathShearFloat(block.Data[i++]);
                        prim.PathShearY       = PrimObject.PathShearFloat(block.Data[i++]);
                        prim.PathTwist        = (int)block.Data[i++];
                        prim.PathTwistBegin   = (int)block.Data[i++];
                        prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat((sbyte)block.Data[i++]);
                        //prim.PathTaperX = PrimObject.PathTaperFloat(block.Data[i++]);
                        //prim.PathTaperY = PrimObject.PathTaperFloat(block.Data[i++]);
                        i += 2;
                        prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.Data[i++]);
                        prim.PathSkew        = PrimObject.PathSkewFloat(block.Data[i++]);

                        prim.ProfileCurve  = (uint)block.Data[i++];
                        prim.ProfileBegin  = PrimObject.ProfileBeginFloat(block.Data[i++]);
                        prim.ProfileEnd    = PrimObject.ProfileEndFloat(block.Data[i++]);
                        prim.ProfileHollow = (uint)block.Data[i++];

                        int textureEntryLength = (int)(block.Data[i++] + (block.Data[i++] << 8) +
                                                       (block.Data[i++] << 16) + (block.Data[i++] << 24));

                        prim.Textures = new TextureEntry(block.Data, i, textureEntryLength);

                        i += textureEntryLength;

                        if (i < block.Data.Length)
                        {
                            int textureAnimLength = (int)(block.Data[i++] + (block.Data[i++] << 8) +
                                                          (block.Data[i++] << 16) + (block.Data[i++] << 24));

                            prim.TextureAnim = new TextureAnimation(block.Data, i);
                        }

                        if (OnNewPrim != null)
                        {
                            OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                        }

                        #endregion PrimRegion
                    }
                    else if (pcode == (byte)PCode.Avatar)
                    {
                        Client.Log("######### Got an ObjectUpdateCompressed for an avatar, implement this! #########",
                                   Helpers.LogLevel.Warning);
                    }
                    else if (pcode == (byte)PCode.Grass || pcode == (byte)PCode.Tree)
                    {
                        // TODO: Add new_tree and any other tree-like prims
                        ;
                    }
                    else
                    {
                        // TODO: ...
                        continue;
                    }
                }
                catch (System.IndexOutOfRangeException e)
                {
                    Client.Log("Had a problem decoding an ObjectUpdateCompressed packet: " +
                               e.ToString(), Helpers.LogLevel.Warning);
                    Client.Log(block.ToString(), Helpers.LogLevel.Warning);
                }
            }
        }
Ejemplo n.º 2
0
        private void UpdateHandler(Packet packet, Simulator simulator)
        {
            if (OnNewPrim != null || OnNewAvatar != null)
            {
                ObjectUpdatePacket update = (ObjectUpdatePacket)packet;

                foreach (ObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
                {
                    if (block.PCode == (byte)PCode.Prim)
                    {
                        if (OnNewPrim != null)
                        {
                            // New prim spotted
                            PrimObject prim = new PrimObject(Client);

                            prim.Position = new LLVector3(block.ObjectData, 0);
                            prim.Rotation = new LLQuaternion(block.ObjectData, 36, true);

                            // TODO: Parse the rest of the ObjectData byte array fields

                            prim.LocalID  = block.ID;
                            prim.State    = block.State;
                            prim.ID       = block.FullID;
                            prim.ParentID = block.ParentID;
                            //block.OwnerID Sound-related
                            prim.Material         = block.Material;
                            prim.PathCurve        = block.PathCurve;
                            prim.ProfileCurve     = block.ProfileCurve;
                            prim.PathBegin        = PrimObject.PathBeginFloat(block.PathBegin);
                            prim.PathEnd          = PrimObject.PathEndFloat(block.PathEnd);
                            prim.PathTaperX       = PrimObject.PathScaleFloat(block.PathScaleX);
                            prim.PathTaperY       = PrimObject.PathScaleFloat(block.PathScaleY);
                            prim.PathShearX       = PrimObject.PathShearFloat(block.PathShearX);
                            prim.PathShearY       = PrimObject.PathShearFloat(block.PathShearY);
                            prim.PathTwist        = block.PathTwist;      //PrimObject.PathTwistFloat(block.PathTwist);
                            prim.PathTwistBegin   = block.PathTwistBegin; //PrimObject.PathTwistFloat(block.PathTwistBegin);
                            prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat(block.PathRadiusOffset);
                            //prim.PathTaperX = PrimObject.PathTaperFloat((byte)block.PathTaperX);
                            //prim.PathTaperY = PrimObject.PathTaperFloat((byte)block.PathTaperY);
                            prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.PathRevolutions);
                            prim.PathSkew        = PrimObject.PathSkewFloat((byte)block.PathSkew);
                            prim.ProfileBegin    = PrimObject.ProfileBeginFloat(block.ProfileBegin);
                            prim.ProfileEnd      = PrimObject.ProfileEndFloat(block.ProfileEnd);
                            prim.ProfileHollow   = block.ProfileHollow;
                            prim.Name            = Helpers.FieldToString(block.NameValue);
                            //block.Data ?
                            prim.Text = ASCIIEncoding.ASCII.GetString(block.Text);
                            //block.TextColor LLColor4U of the hovering text
                            //block.MediaURL Quicktime stream
                            prim.Textures    = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);
                            prim.TextureAnim = new TextureAnimation(block.TextureAnim, 0);
                            //block.JointType ?
                            //block.JointPivot ?
                            //block.JointAxisOrAnchor ?
                            prim.ParticleSys = new ParticleSystem(block.PSBlock, 0);
                            prim.SetExtraParamsFromBytes(block.ExtraParams, 0);
                            prim.Scale = block.Scale;
                            //block.Flags ?
                            //block.UpdateFlags ?
                            //block.ClickAction ?
                            //block.Gain Sound-related
                            //block.Sound Sound-related
                            //block.Radius Sound-related

                            if (OnNewPrim != null)
                            {
                                OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                            }
                        }
                    }
                    else if (block.PCode == (byte)PCode.Avatar)
                    {
                        if (OnNewAvatar != null)
                        {
                            Avatar avatar = new Avatar();

                            string FirstName = "";
                            string LastName  = "";
                            string GroupName = "";

                            //avatar.CollisionPlane = new LLQuaternion(block.ObjectData, 0);
                            avatar.Position = new LLVector3(block.ObjectData, 16);
                            avatar.Rotation = new LLQuaternion(block.ObjectData, 52, true);

                            // TODO: Parse the rest of the ObjectData byte array fields

                            ParseAvName(Helpers.FieldToString(block.NameValue), ref FirstName, ref LastName, ref GroupName);

                            avatar.ID            = block.FullID;
                            avatar.LocalID       = block.ID;
                            avatar.Name          = FirstName + " " + LastName;
                            avatar.GroupName     = GroupName;
                            avatar.Online        = true;
                            avatar.CurrentRegion = simulator.Region;

                            avatar.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);

                            if (FirstName == Client.Self.FirstName && LastName == Client.Self.LastName)
                            {
                                // Update our avatar
                                Client.Self.LocalID  = avatar.LocalID;
                                Client.Self.Position = avatar.Position;
                                Client.Self.Rotation = avatar.Rotation;
                            }
                            else
                            {
                                if (OnNewAvatar != null)
                                {
                                    OnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                                }
                            }
                        }
                    }
                    else if (block.PCode == (byte)PCode.Grass)
                    {
                        // FIXME: Handle grass objects
                        ;
                    }
                    else if (block.PCode == (byte)PCode.Tree)
                    {
                        // FIXME: Handle tree objects
                        ;
                    }
                    else if (block.PCode == (byte)PCode.ParticleSystem)
                    {
                        ;
                    }
                    else
                    {
                        // FIXME: How many of the PCodes do we actually need to handle?
                        ;
                    }
                }
            }
        }