Пример #1
0
        public static NameValue[] ParseNameValues(string text)
        {
            // Parse the name values
            if (text.Length > 0)
            {
                if (text == "\n")
                {
                    return(new NameValue[0]);
                }

                string[] lines      = text.Split('\n');
                var      NameValues = new NameValue[lines.Length];

                for (int j = 0; j < lines.Length; j++)
                {
                    if (!String.IsNullOrEmpty(lines[j]))
                    {
                        NameValue nv = new NameValue(lines[j]);
                        NameValues[j] = nv;
                    }
                }
                return(NameValues);
            }
            return(null);
        }
Пример #2
0
        public static string NameValuesToString(NameValue[] values)
        {
            if (values == null)
            {
                return(String.Empty);
            }
            if (values.Length == 0)
            {
                return("\n");
            }

            StringBuilder output = new StringBuilder();

            for (int i = 0; i < values.Length; i++)
            {
                NameValue value = values[i];

                if (value.Value != null)
                {
                    string newLine = (i < values.Length - 1) ? "\n" : String.Empty;
                    output.AppendFormat("{0} {1} {2} {3} {4}{5}", value.Name, TypeStrings[(int)value.Type],
                                        ClassStrings[(int)value.Class], SendtoStrings[(int)value.Sendto], value.Value.ToString(), newLine);
                }
            }

            return(output.ToString());
        }
Пример #3
0
        void CompleteAgentMovementHandler(Packet packet, Agent agent)
        {
            CompleteAgentMovementPacket request = (CompleteAgentMovementPacket)packet;

            // Create a representation for this agent
            Avatar avatar = new Avatar();
            avatar.ID = agent.AgentID;
            avatar.LocalID = (uint)Interlocked.Increment(ref currentLocalID);
            avatar.Position = new Vector3(128f, 128f, 25f);
            avatar.Rotation = Quaternion.Identity;
            avatar.Scale = new Vector3(1f, 1f, 3f);

            // Set the avatar name
            NameValue[] name = new NameValue[2];
            name[0] = new NameValue("FirstName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite,
                NameValue.SendtoType.SimViewer, agent.FirstName);
            name[1] = new NameValue("LastName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite,
                NameValue.SendtoType.SimViewer, agent.LastName);
            avatar.NameValues = name;

            // Link this avatar up with the corresponding agent
            agent.Avatar = avatar;

            // Give testers a provisionary balance of 1000L
            agent.Balance = 1000;

            AgentMovementCompletePacket complete = new AgentMovementCompletePacket();
            complete.AgentData.AgentID = agent.AgentID;
            complete.AgentData.SessionID = agent.SessionID;
            complete.Data.LookAt = Vector3.UnitX;
            complete.Data.Position = avatar.Position;
            complete.Data.RegionHandle = server.RegionHandle;
            complete.Data.Timestamp = Utils.DateTimeToUnixTime(DateTime.Now);
            complete.SimData.ChannelVersion = Utils.StringToBytes("Simian");

            agent.SendPacket(complete);

            SendLayerData(agent);
        }
