Пример #1
0
        public void LoadXml(string filename)
        {
            var srl = new NomadXmlSerializer();

            NomadObject root = null;

            using (var fs = File.Open(filename, FileMode.Open))
            {
                root = srl.Deserialize(fs);
            }

            Version   = int.Parse(root.GetAttributeValue("Version"));
            MoveCount = int.Parse(root.GetAttributeValue("Count"));

            var resources = new List <MoveResourceData>();
            var infos     = new List <MoveResourceInfo>();

            var size = 0;

            foreach (var child in root.Children)
            {
                var resource = new MoveResourceData();
                resource.Deserialize(child);

                resources.Add(resource);

                var info = resource.GetInfo();
                infos.Add(info);

                size += info.Size;
            }

            var buffer = new byte[size];
            var offset = 0;

            for (int i = 0; i < resources.Count; i++)
            {
                var resource = resources[i];
                var info     = infos[i];

                foreach (var param in resource.AllParams)
                {
                    var globalParam = AllParams.First((p) => p.Name == param.Name);

                    globalParam.Values.AddRange(param.Values);

                    foreach (var fixup in param.Fixups)
                    {
                        var fixupInfo = new FixupInfo(fixup.Hash, fixup.Offset + offset);
                        globalParam.Fixups.Add(fixupInfo);
                    }
                }

                Buffer.BlockCopy(resource.MoveData, 0, buffer, offset, info.Size);
                offset += info.Size;
            }

            PerMoveResourceInfo.Infos = infos;
            MoveData = buffer;
        }
