예제 #1
0
        public IParam Clone()
        {
            ParamStruct clone = new ParamStruct(Nodes.Count);

            foreach (var node in Nodes)
            {
                clone.Nodes.Add(node.Key, node.Value.Clone());
            }
            return(clone);
        }
예제 #2
0
        public Assembler(string filepath, ParamStruct root)
        {
            Root     = root;
            Filepath = filepath;

            AsmHashTable      = new List <ulong>();
            AsmRefEntries     = new List <object>();
            StructRefEntries  = new Dictionary <ParamStruct, RefTableEntry>();
            UnresolvedStructs = new List <Tuple <int, ParamStruct> >();
            UnresolvedStrings = new List <Tuple <int, string> >();
            RefStringEntries  = new Dictionary <string, int>();
        }
예제 #3
0
        public void Open(string filepath)
        {
            Disassembler disassembler = new Disassembler(filepath);

            Root = disassembler.Start();
        }
예제 #4
0
 public ParamFile(ParamStruct root)
 {
     Root = root;
 }
예제 #5
0
 public ParamFile()
 {
     Root = new ParamStruct();
 }
예제 #6
0
        private IParam Read()
        {
            byte key = Reader.ReadByte();

            if (!Enum.IsDefined(typeof(ParamType), key))
            {
                throw new NotImplementedException($"Unimplemented param type '{key}' at {Reader.BaseStream.Position - 1}");
            }
            ParamType type = (ParamType)key;

            IParam param;

            switch (type)
            {
            case ParamType.@struct:
            {
                int startPos        = (int)Reader.BaseStream.Position - 1;
                int size            = Reader.ReadInt32();
                int structRefOffset = Reader.ReadInt32();

                var str = new ParamStruct(size);

                IOrderedEnumerable <KeyValuePair <int, int> > hashOffsets;
                if (RefEntries.TryGetValue(structRefOffset, out var refEntry))
                {
                    hashOffsets = refEntry;
                }
                else
                {
                    Reader.BaseStream.Position = structRefOffset + RefStart;
                    var tempHashOffsets = new List <KeyValuePair <int, int> >(size);
                    for (int i = 0; i < size; i++)
                    {
                        int hashIndex   = Reader.ReadInt32();
                        int paramOffset = Reader.ReadInt32();
                        tempHashOffsets.Add(new KeyValuePair <int, int>(hashIndex, paramOffset));
                    }
                    hashOffsets = tempHashOffsets.OrderBy(a => a.Key);
                    RefEntries.Add(structRefOffset, hashOffsets);
                }

                foreach (var pair in hashOffsets)
                {
                    Reader.BaseStream.Position = startPos + pair.Value;
                    ulong  hash  = HashTable[pair.Key];
                    IParam child = Read();
                    str.Nodes.Add(hash, child);
                }

                param = str;
                break;
            }

            case ParamType.list:
            {
                int    startPos = (int)Reader.BaseStream.Position - 1;
                int    count    = Reader.ReadInt32();
                uint[] offsets  = new uint[count];

                var list = new ParamList(count);

                //all elements should be the same type but it's not enforced

                for (int i = 0; i < offsets.Length; i++)
                {
                    offsets[i] = Reader.ReadUInt32();
                }

                for (int i = 0; i < count; i++)
                {
                    Reader.BaseStream.Position = startPos + offsets[i];
                    list.Nodes.Add(Read());
                }

                param = list;
                break;
            }

            default:
            {
                var    value = new ParamValue(type);
                object v     = null;

                switch (type)
                {
                case ParamType.@bool:
                    v = Reader.ReadByte() != 0;
                    break;

                case ParamType.@sbyte:
                    v = Reader.ReadSByte();
                    break;

                case ParamType.@byte:
                    v = Reader.ReadByte();
                    break;

                case ParamType.@short:
                    v = Reader.ReadInt16();
                    break;

                case ParamType.@ushort:
                    v = Reader.ReadUInt16();
                    break;

                case ParamType.@int:
                    v = Reader.ReadInt32();
                    break;

                case ParamType.@uint:
                    v = Reader.ReadUInt32();
                    break;

                case ParamType.@float:
                    v = Reader.ReadSingle();
                    break;

                case ParamType.hash40:
                    v = HashTable[Reader.ReadUInt32()];
                    break;

                case ParamType.@string:
                    long returnTo = Reader.BaseStream.Position;
                    Reader.BaseStream.Seek(RefStart + Reader.ReadInt32(), SeekOrigin.Begin);
                    string s = ""; char c;
                    while ((c = Reader.ReadChar()) != 0)
                    {
                        s += c;
                    }
                    Reader.BaseStream.Seek(returnTo, SeekOrigin.Begin);
                    v = s;
                    break;
                }

                value.Value = v;
                param       = value;
                break;
            }
            }
            return(param);
        }
예제 #7
0
 public RefTableEntry(ParamStruct correspondingStruct)
 {
     CorrespondingStruct = correspondingStruct;
     HashOffsets         = new List <KeyValuePair <int, int> >();
 }