Пример #4
0
        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void ObjectUpdateHandler(object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.Packet;
            Simulator simulator = e.Simulator;

            ObjectUpdatePacket update = (ObjectUpdatePacket)packet;
            UpdateDilation(e.Simulator, update.RegionData.TimeDilation);

            for (int b = 0; b < update.ObjectData.Length; b++)
            {
                ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b];

                ObjectMovementUpdate objectupdate = new ObjectMovementUpdate();
                //Vector4 collisionPlane = Vector4.Zero;
                //Vector3 position;
                //Vector3 velocity;
                //Vector3 acceleration;
                //Quaternion rotation;
                //Vector3 angularVelocity;
                NameValue[] nameValues;
                bool attachment = false;
                PCode pcode = (PCode)block.PCode;

                #region Relevance check

                // Check if we are interested in this object
                if (!Client.Settings.ALWAYS_DECODE_OBJECTS)
                {
                    switch (pcode)
                    {
                        case PCode.Grass:
                        case PCode.Tree:
                        case PCode.NewTree:
                        case PCode.Prim:
                            if (m_ObjectUpdate == null) continue;
                            break;
                        case PCode.Avatar:
                            // Make an exception for updates about our own agent
                            if (block.FullID != Client.Self.AgentID && m_AvatarUpdate == null) continue;
                            break;
                        case PCode.ParticleSystem:
                            continue; // TODO: Do something with these
                    }
                }

                #endregion Relevance check

                #region NameValue parsing

                string nameValue = Utils.BytesToString(block.NameValue);
                if (nameValue.Length > 0)
                {
                    string[] lines = nameValue.Split('\n');
                    nameValues = new NameValue[lines.Length];

                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (!String.IsNullOrEmpty(lines[i]))
                        {
                            NameValue nv = new NameValue(lines[i]);
                            if (nv.Name == "AttachItemID") attachment = true;
                            nameValues[i] = nv;
                        }
                    }
                }
                else
                {
                    nameValues = new NameValue[0];
                }

                #endregion NameValue parsing

                #region Decode Object (primitive) parameters
                Primitive.ConstructionData data = new Primitive.ConstructionData();
                data.State = block.State;
                data.Material = (Material)block.Material;
                data.PathCurve = (PathCurve)block.PathCurve;
                data.profileCurve = block.ProfileCurve;
                data.PathBegin = Primitive.UnpackBeginCut(block.PathBegin);
                data.PathEnd = Primitive.UnpackEndCut(block.PathEnd);
                data.PathScaleX = Primitive.UnpackPathScale(block.PathScaleX);
                data.PathScaleY = Primitive.UnpackPathScale(block.PathScaleY);
                data.PathShearX = Primitive.UnpackPathShear((sbyte)block.PathShearX);
                data.PathShearY = Primitive.UnpackPathShear((sbyte)block.PathShearY);
                data.PathTwist = Primitive.UnpackPathTwist(block.PathTwist);
                data.PathTwistBegin = Primitive.UnpackPathTwist(block.PathTwistBegin);
                data.PathRadiusOffset = Primitive.UnpackPathTwist(block.PathRadiusOffset);
                data.PathTaperX = Primitive.UnpackPathTaper(block.PathTaperX);
                data.PathTaperY = Primitive.UnpackPathTaper(block.PathTaperY);
                data.PathRevolutions = Primitive.UnpackPathRevolutions(block.PathRevolutions);
                data.PathSkew = Primitive.UnpackPathTwist(block.PathSkew);
                data.ProfileBegin = Primitive.UnpackBeginCut(block.ProfileBegin);
                data.ProfileEnd = Primitive.UnpackEndCut(block.ProfileEnd);
                data.ProfileHollow = Primitive.UnpackProfileHollow(block.ProfileHollow);
                data.PCode = pcode;
                #endregion

                #region Decode Additional packed parameters in ObjectData
                int pos = 0;
                switch (block.ObjectData.Length)
                {
                    case 76:
                        // Collision normal for avatar
                        objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos);
                        pos += 16;

                        goto case 60;
                    case 60:
                        // Position
                        objectupdate.Position = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Velocity
                        objectupdate.Velocity = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Acceleration
                        objectupdate.Acceleration = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Rotation (theta)
                        objectupdate.Rotation = new Quaternion(block.ObjectData, pos, true);
                        pos += 12;
                        // Angular velocity (omega)
                        objectupdate.AngularVelocity = new Vector3(block.ObjectData, pos);
                        pos += 12;

                        break;
                    case 48:
                        // Collision normal for avatar
                        objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos);
                        pos += 16;

                        goto case 32;
                    case 32:
                        // The data is an array of unsigned shorts

                        // Position
                        objectupdate.Position = new Vector3(
                            Utils.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f));
                        pos += 6;
                        // Velocity
                        objectupdate.Velocity = new Vector3(
                            Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Acceleration
                        objectupdate.Acceleration = new Vector3(
                            Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Rotation (theta)
                        objectupdate.Rotation = new Quaternion(
                            Utils.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f));
                        pos += 8;
                        // Angular velocity (omega)
                        objectupdate.AngularVelocity = new Vector3(
                            Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;

                        break;
                    case 16:
                        // The data is an array of single bytes (8-bit numbers)

                        // Position
                        objectupdate.Position = new Vector3(
                            Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Velocity
                        objectupdate.Velocity = new Vector3(
                            Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Accleration
                        objectupdate.Acceleration = new Vector3(
                            Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Rotation
                        objectupdate.Rotation = new Quaternion(
                            Utils.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f));
                        pos += 4;
                        // Angular Velocity
                        objectupdate.AngularVelocity = new Vector3(
                            Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;

                        break;
                    default:
                        Logger.Log("Got an ObjectUpdate block with ObjectUpdate field length of " +
                            block.ObjectData.Length, Helpers.LogLevel.Warning, Client);

                        continue;
                }
                #endregion

                // Determine the object type and create the appropriate class
                switch (pcode)
                {
                    #region Prim and Foliage
                    case PCode.Grass:
                    case PCode.Tree:
                    case PCode.NewTree:
                    case PCode.Prim:

                        bool isNewObject;
                        lock (simulator.ObjectsPrimitives.Dictionary)
                            isNewObject = !simulator.ObjectsPrimitives.ContainsKey(block.ID);

                        Primitive prim = GetPrimitive(simulator, block.ID, block.FullID);

                        // Textures
                        objectupdate.Textures = new Primitive.TextureEntry(block.TextureEntry, 0,
                            block.TextureEntry.Length);

                        OnObjectDataBlockUpdate(new ObjectDataBlockUpdateEventArgs(simulator, prim, data, block, objectupdate, nameValues));

                        #region Update Prim Info with decoded data
                        prim.Flags = (PrimFlags)block.UpdateFlags;

                        if ((prim.Flags & PrimFlags.ZlibCompressed) != 0)
                        {
                            Logger.Log("Got a ZlibCompressed ObjectUpdate, implement me!",
                                Helpers.LogLevel.Warning, Client);
                            continue;
                        }

                        // Automatically request ObjectProperties for prim if it was rezzed selected.
                        if ((prim.Flags & PrimFlags.CreateSelected) != 0)
                        {
                            SelectObject(simulator, prim.LocalID);
                        }

                        prim.NameValues = nameValues;
                        prim.LocalID = block.ID;
                        prim.ID = block.FullID;
                        prim.ParentID = block.ParentID;
                        prim.RegionHandle = update.RegionData.RegionHandle;
                        prim.Scale = block.Scale;
                        prim.ClickAction = (ClickAction)block.ClickAction;
                        prim.OwnerID = block.OwnerID;
                        prim.MediaURL = Utils.BytesToString(block.MediaURL);
                        prim.Text = Utils.BytesToString(block.Text);
                        prim.TextColor = new Color4(block.TextColor, 0, false, true);

                        // Sound information
                        prim.Sound = block.Sound;
                        prim.SoundFlags = (SoundFlags)block.Flags;
                        prim.SoundGain = block.Gain;
                        prim.SoundRadius = block.Radius;

                        // Joint information
                        prim.Joint = (JointType)block.JointType;
                        prim.JointPivot = block.JointPivot;
                        prim.JointAxisOrAnchor = block.JointAxisOrAnchor;

                        // Object parameters
                        prim.PrimData = data;

                        // Textures, texture animations, particle system, and extra params
                        prim.Textures = objectupdate.Textures;

                        prim.TextureAnim = new Primitive.TextureAnimation(block.TextureAnim, 0);
                        prim.ParticleSys = new Primitive.ParticleSystem(block.PSBlock, 0);
                        prim.SetExtraParamsFromBytes(block.ExtraParams, 0);

                        // PCode-specific data
                        switch (pcode)
                        {
                            case PCode.Grass:
                            case PCode.Tree:
                            case PCode.NewTree:
                                if (block.Data.Length == 1)
                                    prim.TreeSpecies = (Tree)block.Data[0];
                                else
                                    Logger.Log("Got a foliage update with an invalid TreeSpecies field", Helpers.LogLevel.Warning);
                            //    prim.ScratchPad = Utils.EmptyBytes;
                            //    break;
                            //default:
                            //    prim.ScratchPad = new byte[block.Data.Length];
                            //    if (block.Data.Length > 0)
                            //        Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length);
                                break;
                        }
                        prim.ScratchPad = Utils.EmptyBytes;

                        // Packed parameters
                        prim.CollisionPlane = objectupdate.CollisionPlane;
                        prim.Position = objectupdate.Position;
                        prim.Velocity = objectupdate.Velocity;
                        prim.Acceleration = objectupdate.Acceleration;
                        prim.Rotation = objectupdate.Rotation;
                        prim.AngularVelocity = objectupdate.AngularVelocity;
                        #endregion

                        OnObjectUpdate(new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNewObject, attachment));

                        break;
                    #endregion Prim and Foliage
                    #region Avatar
                    case PCode.Avatar:

                        bool isNewAvatar;
                        lock (simulator.ObjectsAvatars.Dictionary)
                            isNewAvatar = !simulator.ObjectsAvatars.ContainsKey(block.ID);

                        // Update some internals if this is our avatar
                        if (block.FullID == Client.Self.AgentID && simulator == Client.Network.CurrentSim)
                        {
                            #region Update Client.Self

                            // We need the local ID to recognize terse updates for our agent
                            Client.Self.localID = block.ID;

                            // Packed parameters
                            Client.Self.collisionPlane = objectupdate.CollisionPlane;
                            Client.Self.relativePosition = objectupdate.Position;
                            Client.Self.velocity = objectupdate.Velocity;
                            Client.Self.acceleration = objectupdate.Acceleration;
                            Client.Self.relativeRotation = objectupdate.Rotation;
                            Client.Self.angularVelocity = objectupdate.AngularVelocity;

                            #endregion
                        }

                        #region Create an Avatar from the decoded data

                        Avatar avatar = GetAvatar(simulator, block.ID, block.FullID);

                        objectupdate.Avatar = true;
                        // Textures
                        objectupdate.Textures = new Primitive.TextureEntry(block.TextureEntry, 0,
                            block.TextureEntry.Length);

                        OnObjectDataBlockUpdate(new ObjectDataBlockUpdateEventArgs(simulator, avatar, data, block, objectupdate, nameValues));

                        uint oldSeatID = avatar.ParentID;

                        avatar.ID = block.FullID;
                        avatar.LocalID = block.ID;
                        avatar.CollisionPlane = objectupdate.CollisionPlane;
                        avatar.Position = objectupdate.Position;
                        avatar.Velocity = objectupdate.Velocity;
                        avatar.Acceleration = objectupdate.Acceleration;
                        avatar.Rotation = objectupdate.Rotation;
                        avatar.AngularVelocity = objectupdate.AngularVelocity;
                        avatar.NameValues = nameValues;
                        avatar.PrimData = data;
                        if (block.Data.Length > 0)
                        {
                            Logger.Log("Unexpected Data field for an avatar update, length " + block.Data.Length, Helpers.LogLevel.Warning);
                        }
                        avatar.ParentID = block.ParentID;
                        avatar.RegionHandle = update.RegionData.RegionHandle;

                        SetAvatarSittingOn(simulator, avatar, block.ParentID, oldSeatID);

                        // Textures
                        avatar.Textures = objectupdate.Textures;

                        #endregion Create an Avatar from the decoded data

                        OnAvatarUpdate(new AvatarUpdateEventArgs(simulator, avatar, update.RegionData.TimeDilation, isNewAvatar));

                        break;
                    #endregion Avatar
                    case PCode.ParticleSystem:
                        DecodeParticleUpdate(block);
                        // TODO: Create a callback for particle updates
                        break;
                    default:
                        Logger.DebugLog("Got an ObjectUpdate block with an unrecognized PCode " + pcode.ToString(), Client);
                        break;
                }
            }
        }
Пример #5
0
        public static new Avatar FromOSD(OSD O)
        {

            OSDMap tex = (OSDMap)O;

            Avatar A = new Avatar();
            
            Primitive P = Primitive.FromOSD(O);

            Type Prim = typeof(Primitive);

            FieldInfo[] Fields = Prim.GetFields();

            for (int x = 0; x < Fields.Length; x++)
            {
                Logger.Log("Field Matched in FromOSD: "+Fields[x].Name, Helpers.LogLevel.Debug);
                Fields[x].SetValue(A, Fields[x].GetValue(P));
            }            

            A.Groups = new List<UUID>();

            foreach (OSD U in (OSDArray)tex["groups"])
            {
                A.Groups.Add(U.AsUUID());
            }

            A.ProfileStatistics = Statistics.FromOSD(tex["profile_statistics"]);
            A.ProfileProperties = AvatarProperties.FromOSD(tex["profile_properties"]);
            A.ProfileInterests = Interests.FromOSD(tex["profile_interest"]);
            A.ControlFlags = (AgentManager.ControlFlags)tex["control_flags"].AsInteger();

            OSDArray vp = (OSDArray)tex["visual_parameters"];
            A.VisualParameters = new byte[vp.Count];

            for (int i = 0; i < vp.Count; i++)
            {
                A.VisualParameters[i] = (byte)vp[i].AsInteger();
            }

            // *********************From Code Above *******************************
            /*if (NameValues[i].Name == "FirstName" && NameValues[i].Type == NameValue.ValueType.String)
                              firstName = (string)NameValues[i].Value;
                          else if (NameValues[i].Name == "LastName" && NameValues[i].Type == NameValue.ValueType.String)
                              lastName = (string)NameValues[i].Value;*/
            // ********************************************************************

            A.NameValues = new NameValue[3];

            NameValue First = new NameValue();
            First.Name = "FirstName";
            First.Type = NameValue.ValueType.String;
            First.Value = tex["first_name"].AsString();

            NameValue Last = new NameValue();
            Last.Name = "LastName";
            Last.Type = NameValue.ValueType.String;
            Last.Value = tex["last_name"].AsString();

            // ***************From Code Above***************
            // if (NameValues[i].Name == "Title" && NameValues[i].Type == NameValue.ValueType.String)
            // *********************************************

            NameValue Group = new NameValue();
            Group.Name = "Title";
            Group.Type = NameValue.ValueType.String;
            Group.Value = tex["group_name"].AsString();



            A.NameValues[0] = First;
            A.NameValues[1] = Last;
            A.NameValues[2] = Group;

            return A;


        }
Пример #6
0
        public static new Avatar FromOSD(OSD O)
        {
            OSDMap tex = (OSDMap)O;

            Avatar A = new Avatar();

            Primitive P = Primitive.FromOSD(O);

            Type Prim = typeof(Primitive);

            FieldInfo[] Fields = Prim.GetFields();

            for (int x = 0; x < Fields.Length; x++)
            {
                Logger.Log("Field Matched in FromOSD: " + Fields[x].Name, Helpers.LogLevel.Debug);
                Fields[x].SetValue(A, Fields[x].GetValue(P));
            }

            A.Groups = new List <UUID>();

            foreach (OSD U in (OSDArray)tex["groups"])
            {
                A.Groups.Add(U.AsUUID());
            }

            A.ProfileStatistics = Statistics.FromOSD(tex["profile_statistics"]);
            A.ProfileProperties = AvatarProperties.FromOSD(tex["profile_properties"]);
            A.ProfileInterests  = Interests.FromOSD(tex["profile_interest"]);
            A.ControlFlags      = (AgentManager.ControlFlags)tex["control_flags"].AsInteger();

            OSDArray vp = (OSDArray)tex["visual_parameters"];

            A.VisualParameters = new byte[vp.Count];

            for (int i = 0; i < vp.Count; i++)
            {
                A.VisualParameters[i] = (byte)vp[i].AsInteger();
            }

            // *********************From Code Above *******************************

            /*if (NameValues[i].Name == "FirstName" && NameValues[i].Type == NameValue.ValueType.String)
             *                firstName = (string)NameValues[i].Value;
             *            else if (NameValues[i].Name == "LastName" && NameValues[i].Type == NameValue.ValueType.String)
             *                lastName = (string)NameValues[i].Value;*/
            // ********************************************************************

            A.NameValues = new NameValue[3];

            NameValue First = new NameValue();

            First.Name  = "FirstName";
            First.Type  = NameValue.ValueType.String;
            First.Value = tex["first_name"].AsString();

            NameValue Last = new NameValue();

            Last.Name  = "LastName";
            Last.Type  = NameValue.ValueType.String;
            Last.Value = tex["last_name"].AsString();

            // ***************From Code Above***************
            // if (NameValues[i].Name == "Title" && NameValues[i].Type == NameValue.ValueType.String)
            // *********************************************

            NameValue Group = new NameValue();

            Group.Name  = "Title";
            Group.Type  = NameValue.ValueType.String;
            Group.Value = tex["group_name"].AsString();



            A.NameValues[0] = First;
            A.NameValues[1] = Last;
            A.NameValues[2] = Group;

            return(A);
        }
Пример #7
0
        public ObjectUpdatePacket.ObjectDataBlock modBlock(ObjectUpdatePacket.ObjectDataBlock block)
        {
            string FirstName = null;
            string LastName = null;
            string Title = null;

            string[] namevalues = Utils.BytesToString(block.NameValue).Split("\r\n".ToCharArray());
            foreach (string line in namevalues)
            {
                NameValue namevalue = new NameValue(line);
                if (namevalue.Value != null)
                {
                    if (namevalue.Name == "FirstName")
                    {

                        FirstName = Convert.ToString(namevalue.Value);
                        if (avclients.ContainsKey(block.FullID))
                        {
                            if (avclients[block.FullID] == "") { }
                            else
                            {
                                if (form.Display())
                                    FirstName = "(" + avclients[block.FullID] + ") " + FirstName;
                            }
                            namevalue.Value = FirstName;
                        }
                        else
                        {
                            blocks.Add(block.FullID, block);
                        }
                    }
                    else if (namevalue.Name == "LastName")
                    {
                        LastName = Convert.ToString(namevalue.Value);
                    }
                    else if (namevalue.Name == "Title")
                    {
                        Title = Convert.ToString(namevalue.Value);
                    }

                }

            }
            string newname = "";
            if (FirstName != null)
            {
                if (newname != "") newname += "\r\n";
                newname += "FirstName STRING RW SV " + FirstName;

            }
            if (LastName != null)
            {
                if (newname != "") newname += "\n";
                newname += "LastName STRING RW SV " + LastName;
            }
            if (Title != null)
            {
                if (newname != "") newname += "\r\n";
                newname += "Title STRING RW SV " + Title;
            }
            block.NameValue = Utils.StringToBytes(newname);
            //writethis("\n" + block.FullID.ToString() + "\n" + newname, ConsoleColor.White, ConsoleColor.Green);
            return block;
        }
Пример #8
0
        public Packet inObj(Packet packet, IPEndPoint sim)
        {
            string simIP = sim.ToString();
            if (!lastSim.Equals(simIP))
            {
                lastSim = simIP;
                avclients.Clear();
            }
            ObjectUpdatePacket ObjectUpdate = (ObjectUpdatePacket)packet;
            foreach (ObjectUpdatePacket.ObjectDataBlock block in ObjectUpdate.ObjectData)
            {
                if ((block.PCode == 0x2f) && (block.FullID!=frame.AgentID)) // Avatars only
                {
                    //writethis("\n\n-----------\n------\n---\n" + block.ToString(),ConsoleColor.White,ConsoleColor.DarkBlue);
                    string FirstName = null;
                    string LastName = null;
                    string Title = null;
                    #region decode name
                    if (block.NameValue != null)
                    {
                        if(local2global.ContainsKey(block.ID))
                        {
                            local2global[block.ID]=block.FullID;
                        }else
                        {
                            local2global.Add(block.ID,block.FullID);
                        }
                        string[] namevalues = Utils.BytesToString(block.NameValue).Split("\r\n".ToCharArray());
                        foreach (string line in namevalues)
                        {
                            NameValue namevalue = new NameValue(line);
                            if (namevalue.Value != null)
                            {
                                if (namevalue.Name == "FirstName")
                                {

                                    FirstName = Convert.ToString(namevalue.Value);
                                    if (avclients.ContainsKey(block.FullID))
                                    {
                                        if (avclients[block.FullID] == "") { }
                                        else
                                        {
                                            if(form.Display())
                                            FirstName = "(" + avclients[block.FullID] + ") " + FirstName;
                                        }
                                        namevalue.Value = FirstName;
                                    }
                                    else
                                    {
                                        if (!blocks.ContainsKey(block.FullID))
                                        {
                                            blocks.Add(block.FullID, block);
                                            rb = ObjectUpdate.RegionData;
                                        }
                                    }
                                }
                                else if (namevalue.Name == "LastName")
                                {
                                    LastName = Convert.ToString(namevalue.Value);
                                }
                                else if (namevalue.Name == "Title")
                                {
                                    Title = Convert.ToString(namevalue.Value);
                                }

                            }

                        }
                        string newname = "";
                        if (FirstName != null)
                        {
                            if (newname != "") newname += "\r\n";
                            newname += "FirstName STRING RW SV " + FirstName;

                        }
                        if (LastName != null)
                        {
                            if (newname != "") newname += "\n";
                            newname += "LastName STRING RW SV " + LastName;
                        }
                        if (Title != null)
                        {
                            if (newname != "") newname += "\n";
                            newname += "Title STRING RW SV " + Title;
                        }
                        block.NameValue = Utils.StringToBytes(newname);
                        //writethis("\n" + block.FullID.ToString() + "\n" + newname, ConsoleColor.White, ConsoleColor.DarkGreen);

                    }

                    #endregion

                }
            }
            return ObjectUpdate;
        }
Пример #9
0
 private void ObjectDataBlockUpdateHandler(Simulator simulator, Primitive prim, Primitive.ConstructionData constructionData, ObjectUpdatePacket.ObjectDataBlock block, ObjectUpdate update, NameValue[] nameValues)
 {
     // Note: We can't do membership or really much useful here since the
     // primitive doesn't have its information filled in quite yet.  Instead,
     // we're forced to use the OnNew* events, which get called *after* all
     // the data has been filled in.
     //Console.WriteLine("Object: " + update.LocalID.ToString() + " - " + update.Position.ToString() + " " + update.Velocity.ToString());
 }
Пример #10
0
        public static string NameValuesToString(NameValue[] values)
        {
            if (values == null || values.Length == 0)
                return String.Empty;

            StringBuilder output = new StringBuilder();

            for (int i = 0; i < values.Length; i++)
            {
                NameValue value = values[i];

                if (value.Value != null)
                {
                    string newLine = (i < values.Length - 1) ? "\n" : String.Empty;
                    output.AppendFormat("{0} {1} {2} {3} {4}{5}", value.Name, TypeStrings[(int)value.Type],
                        ClassStrings[(int)value.Class], SendtoStrings[(int)value.Sendto], value.Value.ToString(), newLine);
                }
            }

            return output.ToString();
        }
Пример #11
0
        public static string NameValuesToString(NameValue[] values)
        {
            if (values == null || values.Length == 0)
                return String.Empty;

            // Set the culture to en-US to print out values in the format SL is expecting them
            System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Threading.Thread.CurrentThread.CurrentCulture = Utils.EnUsCulture;

            StringBuilder output = new StringBuilder();

            for (int i = 0; i < values.Length; i++)
            {
                NameValue value = values[i];

                if (value.Value != null)
                {
                    string newLine = (i < values.Length - 1) ? "\n" : String.Empty;
                    output.AppendFormat("{0} {1} {2} {3} {4}{5}", value.Name, TypeStrings[(int)value.Type],
                        ClassStrings[(int)value.Class], SendtoStrings[(int)value.Sendto], value.Value.ToString(), newLine);
                }
            }

            // Set the culture back
            System.Threading.Thread.CurrentThread.CurrentCulture = culture;

            return output.ToString();
        }
Пример #12
0
        private Packet InObjectUpdateHandler(Packet packet, IPEndPoint sim)
        {
            string simIP = sim.ToString();
            ObjectUpdatePacket ObjectUpdate = (ObjectUpdatePacket)packet;
            foreach (ObjectUpdatePacket.ObjectDataBlock block in ObjectUpdate.ObjectData)
            {
                if (block.PCode == 0x2f) // Avatars only
                {
                    // If this simulator doesn't exist, create it
                    if (!SharedInfo.Aux_Simulators.ContainsKey(simIP))
                    {
                        SharedInfo.Aux_Simulators.Add(simIP, new PubComb.Aux_Simulator(simIP));
                    }

                    Vector3 position = new Vector3();
                    #region decode position
                    switch (block.ObjectData.Length)
                    {
                        case 76:
                            position = new Vector3(block.ObjectData, 16);
                            break;
                        case 60:
                            position = new Vector3(block.ObjectData, 0);
                            break;
                        case 32:
                            // The data is an array of unsigned shorts
                            position = new Vector3(
                                Utils.UInt16ToFloat(block.ObjectData, 0, -0.5f * 256.0f, 1.5f * 256.0f),
                                Utils.UInt16ToFloat(block.ObjectData, 2, -0.5f * 256.0f, 1.5f * 256.0f),
                                Utils.UInt16ToFloat(block.ObjectData, 4, -256.0f, 3.0f * 256.0f));
                            break;
                        case 16:
                            // The data is an array of single bytes (8-bit numbers)
                            position = new Vector3(
                                Utils.ByteToFloat(block.ObjectData, 0, -256.0f, 256.0f),
                                Utils.ByteToFloat(block.ObjectData, 1, -256.0f, 256.0f),
                                Utils.ByteToFloat(block.ObjectData, 2, -256.0f, 256.0f));
                            break;
                        default:
                            plugin.SayToUser("Couldn't decode position, the data was " + block.ObjectData.Length.ToString() + " bytes long.");
                            break;
                    }
                    #endregion

                    string FirstName = null;
                    string LastName = null;
                    #region decode name
                    if (block.NameValue != null)
                    {
                        string[] namevalues = Utils.BytesToString(block.NameValue).Split("\r\n".ToCharArray());
                        foreach (string line in namevalues)
                        {
                            NameValue namevalue = new NameValue(line);
                            if (namevalue.Value != null)
                            {
                                if (namevalue.Name == "FirstName")
                                {
                                    FirstName = Convert.ToString(namevalue.Value);
                                }
                                else if (namevalue.Name == "LastName")
                                {
                                    LastName = Convert.ToString(namevalue.Value);
                                }
                            }
                        }
                    }
                    string name = "";
                    if (FirstName != null) name += FirstName;
                    else name += "(Waiting)";
                    name += " ";
                    if (LastName != null) name += LastName;
                    else name += "(Waiting)";
                    #endregion

                    PubComb.Aux_Avatar avatar = new PubComb.Aux_Avatar(block.FullID, simIP, block.ID, name, position);
                    if (!SharedInfo.Aux_Simulators[simIP].Avatars.ContainsKey(block.FullID))
                    {
                        // Add avatar to simulator
                        SharedInfo.Aux_Simulators[simIP].Avatars.Add(block.FullID, avatar);

                         form.AddAvatar(avatar);
                    }
                    else
                    {
                        // Just update the avatar's position
                        SharedInfo.Aux_Simulators[simIP].Avatars[block.FullID].Position = position;
                         form.UpdateAvatar(avatar);
                    }
                    if (avatar.UUID == frame.AgentID)
                    {
                        SharedInfo.AgentName = name;
                        SharedInfo.AvPosition = position;
                    }
                }
            }
            return packet;
        }
Пример #13
0
 protected void FireOnObjectDataBlockUpdate(Simulator simulator, Primitive primitive, Primitive.ConstructionData data, ObjectUpdatePacket.ObjectDataBlock block, ObjectUpdate objectupdate, NameValue[] nameValue)
 {
     if (OnObjectDataBlockUpdate != null)
     {
         try { OnObjectDataBlockUpdate(simulator, primitive, data, block, objectupdate, nameValue); }
         catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
     }
 }
Пример #14
0
        public bool AgentAdd(object sender, Agent agent, PrimFlags creatorFlags)
        {
            // Sanity check, since this should have already been done
            agent.Avatar.Prim.ID = agent.Info.ID;

            // Check if the agent already exists in the scene
            lock (sceneAgents)
            {
                if (sceneAgents.ContainsKey(agent.ID))
                    sceneAgents.Remove(agent.ID);
            }

            // Update the current region handle
            agent.Avatar.Prim.RegionHandle = regionHandle;

            // Avatars always have physics
            agent.Avatar.Prim.Flags |= PrimFlags.Physics;

            // Default avatar values
            agent.Avatar.Prim.Position = new Vector3(128f, 128f, 25f);
            agent.Avatar.Prim.Rotation = Quaternion.Identity;
            agent.Avatar.Prim.Scale = new Vector3(0.45f, 0.6f, 1.9f);
            agent.Avatar.Prim.PrimData.Material = Material.Flesh;
            agent.Avatar.Prim.PrimData.PCode = PCode.Avatar;
            agent.Avatar.Prim.Textures = new Primitive.TextureEntry(new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"));

            // Set the avatar name
            NameValue[] name = new NameValue[2];
            name[0] = new NameValue("FirstName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite,
                NameValue.SendtoType.SimViewer, agent.Info.FirstName);
            name[1] = new NameValue("LastName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite,
                NameValue.SendtoType.SimViewer, agent.Info.LastName);
            agent.Avatar.Prim.NameValues = name;

            // Give testers a provisionary balance of 1000L
            agent.Info.Balance = 1000;

            // Some default avatar prim properties
            agent.Avatar.Prim.Properties = new Primitive.ObjectProperties();
            agent.Avatar.Prim.Properties.CreationDate = Utils.UnixTimeToDateTime(agent.Info.CreationTime);
            agent.Avatar.Prim.Properties.Name = agent.FullName;
            agent.Avatar.Prim.Properties.ObjectID = agent.ID;

            if (agent.Avatar.Prim.LocalID == 0)
            {
                // Assign a unique LocalID to this agent
                agent.Avatar.Prim.LocalID = (uint)Interlocked.Increment(ref currentLocalID);
            }

            if (OnAgentAdd != null)
                OnAgentAdd(sender, agent, creatorFlags);

            // Add the agent to the scene dictionary
            lock (sceneAgents) sceneAgents[agent.ID] = agent;

            Logger.Log("Added agent " + agent.FullName + " to the scene", Helpers.LogLevel.Info);

            return true;
        }
Пример #15
0
        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void ObjectUpdateCompressedHandler(object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.Packet;
            Simulator simulator = e.Simulator;

            ObjectUpdateCompressedPacket update = (ObjectUpdateCompressedPacket)packet;

            for (int b = 0; b < update.ObjectData.Length; b++)
            {
                ObjectUpdateCompressedPacket.ObjectDataBlock block = update.ObjectData[b];
                int i = 0;

                try
                {
                    // UUID
                    UUID FullID = new UUID(block.Data, 0);
                    i += 16;
                    // Local ID
                    uint LocalID = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                        (block.Data[i++] << 16) + (block.Data[i++] << 24));
                    // PCode
                    PCode pcode = (PCode)block.Data[i++];

                    #region Relevance check

                    if (!Client.Settings.ALWAYS_DECODE_OBJECTS)
                    {
                        switch (pcode)
                        {
                            case PCode.Grass:
                            case PCode.Tree:
                            case PCode.NewTree:
                            case PCode.Prim:
                                if (m_ObjectUpdate == null) continue;
                                break;
                        }
                    }

                    #endregion Relevance check

                    bool isNew;
                    lock (simulator.ObjectsPrimitives.Dictionary)
                        isNew = simulator.ObjectsPrimitives.ContainsKey(LocalID);

                    Primitive prim = GetPrimitive(simulator, LocalID, FullID);

                    prim.LocalID = LocalID;
                    prim.ID = FullID;
                    prim.Flags = (PrimFlags)block.UpdateFlags;
                    prim.PrimData.PCode = pcode;

                    #region Decode block and update Prim

                    // State
                    prim.PrimData.State = block.Data[i++];
                    // CRC
                    i += 4;
                    // Material
                    prim.PrimData.Material = (Material)block.Data[i++];
                    // Click action
                    prim.ClickAction = (ClickAction)block.Data[i++];
                    // Scale
                    prim.Scale = new Vector3(block.Data, i);
                    i += 12;
                    // Position
                    prim.Position = new Vector3(block.Data, i);
                    i += 12;
                    // Rotation
                    prim.Rotation = new Quaternion(block.Data, i, true);
                    i += 12;
                    // Compressed flags
                    CompressedFlags flags = (CompressedFlags)Utils.BytesToUInt(block.Data, i);
                    i += 4;

                    prim.OwnerID = new UUID(block.Data, i);
                    i += 16;

                    // Angular velocity
                    if ((flags & CompressedFlags.HasAngularVelocity) != 0)
                    {
                        prim.AngularVelocity = new Vector3(block.Data, i);
                        i += 12;
                    }

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

                    // Tree data
                    if ((flags & CompressedFlags.Tree) != 0)
                    {
                        prim.TreeSpecies = (Tree)block.Data[i++];
                        //prim.ScratchPad = Utils.EmptyBytes;
                    }
                    // Scratch pad
                    else if ((flags & CompressedFlags.ScratchPad) != 0)
                    {
                        prim.TreeSpecies = (Tree)0;

                        int size = block.Data[i++];
                        //prim.ScratchPad = new byte[size];
                        //Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size);
                        i += size;
                    }
                    prim.ScratchPad = Utils.EmptyBytes;

                    // Floating text
                    if ((flags & CompressedFlags.HasText) != 0)
                    {
                        string text = String.Empty;
                        while (block.Data[i] != 0)
                        {
                            text += (char)block.Data[i];
                            i++;
                        }
                        i++;

                        // Floating text
                        prim.Text = text;

                        // Text color
                        prim.TextColor = new Color4(block.Data, i, false);
                        i += 4;
                    }
                    else
                    {
                        prim.Text = String.Empty;
                    }

                    // Media URL
                    if ((flags & CompressedFlags.MediaURL) != 0)
                    {
                        string text = String.Empty;
                        while (block.Data[i] != 0)
                        {
                            text += (char)block.Data[i];
                            i++;
                        }
                        i++;

                        prim.MediaURL = text;
                    }

                    // Particle system
                    if ((flags & CompressedFlags.HasParticles) != 0)
                    {
                        prim.ParticleSys = new Primitive.ParticleSystem(block.Data, i);
                        i += 86;
                    }

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

                    //Sound data
                    if ((flags & CompressedFlags.HasSound) != 0)
                    {
                        prim.Sound = new UUID(block.Data, i);
                        i += 16;

                        prim.SoundGain = Utils.BytesToFloat(block.Data, i);
                        i += 4;
                        prim.SoundFlags = (SoundFlags)block.Data[i++];
                        prim.SoundRadius = Utils.BytesToFloat(block.Data, i);
                        i += 4;
                    }

                    // Name values
                    if ((flags & CompressedFlags.HasNameValues) != 0)
                    {
                        string text = String.Empty;
                        while (block.Data[i] != 0)
                        {
                            text += (char)block.Data[i];
                            i++;
                        }
                        i++;

                        // Parse the name values
                        if (text.Length > 0)
                        {
                            string[] lines = text.Split('\n');
                            prim.NameValues = new NameValue[lines.Length];

                            for (int j = 0; j < lines.Length; j++)
                            {
                                if (!String.IsNullOrEmpty(lines[j]))
                                {
                                    NameValue nv = new NameValue(lines[j]);
                                    prim.NameValues[j] = nv;
                                }
                            }
                        }
                    }

                    prim.PrimData.PathCurve = (PathCurve)block.Data[i++];
                    ushort pathBegin = Utils.BytesToUInt16(block.Data, i); i += 2;
                    prim.PrimData.PathBegin = Primitive.UnpackBeginCut(pathBegin);
                    ushort pathEnd = Utils.BytesToUInt16(block.Data, i); i += 2;
                    prim.PrimData.PathEnd = Primitive.UnpackEndCut(pathEnd);
                    prim.PrimData.PathScaleX = Primitive.UnpackPathScale(block.Data[i++]);
                    prim.PrimData.PathScaleY = Primitive.UnpackPathScale(block.Data[i++]);
                    prim.PrimData.PathShearX = Primitive.UnpackPathShear((sbyte)block.Data[i++]);
                    prim.PrimData.PathShearY = Primitive.UnpackPathShear((sbyte)block.Data[i++]);
                    prim.PrimData.PathTwist = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                    prim.PrimData.PathTwistBegin = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                    prim.PrimData.PathRadiusOffset = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                    prim.PrimData.PathTaperX = Primitive.UnpackPathTaper((sbyte)block.Data[i++]);
                    prim.PrimData.PathTaperY = Primitive.UnpackPathTaper((sbyte)block.Data[i++]);
                    prim.PrimData.PathRevolutions = Primitive.UnpackPathRevolutions(block.Data[i++]);
                    prim.PrimData.PathSkew = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);

                    prim.PrimData.profileCurve = block.Data[i++];
                    ushort profileBegin = Utils.BytesToUInt16(block.Data, i); i += 2;
                    prim.PrimData.ProfileBegin = Primitive.UnpackBeginCut(profileBegin);
                    ushort profileEnd = Utils.BytesToUInt16(block.Data, i); i += 2;
                    prim.PrimData.ProfileEnd = Primitive.UnpackEndCut(profileEnd);
                    ushort profileHollow = Utils.BytesToUInt16(block.Data, i); i += 2;
                    prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(profileHollow);

                    // TextureEntry
                    int textureEntryLength = (int)Utils.BytesToUInt(block.Data, i);
                    i += 4;
                    prim.Textures = new Primitive.TextureEntry(block.Data, i, textureEntryLength);
                    i += textureEntryLength;

                    // Texture animation
                    if ((flags & CompressedFlags.TextureAnimation) != 0)
                    {
                        //int textureAnimLength = (int)Utils.BytesToUIntBig(block.Data, i);
                        i += 4;
                        prim.TextureAnim = new Primitive.TextureAnimation(block.Data, i);
                    }

                    #endregion

                    #region Raise Events

                    bool isAttachment = (flags & CompressedFlags.HasNameValues) != 0 && prim.ParentID != 0;

                    OnObjectUpdate(new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNew, isAttachment));

                    #endregion
                }
                catch (IndexOutOfRangeException ex)
                {
                    Logger.Log("Error decoding an ObjectUpdateCompressed packet", Helpers.LogLevel.Warning, Client, ex);
                    Logger.Log(block, Helpers.LogLevel.Warning);
                }
            }
        }