Пример #2
0
        public void SaveXml(string filename)
        {
            var xml  = new XDocument();
            var root = new XElement("CombinedMoveFile");

            root.SetAttributeValue("Version", 1);
            root.SetAttributeValue("Count", MoveCount);

            var srl = new NomadXmlSerializer();

            //foreach (var child in Root.Children)
            //    srl.CreateXmlElement(child, root);

            var fixups = new List <(int offset, int hash, string param)>();

            foreach (var param in AllParams)
            {
                foreach (var fixup in param.Fixups)
                {
                    fixups.Add((fixup.Offset, fixup.Hash, param.Name));
                }
            }

            fixups = fixups.OrderBy((e) => e.offset).ToList();

            var resources = new List <MoveResourceData>();
            var offset    = 0;

            foreach (var info in PerMoveResourceInfo.Infos)
            {
                var hash  = BitConverter.ToInt32(MoveData, offset);
                var bound = (offset + info.Size);

                var resource = new MoveResourceData();
                var hashes   = new List <int>();

                foreach (var fixup in fixups.Where((e) => e.offset > offset))
                {
                    if (fixup.offset > bound)
                    {
                        break;
                    }

                    var param       = resource.AllParams.First((m) => m.Name == fixup.param);
                    var globalParam = AllParams.First((m) => m.Name == fixup.param);

                    var fixupInfo = new FixupInfo(fixup.hash, fixup.offset - offset);

                    param.Fixups.Add(fixupInfo);

                    // add value once
                    if (!hashes.Contains(fixup.hash))
                    {
                        hashes.Add(fixup.hash);

                        foreach (var value in globalParam.Values)
                        {
                            var hashAttr = value.GetAttribute("hash");
                            var hashData = hashAttr.Data;

                            int paramHash = 0;

                            // HACKS!!!!!
                            if (hashData.Size < 4)
                            {
                                if (hashData.Size == 1)
                                {
                                    paramHash = (sbyte)hashData.Buffer[0];
                                }
                                else
                                {
                                    paramHash = Utils.UnpackData(hashAttr, BitConverter.ToInt16);
                                }
                            }
                            else
                            {
                                paramHash = Utils.UnpackData(hashAttr, BitConverter.ToInt32);
                            }

                            if (paramHash == fixup.hash)
                            {
                                param.Values.Add(value);
                                break;
                            }
                        }
                    }
                }

                var buffer = new byte[info.Size];

                Buffer.BlockCopy(MoveData, offset, buffer, 0, info.Size);

                resource.RootNodeId = info.RootNodeId;
                resource.MoveData   = buffer;

                resources.Add(resource);

                offset += info.Size;
            }

            foreach (var resource in resources)
            {
                srl.CreateXmlElement(resource.ToObject(), root);
            }

#if PATCH_FIXUP_TAGS
            var buffer = new byte[MoveData.Length];

            Buffer.BlockCopy(MoveData, 0, buffer, 0, buffer.Length);

            foreach (var param in AllParams)
            {
                if (param.Tag == "xxxx")
                {
                    continue;
                }

                MagicNumber mgx = param.Tag;

                var tag = BitConverter.GetBytes((int)mgx);

                foreach (var fixup in param.Fixups)
                {
                    Buffer.BlockCopy(tag, 0, buffer, fixup.Offset, tag.Length);
                }
            }

            File.WriteAllBytes(Path.ChangeExtension(filename, ".tags.bin"), buffer);
#endif
#if DUMP_FIXUP_LOG_INFO
            var dbg = new List <(int offset, string name, int old, int hash)>();
            var sb  = new StringBuilder();

            foreach (var param in AllParams)
            {
                var idx = 0;

                foreach (var fixup in param.Fixups)
                {
                    var orig = BitConverter.ToInt32(MoveData, fixup.Offset);

                    dbg.Add((fixup.Offset, $"{param.Name} fixup {idx++}", orig, fixup.Hash));
                }
            }

            var fixups = dbg.OrderBy((e) => e.offset).ToList();

            var infoOffset = 0;
            var infoIndex  = 0;

            var rootDir = Path.GetDirectoryName(filename);
            var outDir  = Path.Combine(rootDir, "movedata_files");

            if (!Directory.Exists(outDir))
            {
                Directory.CreateDirectory(outDir);
            }

            foreach (var info in PerMoveResourceInfo.Infos)
            {
                var hash = BitConverter.ToInt32(MoveData, infoOffset);

                var unk_04 = BitConverter.ToInt32(MoveData, infoOffset + 4);

                var unk_08 = MoveData[infoOffset + 8];
                var unk_09 = MoveData[infoOffset + 9];
                var unk_0a = MoveData[infoOffset + 10];
                var unk_0b = MoveData[infoOffset + 11];

                sb.AppendLine($"MoveData({hash:X8})[{infoIndex++}] @ {infoOffset:X8}");
                sb.AppendLine($"  Unk_04: {unk_04}");
                sb.AppendLine($"  Unk_08: ({unk_08}, {unk_09}, {unk_0a}, {unk_0b})");
                sb.AppendLine($"  RootNodeId: {info.RootNodeId:X8}");

                var upperBound = (infoOffset + info.Size);

                var fixupOffset = infoOffset;

                foreach (var fixup in fixups.Where((e) => e.offset < upperBound))
                {
                    if (fixup.offset < infoOffset)
                    {
                        continue;
                    }

                    sb.AppendLine($" - {fixup.offset - infoOffset:X8}: {fixup.old:X8} -> {fixup.hash:X8} ; {fixup.name}");
                }

                var buffer = new byte[info.Size];

                Buffer.BlockCopy(MoveData, infoOffset, buffer, 0, info.Size);
                File.WriteAllBytes(Path.Combine(outDir, $"{unk_08}_{unk_09}_{unk_0a}_{unk_0b}#{hash:X8}.bin"), buffer);

                infoOffset += info.Size;
            }

            //var dbgTxt = String.Join("\r\n", dbg.OrderBy((e) => e.offset).Select((e) => $"{e.offset:X8}: {e.old:X8} -> {e.hash:X8} ; {e.name}"));
            //sb.Append(dbgTxt);

            File.WriteAllBytes(Path.ChangeExtension(filename, ".data.bin"), MoveData);
            File.WriteAllText(Path.ChangeExtension(filename, ".debug.log"), sb.ToString());
#endif
            xml.Add(root);
            xml.SaveFormatted(filename, true);
        }