Ejemplo n.º 1
0
        public void Deserialize(XmlAttribute xml)
        {
            var name = xml.Name;

            if (name[0] == '_')
            {
                Hash = int.Parse(name.Substring(1), NumberStyles.HexNumber);
            }
            else
            {
                // known attribute :)
                Name = name;
            }

            var type = AttributeTypes.GetType(Hash);

            // try resolving the full name, e.g. 'Class.bProperty'
            var fullHash = StringHasher.GetHash(FullName);

            if (fullHash != Hash)
            {
                if (AttributeTypes.IsTypeKnown(fullHash))
                {
                    type = AttributeTypes.GetType(fullHash);
                }
            }

            Data = new AttributeData(type, xml.Value);

            // looks to be part of the spec :/
            //if (Data.Type != type)
            //    Debug.WriteLine($"Attribute '{FullName}' was created as a '{type.ToString()}' but was actually a '{Data.Type.ToString()}'!");
        }
Ejemplo n.º 2
0
        public StringId(string name)
        {
            m_Length = name.Length;

            m_Hash = StringHasher.GetHash(name);
            m_Name = name;
        }
Ejemplo n.º 3
0
        public static void RegisterType(string name, DataType type)
        {
            var hash = StringHasher.GetHash(name);

            if (!m_userTypes.ContainsKey(hash))
            {
                m_userTypes.Add(hash, type);
            }
        }
Ejemplo n.º 4
0
        public void Deserialize(BinaryStream stream, bool readHash)
        {
            if (readHash)
            {
                var hash = stream.ReadInt32();

                var name = StringHasher.ResolveHash(hash);
                var type = AttributeTypes.GetType(hash);

                // cannot be null or contain spaces
                var nameResolved = ((name != null) && !name.Contains(" "));

                if (nameResolved)
                {
                    Name = name;
                }
                else
                {
                    Hash = hash;
                }

                // try resolving the full name, e.g. 'Class.bProperty'
                var fullHash = StringHasher.GetHash(FullName);

                if (fullHash != hash)
                {
                    if (AttributeTypes.IsTypeKnown(fullHash))
                    {
                        type = AttributeTypes.GetType(fullHash);
                    }
                }

                Data = new AttributeData(type);
            }
            else
            {
                Deserialize(stream);
            }
        }
Ejemplo n.º 5
0
        public void Deserialize(NodeClass node)
        {
            if (node.Attributes.Count > 0)
            {
                foreach (var attr in node.Attributes)
                {
                    if (attr.Hash == StringHasher.GetHash("Name"))
                    {
                        Name = attr.Data.ToString();
                        break;
                    }
                }
            }

            var nChildren = node.Children.Count;

            Entries = new List <EntityReference>(nChildren);

            // _256A1FF9 nodes
            foreach (var group in node.Children)
            {
                if (group.Children.Count != 1)
                {
                    throw new InvalidOperationException("Houston, we got a bit of a problem...");
                }

                var entry = new EntityReference()
                {
                    Use32Bit   = Use32Bit,
                    GroupNode  = group,
                    EntityNode = group.Children[0],
                };

                Entries.Add(entry);
            }
        }