Пример #16
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="simulator"></param>
        protected void CompressedUpdateHandler(Packet packet, Simulator simulator)
        {
            ObjectUpdateCompressedPacket update = (ObjectUpdateCompressedPacket)packet;

            for (int b = 0; b < update.ObjectData.Length; b++)
            {
                ObjectUpdateCompressedPacket.ObjectDataBlock block = update.ObjectData[b];
                int i = 0;

                try
                {
                    // UUID
                    UUID FullID = new UUID(block.Data, 0);
                    i += 16;
                    // Local ID
                    uint LocalID = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                        (block.Data[i++] << 16) + (block.Data[i++] << 24));
                    // PCode
                    PCode pcode = (PCode)block.Data[i++];

                    #region Relevance check
                    if (!Client.Settings.ALWAYS_DECODE_OBJECTS)
                    {
                        switch (pcode)
                        {
                            case PCode.Grass:
                            case PCode.Tree:
                            case PCode.NewTree:
                                if (OnNewFoliage == null) continue;
                                break;
                            case PCode.Prim:
                                if (OnNewPrim == null) continue;
                                break;
                        }
                    }
                    #endregion Relevance check

                    Primitive prim = GetPrimitive(simulator, LocalID, FullID);

                    prim.LocalID = LocalID;
                    prim.ID = FullID;
                    prim.Flags = (PrimFlags)block.UpdateFlags;
                    prim.PrimData.PCode = pcode;

                    switch (pcode)
                    {
                        case PCode.Grass:
                        case PCode.Tree:
                        case PCode.NewTree:
                            #region Foliage Decoding

                            // State
                            prim.PrimData.State = block.Data[i++];
                            // CRC
                            i += 4;
                            // Material
                            prim.PrimData.Material = (Material)block.Data[i++];
                            // Click action
                            prim.ClickAction = (ClickAction)block.Data[i++];
                            // Scale
                            prim.Scale = new Vector3(block.Data, i);
                            i += 12;
                            // Position
                            prim.Position = new Vector3(block.Data, i);
                            i += 12;
                            // Rotation
                            prim.Rotation = new Quaternion(block.Data, i, true);
                            i += 12;

                            #endregion Foliage Decoding

                            // FIXME: We are leaving a lot of data left undecoded here, including the
                            // tree species. Need to understand what is going on with these packets
                            // and fix it soon!

                            FireOnNewFoliage(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);

                            break;
                        case PCode.Prim:
                            #region Decode block and update Prim
                            // State
                            prim.PrimData.State = block.Data[i++];
                            // CRC
                            i += 4;
                            // Material
                            prim.PrimData.Material = (Material)block.Data[i++];
                            // Click action
                            prim.ClickAction = (ClickAction)block.Data[i++];
                            // Scale
                            prim.Scale = new Vector3(block.Data, i);
                            i += 12;
                            // Position
                            prim.Position = new Vector3(block.Data, i);
                            i += 12;
                            // Rotation
                            prim.Rotation = new Quaternion(block.Data, i, true);
                            i += 12;
                            // Compressed flags
                            CompressedFlags flags = (CompressedFlags)Utils.BytesToUInt(block.Data, i);
                            i += 4;

                            prim.OwnerID = new UUID(block.Data, i);
                            i += 16;

                            // Angular velocity
                            if ((flags & CompressedFlags.HasAngularVelocity) != 0)
                            {
                                prim.AngularVelocity = new Vector3(block.Data, i);
                                i += 12;
                            }

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

                            // Tree data
                            if ((flags & CompressedFlags.Tree) != 0)
                            {
                                prim.GenericData = new byte[1];
                                prim.GenericData[0] = block.Data[i++];
                            }
                            // Scratch pad
                            else if ((flags & CompressedFlags.ScratchPad) != 0)
                            {
                                int size = block.Data[i++];
                                prim.GenericData = new byte[size];
                                Buffer.BlockCopy(block.Data, i, prim.GenericData, 0, size);
                                i += size;
                            }

                            // Floating text
                            if ((flags & CompressedFlags.HasText) != 0)
                            {
                                string text = String.Empty;
                                while (block.Data[i] != 0)
                                {
                                    text += (char)block.Data[i];
                                    i++;
                                }
                                i++;

                                // Floating text
                                prim.Text = text;

                                // Text color
                                prim.TextColor = new Color4(block.Data, i, false);
                                // FIXME: Is alpha inversed here as well?
                                i += 4;
                            }
                            else
                            {
                                prim.Text = String.Empty;
                            }

                            // Media URL
                            if ((flags & CompressedFlags.MediaURL) != 0)
                            {
                                string text = String.Empty;
                                while (block.Data[i] != 0)
                                {
                                    text += (char)block.Data[i];
                                    i++;
                                }
                                i++;

                                prim.MediaURL = text;
                            }

                            // Particle system
                            if ((flags & CompressedFlags.HasParticles) != 0)
                            {
                                prim.ParticleSys = new Primitive.ParticleSystem(block.Data, i);
                                i += 86;
                            }

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

                            //Sound data
                            if ((flags & CompressedFlags.HasSound) != 0)
                            {
                                prim.Sound = new UUID(block.Data, i);
                                i += 16;

                                prim.SoundGain = Utils.BytesToFloat(block.Data, i);
                                i += 4;
                                prim.SoundFlags = block.Data[i++];
                                prim.SoundRadius = Utils.BytesToFloat(block.Data, i);
                                i += 4;
                            }

                            // Name values
                            if ((flags & CompressedFlags.HasNameValues) != 0)
                            {
                                string text = String.Empty;
                                while (block.Data[i] != 0)
                                {
                                    text += (char)block.Data[i];
                                    i++;
                                }
                                i++;

                                // Parse the name values
                                if (text.Length > 0)
                                {
                                    string[] lines = text.Split('\n');
                                    prim.NameValues = new NameValue[lines.Length];

                                    for (int j = 0; j < lines.Length; j++)
                                    {
                                        if (!String.IsNullOrEmpty(lines[j]))
                                        {
                                            NameValue nv = new NameValue(lines[j]);
                                            prim.NameValues[j] = nv;
                                        }
                                    }
                                }
                            }

                            prim.PrimData.PathCurve = (PathCurve)block.Data[i++];
                            ushort pathBegin = Utils.BytesToUInt16(block.Data, i); i += 2;
                            prim.PrimData.PathBegin = Primitive.UnpackBeginCut(pathBegin);
                            ushort pathEnd = Utils.BytesToUInt16(block.Data, i); i += 2;
                            prim.PrimData.PathEnd = Primitive.UnpackEndCut(pathEnd);
                            prim.PrimData.PathScaleX = Primitive.UnpackPathScale(block.Data[i++]);
                            prim.PrimData.PathScaleY = Primitive.UnpackPathScale(block.Data[i++]);
                            prim.PrimData.PathShearX = Primitive.UnpackPathShear((sbyte)block.Data[i++]);
                            prim.PrimData.PathShearY = Primitive.UnpackPathShear((sbyte)block.Data[i++]);
                            prim.PrimData.PathTwist = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                            prim.PrimData.PathTwistBegin = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                            prim.PrimData.PathRadiusOffset = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);
                            prim.PrimData.PathTaperX = Primitive.UnpackPathTaper((sbyte)block.Data[i++]);
                            prim.PrimData.PathTaperY = Primitive.UnpackPathTaper((sbyte)block.Data[i++]);
                            prim.PrimData.PathRevolutions = Primitive.UnpackPathRevolutions(block.Data[i++]);
                            prim.PrimData.PathSkew = Primitive.UnpackPathTwist((sbyte)block.Data[i++]);

                            prim.PrimData.profileCurve = block.Data[i++];
                            ushort profileBegin = Utils.BytesToUInt16(block.Data, i); i += 2;
                            prim.PrimData.ProfileBegin = Primitive.UnpackBeginCut(profileBegin);
                            ushort profileEnd = Utils.BytesToUInt16(block.Data, i); i += 2;
                            prim.PrimData.ProfileEnd = Primitive.UnpackEndCut(profileEnd);
                            ushort profileHollow = Utils.BytesToUInt16(block.Data, i); i += 2;
                            prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(profileHollow);

                            // TextureEntry
                            int textureEntryLength = (int)Utils.BytesToUInt(block.Data, i);
                            i += 4;
                            prim.Textures = new Primitive.TextureEntry(block.Data, i, textureEntryLength);
                            i += textureEntryLength;

                            // Texture animation
                            if ((flags & CompressedFlags.TextureAnimation) != 0)
                            {
                                //int textureAnimLength = (int)Utils.BytesToUIntBig(block.Data, i);
                                i += 4;
                                prim.TextureAnim = new Primitive.TextureAnimation(block.Data, i);
                            }

                            #endregion

                            #region Fire Events

                            // Fire the appropriate callback
                            if ((flags & CompressedFlags.HasNameValues) != 0 && prim.ParentID != 0)
                                FireOnNewAttachment(simulator, prim, update.RegionData.RegionHandle,
                                    update.RegionData.TimeDilation);
                            else if ((flags & CompressedFlags.Tree) != 0)
                                FireOnNewFoliage(simulator, prim, update.RegionData.RegionHandle,
                                    update.RegionData.TimeDilation);
                            else
                                FireOnNewPrim(simulator, prim, update.RegionData.RegionHandle,
                                    update.RegionData.TimeDilation);

                            #endregion

                            break;
                        default:
                            Logger.DebugLog("Got an ObjectUpdateCompressed for PCode " + pcode.ToString() +
                                ", implement this!", Client);
                            break;
                    }
                }
                catch (IndexOutOfRangeException e)
                {
                    Logger.Log("Error decoding an ObjectUpdateCompressed packet", Helpers.LogLevel.Warning, Client, e);
                    Logger.Log(block, Helpers.LogLevel.Warning);
                }
            }
        }
