コード例 #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()}'!");
        }
コード例 #2
0
ファイル: StringId.cs プロジェクト: DrTexx/DisruptEd
        public StringId(string name)
        {
            m_Length = name.Length;

            m_Hash = StringHasher.GetHash(name);
            m_Name = name;
        }
コード例 #3
0
ファイル: AttributeTypes.cs プロジェクト: DrTexx/DisruptEd
        public static void RegisterType(string name, DataType type)
        {
            var hash = StringHasher.GetHash(name);

            if (!m_userTypes.ContainsKey(hash))
            {
                m_userTypes.Add(hash, type);
            }
        }
コード例 #4
0
ファイル: StringId.cs プロジェクト: DrTexx/DisruptEd
        public static StringId Parse(int hash)
        {
            StringId result = hash;
            var      name   = String.Empty;

            if (StringHasher.TryResolveHash(result, out name))
            {
                result = name;
            }

            return(result);
        }
コード例 #5
0
        public string ToStringId()
        {
            var value   = ToInt32();
            var hashStr = StringHasher.ResolveHash(value);

            if (hashStr != null)
            {
                return(String.Concat("$", hashStr));
            }

            return((value != 0)
                ? ToHexString()
                : String.Empty);
        }
コード例 #6
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);
            }
        }
コード例 #7
0
ファイル: EntityLibrary.cs プロジェクト: DrTexx/DisruptEd
        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);
            }
        }
コード例 #8
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));
        }
コード例 #9
0
ファイル: NodeObject.cs プロジェクト: DrTexx/DisruptEd
        public void Deserialize(BinaryStream stream, List <NodeObject> objRefs)
        {
            Offset = (int)stream.Position;

            // define reference type just in case we f**k up somehow
            var nD = DescriptorTag.Read(stream, ReferenceType.Index);

            if (nD.Type == DescriptorType.Reference)
            {
                throw new InvalidOperationException("Cannot deserialize an object reference directly!");
            }

            var nChildren = nD.Value;

            Children = new List <NodeObject>(nChildren);

            var hash = stream.ReadInt32();
            var name = StringHasher.ResolveHash(hash);

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

            // add a reference to this object
            objRefs.Add(this);

            var aD     = DescriptorTag.Read(stream, ReferenceType.Index);
            var nAttrs = aD.Value;

            Attributes = new List <NodeAttribute>(nAttrs);

            if (nAttrs > 0)
            {
                for (int i = 0; i < nAttrs; i++)
                {
                    // hash and data inline
                    var attr = new NodeAttribute(stream, Name);
                    attr.Deserialize(stream);

                    Attributes.Add(attr);
                }
            }

            if (nChildren > 0)
            {
                // read children
                for (int n = 0; n < nChildren; n++)
                {
                    var cP = (int)stream.Position;
                    var cD = DescriptorTag.Read(stream, ReferenceType.Index);

                    // rip
                    if (cD.IsIndex)
                    {
                        var idx      = cD.Value;
                        var childRef = objRefs[idx];

                        Children.Add(childRef);
                    }
                    else
                    {
                        // move back
                        stream.Position = cP;

                        var child = new NodeObject(stream, objRefs);
                        Children.Add(child);
                    }
                }
            }
        }
コード例 #10
0
ファイル: AttributeTypes.cs プロジェクト: DrTexx/DisruptEd
        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);
        }
コード例 #11
0
ファイル: NodeClass.cs プロジェクト: DrTexx/DisruptEd
        public override void Deserialize(BinaryStream stream)
        {
            var ptr = (int)stream.Position;

            var nD = DescriptorTag.Read(stream, ReferenceType.Offset);

            if (nD.IsOffset)
            {
                stream.Position = nD.Value;
                Deserialize(stream);

                stream.Position = (ptr + nD.Size);
            }
            else
            {
                Offset = ptr;

                var nChildren = nD.Value;

                Children = new List <NodeClass>(nChildren);

                var hash = stream.ReadInt32();
                var size = stream.ReadInt16();

                var name = StringHasher.ResolveHash(hash);

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

                var attrsPtr = (int)stream.Position;
                var next     = (attrsPtr + size);

                if (size != 0)
                {
                    var nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                    var adjustPtr = false;

                    if (nhD.IsOffset)
                    {
                        stream.Position = nhD.Value;

                        // read again
                        nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                        if (nhD.IsOffset)
                        {
                            throw new InvalidOperationException("Cannot have nested offsets!");
                        }

                        // adjust ptr to attributes
                        attrsPtr += nhD.Size;
                        adjustPtr = true;
                    }

                    var nAttrs = nhD.Value;

                    Attributes = new List <NodeAttribute>(nAttrs);

                    for (int i = 0; i < nAttrs; i++)
                    {
                        var attr = new NodeAttribute(stream, Name);
                        Attributes.Add(attr);
                    }

                    // move to the attributes if needed
                    if (adjustPtr)
                    {
                        stream.Position = attrsPtr;
                    }

                    // deserialize attribute data
                    foreach (var attr in Attributes)
                    {
                        attr.Deserialize(stream);
                    }
                }
                else
                {
                    throw new NotImplementedException("Zero-length nodes are not covered under TrumpCare™.");
                }

                if (stream.Position != next)
                {
                    throw new InvalidOperationException("You dun f****d up, son!");
                }

                // read children
                for (int n = 0; n < nChildren; n++)
                {
                    var child = new NodeClass(stream);
                    Children.Add(child);
                }
            }
        }