Ejemplo n.º 6
0
        public static byte[] Parse(string s, ref DataType type)
        {
            if (s.Length == 0)
            {
                // the following MUST have a null terminator!
                switch (type)
                {
                case DataType.String:
                case DataType.RML:
                    return(new byte[1] {
                        0
                    });
                }

                switch (type)
                {
                case DataType.StringId:
                case DataType.PathId:
                    type = DataType.BinHex;
                    return(BitConverter.GetBytes(-1));
                }

                // for others, the resulting buffer can be empty
                return(new byte[0]);
            }

            switch (type)
            {
            case DataType.Bool:
            case DataType.Byte:
            {
                var value = byte.Parse(s);
                return(new byte[1] {
                        value
                    });
            }

            case DataType.Int16:
            {
                var value = short.Parse(s);
                return(BitConverter.GetBytes(value));
            }

            case DataType.UInt16:
            {
                var value = ushort.Parse(s);
                return(BitConverter.GetBytes(value));
            }

            case DataType.Int32:
            {
                var value = int.Parse(s);
                return(BitConverter.GetBytes(value));
            }

            case DataType.UInt32:
            {
                var value = uint.Parse(s);
                return(BitConverter.GetBytes(value));
            }

            case DataType.Float:
            {
                var value = float.Parse(s);
                return(BitConverter.GetBytes(value));
            }

            case DataType.Vector2:
            case DataType.Vector3:
            case DataType.Vector4:
            {
                var vals = s.Split(',');

                if (vals.Length < 2)
                {
                    throw new InvalidOperationException($"Invalid vector value '{s}'");
                }

                var fVals = new float[4];

                for (int i = 0; i < vals.Length; i++)
                {
                    fVals[i] = float.Parse(vals[i]);
                }

                var nVals = 0;

                if (type == DataType.Vector2)
                {
                    nVals = 2;
                }
                if (type == DataType.Vector3)
                {
                    nVals = 3;
                }
                if (type == DataType.Vector4)
                {
                    nVals = 4;
                }

                var buffer = new byte[nVals * 4];

                for (int v = 0; v < nVals; v++)
                {
                    var f = BitConverter.GetBytes(fVals[v]);
                    System.Buffer.BlockCopy(f, 0, buffer, (v * 4), 4);
                }

                return(buffer);
            }

            case DataType.RML:
                return(Utils.GetStringBuffer(s));
            }

            switch (s[0])
            {
            // StringId
            case '$':
                var str  = s.Substring(1);
                var hash = StringHasher.GetHash(str);

                StringHasher.AddToLookup(str);

                type = DataType.StringId;

                return(BitConverter.GetBytes(hash));

            // BinHex
            case '#':
            {
                if (Utils.IsHexString(s))
                {
                    type = DataType.BinHex;

                    return(Utils.HexString2Bytes(s));
                }
            } break;

            // Array
            case '[':
            {
                // strip the braces
                var aryStr  = s.Substring(1, s.Length - 2);
                var aryVals = aryStr.Split(',');

                var count = aryVals.Length;

                var offset = 0;
                var size   = -1;

                byte[] buffer = null;

                for (int i = 0; i < count; i++)
                {
                    var aryVal = aryVals[i];

                    var value = Utils.HexString2Bytes(aryVal);

                    if (buffer == null)
                    {
                        size   = value.Length;
                        buffer = new byte[(count * size) + 4];

                        var cBuf = BitConverter.GetBytes(count);

                        System.Buffer.BlockCopy(cBuf, 0, buffer, 0, 4);
                        offset = 4;
                    }
                    else
                    {
                        if (value.Length != size)
                        {
                            throw new InvalidDataException("Array element size mismatch!");
                        }
                    }

                    System.Buffer.BlockCopy(value, 0, buffer, offset, size);
                    offset += size;
                }

                return(buffer);
            }
            }

            if (Utils.IsHexString(s))
            {
                return(Utils.HexString2Bytes(s));
            }

            // return as string
            type = DataType.String;

            // if it's a StringId, require '$' prefix
            if (type == DataType.StringId)
            {
                throw new InvalidDataException("Malformed StringId -- string must have a prefix!");
            }

            return(Utils.GetStringBuffer(s));
        }
Ejemplo n.º 7
0
        private static bool RegisterTypeToLookup(TypeLookup lookup, string name, int hash, DataType type)
        {
            if (name != null)
            {
                if (hash != -1)
                {
                    // add manual lookup
                    StringHasher.AddToLookup(hash, name);
                }
                else
                {
                    hash = StringHasher.GetHash(name);

                    // try adding this to the lookup
                    if (!StringHasher.CanResolveHash(hash))
                    {
                        Debug.WriteLine($"- Adding '{name}' to lookup");
                        StringHasher.AddToLookup(name);
                    }
                }

                if (!lookup.ContainsKey(hash))
                {
                    lookup.Add(hash, type);
                }

                var id       = name;
                var parentId = "";

                var splitIdx = name.LastIndexOf('.');

                if (splitIdx != -1)
                {
                    parentId = name.Substring(0, splitIdx);
                    id       = name.Substring(splitIdx + 1);

                    StringHasher.AddToLookup(parentId);
                    StringHasher.AddToLookup(id);
                }

                // auto-register accompanying "text_*" string
                if ((type == DataType.StringId) || (type == DataType.PathId))
                {
                    id = $"text_{id}";

                    if (!String.IsNullOrEmpty(parentId))
                    {
                        id = $"{parentId}.{id}";
                    }

                    RegisterTypeToLookup(lookup, id, -1, DataType.String);
                }
            }
            else
            {
                // empty attribute!?
                if (hash == -1)
                {
                    return(false);
                }

                //--var canResolve = StringHasher.CanResolveHash(hash);
                //--
                //--name = (canResolve)
                //--    ? StringHasher.ResolveHash(hash)
                //--    : $"_{hash:X8}";
                //--
                //--if (canResolve)
                //--{
                //--    if (IsTypeKnown(hash))
                //--    {
                //--        var knownType = GetType(hash);
                //--
                //--        //WriteUniqueHint($"<!-- Remove: --><Attribute Hash=\"{attrHash:X8}\" Type=\"{attrType.ToString()}\" /><!-- SameAs --><Attribute Name=\"{name}\" Type=\"{knownType.ToString()}\" />");
                //--    }
                //--    else
                //--    {
                //--        //WriteUniqueHint($"<!-- Rename: --><Attribute Hash=\"{attrHash:X8}\" Type=\"{attrType.ToString()}\" /><!-- EqualTo --><Attribute Name=\"{name}\" Type=\"{attrType.ToString()}\" />");
                //--    }
                //--}

                if (!lookup.ContainsKey(hash))
                {
                    lookup.Add(hash, type);
                }
            }

            return(true);
        }