Пример #17
0
 public ObjectDataBlockUpdateEventArgs(Simulator simulator, Primitive prim, Primitive.ConstructionData constructionData,
     ObjectUpdatePacket.ObjectDataBlock block, ObjectMovementUpdate objectupdate, NameValue[] nameValues)
 {
     this.m_Simulator = simulator;
     this.m_Prim = prim;
     this.m_ConstructionData = constructionData;
     this.m_Block = block;
     this.m_Update = objectupdate;
     this.m_NameValues = nameValues;
 }
Пример #18
0
        /// <summary>
        /// Used for new prims, or significant changes to existing prims
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="simulator"></param>
        protected void UpdateHandler(Packet packet, Simulator simulator)
        {
            ObjectUpdatePacket update = (ObjectUpdatePacket)packet;
			UpdateDilation(simulator, update.RegionData.TimeDilation);

            for (int b = 0; b < update.ObjectData.Length; b++)
            {
                ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b];

                Vector4 collisionPlane = Vector4.Zero;
                Vector3 position;
                Vector3 velocity;
                Vector3 acceleration;
                Quaternion rotation;
                Vector3 angularVelocity;
                NameValue[] nameValues;
                bool attachment = false;
                PCode pcode = (PCode)block.PCode;

                #region Relevance check

                // Check if we are interested in this object
                if (!Client.Settings.ALWAYS_DECODE_OBJECTS)
                {
                    switch (pcode)
                    {
                        case PCode.Grass:
                        case PCode.Tree:
                        case PCode.NewTree:
                            if (OnNewFoliage == null) continue;
                            break;
                        case PCode.Prim:
                            if (OnNewPrim == null) continue;
                            break;
                        case PCode.Avatar:
                            // Make an exception for updates about our own agent
                            if (block.FullID != Client.Self.AgentID && OnNewAvatar == null) continue;
                            break;
                        case PCode.ParticleSystem:
                            continue; // TODO: Do something with these
                    }
                }

                #endregion Relevance check

                #region NameValue parsing

                string nameValue = Helpers.FieldToUTF8String(block.NameValue);
                if (nameValue.Length > 0)
                {
                    string[] lines = nameValue.Split('\n');
                    nameValues = new NameValue[lines.Length];

                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (!String.IsNullOrEmpty(lines[i]))
                        {
                            NameValue nv = new NameValue(lines[i]);
                            if (nv.Name == "AttachItemID") attachment = true;
                            nameValues[i] = nv;
                        }
                    }
                }
                else
                {
                    nameValues = new NameValue[0];
                }

                #endregion NameValue parsing

                #region Decode Object (primitive) parameters
                LLObject.ObjectData data = new LLObject.ObjectData();
                data.State = block.State;
                data.Material = (LLObject.MaterialType)block.Material;
                data.PathCurve = (LLObject.PathCurve)block.PathCurve;
                data.profileCurve = block.ProfileCurve;
                data.PathBegin = LLObject.UnpackBeginCut(block.PathBegin);
                data.PathEnd = LLObject.UnpackEndCut(block.PathEnd);
                data.PathScaleX = LLObject.UnpackPathScale(block.PathScaleX);
                data.PathScaleY = LLObject.UnpackPathScale(block.PathScaleY);
                data.PathShearX = LLObject.UnpackPathShear((sbyte)block.PathShearX);
                data.PathShearY = LLObject.UnpackPathShear((sbyte)block.PathShearY);
                data.PathTwist = LLObject.UnpackPathTwist(block.PathTwist);
                data.PathTwistBegin = LLObject.UnpackPathTwist(block.PathTwistBegin);
                data.PathRadiusOffset = LLObject.UnpackPathTwist(block.PathRadiusOffset);
                data.PathTaperX = LLObject.UnpackPathTaper(block.PathTaperX);
                data.PathTaperY = LLObject.UnpackPathTaper(block.PathTaperY);
                data.PathRevolutions = LLObject.UnpackPathRevolutions(block.PathRevolutions);
                data.PathSkew = LLObject.UnpackPathTwist(block.PathSkew);
                data.ProfileBegin = LLObject.UnpackBeginCut(block.ProfileBegin);
                data.ProfileEnd = LLObject.UnpackEndCut(block.ProfileEnd);
                data.ProfileHollow = LLObject.UnpackProfileHollow(block.ProfileHollow);
                data.PCode = pcode;
                #endregion

                #region Decode Additional packed parameters in ObjectData
                int pos = 0;
                switch (block.ObjectData.Length)
                {
                    case 76:
                        // Collision normal for avatar
                        collisionPlane = new Vector4(block.ObjectData, pos);
                        pos += 16;

                        goto case 60;
                    case 60:
                        // Position
                        position = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Velocity
                        velocity = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Acceleration
                        acceleration = new Vector3(block.ObjectData, pos);
                        pos += 12;
                        // Rotation (theta)
                        rotation = new Quaternion(block.ObjectData, pos, true);
                        pos += 12;
                        // Angular velocity (omega)
                        angularVelocity = new Vector3(block.ObjectData, pos);
                        pos += 12;

                        break;
                    case 48:
                        // Collision normal for avatar
                        collisionPlane = new Vector4(block.ObjectData, pos);
                        pos += 16;

                        goto case 32;
                    case 32:
                        // The data is an array of unsigned shorts

                        // Position
                        position = new Vector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f));
                        pos += 6;
                        // Velocity
                        velocity = new Vector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Acceleration
                        acceleration = new Vector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Rotation (theta)
                        rotation = new Quaternion(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f));
                        pos += 8;
                        // Angular velocity (omega)
                        angularVelocity = new Vector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;

                        break;
                    case 16:
                        // The data is an array of single bytes (8-bit numbers)

                        // Position
                        position = new Vector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Velocity
                        velocity = new Vector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Accleration
                        acceleration = new Vector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Rotation
                        rotation = new Quaternion(
                            Helpers.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f));
                        pos += 4;
                        // Angular Velocity
                        angularVelocity = new Vector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;

                        break;
                    default:
                        Logger.Log("Got an ObjectUpdate block with ObjectUpdate field length of " +
                            block.ObjectData.Length, Helpers.LogLevel.Warning, Client);

                        continue;
                }
                #endregion

                // Determine the object type and create the appropriate class
                switch (pcode)
                {
                    #region Prim and Foliage
                    case PCode.Grass:
                    case PCode.Tree:
                    case PCode.NewTree:
                    case PCode.Prim:
                        Primitive prim = GetPrimitive(simulator, block.ID, block.FullID);

                        #region Update Prim Info with decoded data                            
                        prim.Flags = (LLObject.ObjectFlags)block.UpdateFlags;

                        if ((prim.Flags & LLObject.ObjectFlags.ZlibCompressed) != 0)
                        {
                            Logger.Log("Got a ZlibCompressed ObjectUpdate, implement me!", 
                                Helpers.LogLevel.Warning, Client);
                            continue;
                        }

                        // Automatically request ObjectProperties for prim if it was rezzed selected.
                        if ((prim.Flags & LLObject.ObjectFlags.CreateSelected) == LLObject.ObjectFlags.CreateSelected)
                            SelectObject(simulator, prim.LocalID);

                        prim.NameValues = nameValues;
                        prim.LocalID = block.ID;
                        prim.ID = block.FullID;
                        prim.ParentID = block.ParentID;
					    prim.RegionHandle = update.RegionData.RegionHandle;
                        prim.Scale = block.Scale;
                        prim.ClickAction = (ClickAction)block.ClickAction;
                        prim.OwnerID = block.OwnerID;
                        prim.MediaURL = Helpers.FieldToUTF8String(block.MediaURL);
                        prim.Text = Helpers.FieldToUTF8String(block.Text);
                        prim.TextColor = new Color4(block.TextColor, 0, false, true);

                        // Sound information
                        prim.Sound = block.Sound;
                        prim.SoundFlags = block.Flags;
                        prim.SoundGain = block.Gain;
                        prim.SoundRadius = block.Radius;

                        // Joint information
                        prim.Joint = (Primitive.JointType)block.JointType;
                        prim.JointPivot = block.JointPivot;
                        prim.JointAxisOrAnchor = block.JointAxisOrAnchor;
                        
                        // Object parameters
                        prim.Data = data;

                        // Textures, texture animations, particle system, and extra params
                        prim.Textures = new LLObject.TextureEntry(block.TextureEntry, 0,
                            block.TextureEntry.Length);

                        prim.TextureAnim = new Primitive.TextureAnimation(block.TextureAnim, 0);
                        prim.ParticleSys = new Primitive.ParticleSystem(block.PSBlock, 0);
                        prim.SetExtraParamsFromBytes(block.ExtraParams, 0);

                        // PCode-specific data
                        prim.GenericData = block.Data;

                        // Packed parameters
                        prim.CollisionPlane = collisionPlane;
                        prim.Position = position;
                        prim.Velocity = velocity;
                        prim.Acceleration = acceleration;
                        prim.Rotation = rotation;
                        prim.AngularVelocity = angularVelocity;
                        #endregion

                        if (attachment)
                            FireOnNewAttachment(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);
                        else if (pcode == PCode.Prim)
                            FireOnNewPrim(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);
                        else
                            FireOnNewFoliage(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);

                        break;
                    #endregion Prim and Foliage
                    #region Avatar
                    case PCode.Avatar:
                        // Update some internals if this is our avatar
                        if (block.FullID == Client.Self.AgentID)
                        {
                            #region Update Client.Self
                            
                            // We need the local ID to recognize terse updates for our agent
                            Client.Self.localID = block.ID;
                            
                            // Packed parameters
                            Client.Self.collisionPlane = collisionPlane;
                            Client.Self.relativePosition = position;
                            Client.Self.velocity = velocity;
                            Client.Self.acceleration = acceleration;
                            Client.Self.relativeRotation = rotation;
                            Client.Self.angularVelocity = angularVelocity;

                            #endregion
                        }

                        #region Create an Avatar from the decoded data

                        Avatar avatar = GetAvatar(simulator, block.ID, block.FullID);
                        uint oldSeatID = avatar.sittingOn;

                        avatar.ID = block.FullID;
                        avatar.LocalID = block.ID;
                        avatar.CollisionPlane = collisionPlane;
                        avatar.Position = position;
                        avatar.Velocity = velocity;
                        avatar.Acceleration = acceleration;
                        avatar.Rotation = rotation;
                        avatar.AngularVelocity = angularVelocity;
                        avatar.NameValues = nameValues;
                        avatar.Data = data;
                        avatar.GenericData = block.Data;
                        avatar.sittingOn = block.ParentID;

                        SetAvatarSittingOn(simulator, avatar, block.ParentID, oldSeatID);

                        // Set the current simulator for this avatar
                        avatar.CurrentSim = simulator;

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

                        #endregion Create an Avatar from the decoded data

                        FireOnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, 
                            update.RegionData.TimeDilation);

                        break;
                    #endregion Avatar
                    case PCode.ParticleSystem:
                        DecodeParticleUpdate(block);
                        // TODO: Create a callback for particle updates
                        break;
                    default:
                        Logger.DebugLog("Got an ObjectUpdate block with an unrecognized PCode " + pcode.ToString(), Client);
                        break;
                }
            }
        }