Exemplo n.º 1
0
        public static void Export(AdfFile adf, RuntimeTypeLibrary runtime, Stream input, XmlWriter writer)
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("adf");

            if (adf.InstanceInfos.Count > 0)
            {
                writer.WriteStartElement("instances");

                foreach (var instanceInfo in adf.InstanceInfos)
                {
                    writer.WriteStartElement("instance");
                    writer.WriteAttributeString("root", instanceInfo.Name);

                    var typeDefinition = runtime.GetTypeDefinition(instanceInfo.TypeHash);
                    input.Position = instanceInfo.Offset;
                    using (var data = input.ReadToMemoryStream((int)instanceInfo.Size))
                    {
                        var exporter = new InstanceExporter(adf, runtime);
                        exporter.Write(typeDefinition, instanceInfo.Name, data, writer);
                    }

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
        public static void Export(AdfFile adf, XmlWriter writer)
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("string-lookup");
            writer.WriteAttributeString("extension", adf.extension);
            writer.WriteAttributeString("endian", adf.Endian.ToString());
            writer.WriteAttributeString("comment", adf.Comment);

            if (adf.TypeDefinitions.Count > 0)
            {
                writer.WriteStartElement("type-definitions");
                writer.WriteAttributeString("WARNING", "DO NOT TOUCH THAT F*****G THING");
                foreach (var typeDef in adf.TypeDefinitions)
                {
                    ExportTypeDefinition(typeDef, writer);
                }
                writer.WriteEndElement();
            }

            if (adf.InstanceInfos.Count > 0)
            {
                writer.WriteStartElement("instances");
                writer.WriteAttributeString("NOTE", "HERE YOU CAN TOUCH, BUT BE GENTLE");
                foreach (var instanceInfo in adf.InstanceInfos)
                {
                    ExportInstanceInfo(instanceInfo, writer);
                }
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
Exemplo n.º 3
0
        private static uint ComputeHash(AdfFile adf, string value)
        {
            if (string.IsNullOrEmpty(value) == true)
            {
                return(0);
            }

            uint valueHash;

            if (value[0] == '#')
            {
                if (uint.TryParse(value.Substring(1),
                                  NumberStyles.AllowHexSpecifier,
                                  CultureInfo.InvariantCulture,
                                  out valueHash) == false)
                {
                    throw new FormatException();
                }
            }
            else
            {
                valueHash = value.HashJenkins();
                if (valueHash != 0 && adf.StringHashInfos.Any(shi => shi.ValueHash == valueHash) == false)
                {
                    adf.StringHashInfos.Add(new AdfFile.StringHashInfo()
                    {
                        Value     = value,
                        ValueHash = valueHash,
                    });
                }
            }
            return(valueHash);
        }
Exemplo n.º 4
0
        public void ReadSector()
        {
            var t         = new AdfFile(@"u:\Emulation\Amiga\WinUAE4100_x64\DiskImages\games\HLS_NHL_2018_2019 - Kopie.adf");
            var bytSector = t.GetSector(0);

            Assert.IsTrue(bytSector.Length == 512, System.Text.Encoding.ASCII.GetString(bytSector, 0, 25));
        }
Exemplo n.º 5
0
        private static string ResolveHash(AdfFile adf, uint valueHash)
        {
            if (valueHash == 0)
            {
                return("");
            }
            var stringHashInfo = adf.StringHashInfos.FirstOrDefault(shi => shi.ValueHash == valueHash);

            return(stringHashInfo == default(FileFormats.AdfFile.StringHashInfo)
                       ? string.Format(CultureInfo.InvariantCulture, "#{0:X8}", valueHash)
                       : stringHashInfo.Value);
        }
Exemplo n.º 6
0
 public void TestMethod1()
 {
     try
     {
         var t = new AdfFile(@"u:\Emulation\Amiga\WinUAE4100_x64\DiskImages\games\HLS_NHL_2018_2019 - Kopie.adf");
         Assert.IsTrue(true);
     }
     catch (Exception e)
     {
         Assert.IsFalse(true, e.Message);
     }
 }
Exemplo n.º 7
0
            public InstanceExporter(AdfFile adf, RuntimeTypeLibrary runtime)
            {
                if (adf == null)
                {
                    throw new ArgumentNullException("adf");
                }

                if (runtime == null)
                {
                    throw new ArgumentNullException("runtime");
                }

                this._Adf       = adf;
                this._Runtime   = runtime;
                this._WorkQueue = new Queue <WorkItem>();
            }
Exemplo n.º 8
0
        private static void ImportInstanceInfo(XPathNavigator instanceNode, AdfFile adf)
        {
            InstanceInfo instance = new InstanceInfo()
            {
                Name     = instanceNode.GetAttribute("name", ""),
                NameHash = uint.Parse(instanceNode.GetAttribute("name-hash", "")),
            };

            TypeDefinitionType type;

            Enum.TryParse(instanceNode.GetAttribute("type", ""), out type);
            uint   typeHash   = uint.Parse(instanceNode.GetAttribute("type-hash", ""), CultureInfo.InvariantCulture);
            string typeString = instanceNode.GetAttribute("type-name", "");

            instance.Type     = adf.Runtime.GetTypeDefinition(typeHash);
            instance.TypeHash = instance.Type.NameHash;

            if (!int.TryParse(instanceNode.GetAttribute("inline-array-copy-index", ""), out instance.InlineArrayIndex))
            {
                instance.InlineArrayIndex = -1;
            }
            if (!uint.TryParse(instanceNode.GetAttribute("inline-array-copy-minsz", ""), out instance.MinInlineArraySize))
            {
                instance.MinInlineArraySize = 0;
            }

            if (type != instance.Type.Type)
            {
                throw new InvalidOperationException("do not touch things like type and type-name in the xml file, yo");
            }

            instance.Members = new List <AdfFile.InstanceMemberInfo>();
            // parse members
            var membersList = instanceNode.Select("member");

            // normal array or structure
            foreach (XPathNavigator memberNode in membersList)
            {
                instance.Members.Add(ImportInstanceMemberInfo(memberNode, adf));
            }

            // add it
            adf.AddInstanceInfo(instance);
        }
Exemplo n.º 9
0
        public static AdfFile Import(XPathNavigator root)
        {
            AdfFile adf = new AdfFile()
            {
                Endian = Endian.Little,
            };

            adf.Comment = root.GetAttribute("comment", "");
            Endian adfEndian;

            Enum.TryParse(root.GetAttribute("endian", ""), out adfEndian);
            adf.Endian = adfEndian;

            var typeDefNode = root.SelectSingleNode("type-definitions");

            if (typeDefNode != null)
            {
                var typesList = typeDefNode.Select("type");

                foreach (XPathNavigator typeNode in typesList)
                {
                    ImportTypeDefinition(typeNode, adf);
                }

                // loop the loop
                adf.Runtime.AddTypeDefinitions(adf);
            }

            var instancesNode = root.SelectSingleNode("instances");

            if (instancesNode != null)
            {
                var instancesList = instancesNode.Select("instance");

                foreach (XPathNavigator instanceNode in instancesList)
                {
                    ImportInstanceInfo(instanceNode, adf);
                }
            }
            return(adf);
        }
Exemplo n.º 10
0
        private static void ImportTypeDefinition(XPathNavigator typeNode, AdfFile adf)
        {
            TypeDefinition typeDef = new TypeDefinition()
            {
                Size            = uint.Parse(typeNode.GetAttribute("size", "")),
                Alignment       = uint.Parse(typeNode.GetAttribute("alignment", ""), CultureInfo.InvariantCulture),
                Name            = typeNode.GetAttribute("name", ""),
                NameHash        = uint.Parse(typeNode.GetAttribute("name-hash", ""), CultureInfo.InvariantCulture),
                Flags           = uint.Parse(typeNode.GetAttribute("flags", ""), CultureInfo.InvariantCulture),
                ElementLength   = uint.Parse(typeNode.GetAttribute("length", ""), CultureInfo.InvariantCulture),
                ElementTypeHash = uint.Parse(typeNode.GetAttribute("eltypehash", ""), CultureInfo.InvariantCulture),
            };

            Enum.TryParse(typeNode.GetAttribute("type", ""), out typeDef.Type);

            if (typeDef.Type == TypeDefinitionType.Structure)
            {
                // it has members
                var membersList = typeNode.Select("member");
                // so we will parse them
                typeDef.Members = new AdfFile.MemberDefinition[membersList.Count];

                int i = 0;
                foreach (XPathNavigator memberNode in membersList)
                {
                    typeDef.Members[i].Name         = memberNode.GetAttribute("name", "");
                    typeDef.Members[i].TypeHash     = uint.Parse(memberNode.GetAttribute("type-hash", ""), CultureInfo.InvariantCulture);
                    typeDef.Members[i].Size         = uint.Parse(memberNode.GetAttribute("size", ""), CultureInfo.InvariantCulture);
                    typeDef.Members[i].Offset       = uint.Parse(memberNode.GetAttribute("offset", ""), CultureInfo.InvariantCulture);
                    typeDef.Members[i].DefaultType  = uint.Parse(memberNode.GetAttribute("deftype", ""), CultureInfo.InvariantCulture);
                    typeDef.Members[i].DefaultValue = ulong.Parse(memberNode.GetAttribute("defval", ""), CultureInfo.InvariantCulture);
                    ++i;
                }
            }

            // Add it
            adf.TypeDefinitions.Add(typeDef);
        }
Exemplo n.º 11
0
        private static void Main(string[] args)
        {
            var  mode     = Mode.Unknown;
            bool showHelp = false;

            var options = new OptionSet
            {
                // ReSharper disable AccessToModifiedClosure
                { "e|export", "convert from binary to JSON", v => SetOption(v, ref mode, Mode.Export) },
                { "i|import", "convert from JSON to binary", v => SetOption(v, ref mode, Mode.Import) },
                // ReSharper restore AccessToModifiedClosure
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (mode == Mode.Unknown && extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);
                if (extension != null && extension.ToLowerInvariant() == ".json")
                {
                    mode = Mode.Import;
                }
                else
                {
                    mode = Mode.Export;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true ||
                mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-e] task.onlinec [output_json]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ [-i] input_json [task.onlinec]", GetExecutableName());
                Console.WriteLine("Convert an task file between binary and JSON format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            if (mode == Mode.Export)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".json");

                var adf      = new AdfFile();
                var taskRoot = new TaskRoot();

                using (var input = File.OpenRead(inputPath))
                {
                    adf.Deserialize(input);

                    var taskRootInfo = adf.InstanceInfos.FirstOrDefault(i => i.Name == "Profile");
                    if (taskRootInfo.TypeHash != TaskRoot.TypeHash)
                    {
                        throw new FormatException();
                    }

                    input.Position = taskRootInfo.Offset;
                    taskRoot.Deserialize(input, adf.Endian);
                }

                using (var output = File.Create(outputPath))
                    using (var textWriter = new StreamWriter(output))
                        using (var writer = new JsonTextWriter(textWriter))
                        {
                            writer.Indentation = 2;
                            writer.IndentChar  = ' ';
                            writer.Formatting  = Formatting.Indented;

                            var jsonTasks = taskRoot.Tasks.Select(
                                t =>
                            {
                                var jsonTask = new TaskRootJson.Task()
                                {
                                    Name                      = ResolveHash(adf, t.Name),
                                    TaskGroup                 = ResolveHash(adf, t.TaskGroup),
                                    Type                      = t.Type,
                                    ProvinceWeight            = t.ProvinceWeight,
                                    LiberationPercent         = t.LiberationPercent,
                                    RepeatableRewardSemantics = t.RepeatableRewardSemantics,
                                    RepeatableReward          = new TaskRootJson.Reward()
                                    {
                                        Skillpoints         = t.RepeatableReward.Skillpoints,
                                        Chaos               = t.RepeatableReward.Chaos,
                                        ItemRewardSemantics = t.RepeatableReward.ItemRewardSemantics,
                                    },
                                    HasChurch     = t.HasChurch,
                                    ShownOnMap    = t.ShownOnMap,
                                    UIName        = ResolveHash(adf, t.UIName),
                                    UIDescription = ResolveHash(adf, t.UIDescription),
                                    UITip         = ResolveHash(adf, t.UITip),
                                    UIOrderHint   = t.UIOrderHint,
                                };
                                if (t.RepeatableReward.Items != null)
                                {
                                    jsonTask.RepeatableReward.Items.AddRange(
                                        t.RepeatableReward.Items.Select(i => new TaskRootJson.ItemReward()
                                    {
                                        Item      = ResolveHash(adf, i.Item),
                                        Permanent = i.Permanent,
                                        Duration  = i.Duration,
                                        Quantity  = i.Quantity,
                                        Delivery  = i.Delivery,
                                    }));
                                }
                                if (t.RewardThresholds != null)
                                {
                                    jsonTask.RewardThresholds.AddRange(
                                        t.RewardThresholds.Select(
                                            rt =>
                                    {
                                        var jsonRewardThreshold = new TaskRootJson.RewardThreshold()
                                        {
                                            Threshold = rt.Threshold,
                                            Reward    = new TaskRootJson.Reward()
                                            {
                                                Skillpoints         = rt.Reward.Skillpoints,
                                                Chaos               = rt.Reward.Chaos,
                                                ItemRewardSemantics = rt.Reward.ItemRewardSemantics,
                                            },
                                        };
                                        if (rt.Reward.Items != null)
                                        {
                                            jsonRewardThreshold.Reward.Items.AddRange(
                                                rt.Reward.Items.Select(i => new TaskRootJson.ItemReward()
                                            {
                                                Item      = ResolveHash(adf, i.Item),
                                                Permanent = i.Permanent,
                                                Duration  = i.Duration,
                                                Quantity  = i.Quantity,
                                                Delivery  = i.Delivery,
                                            }));
                                        }
                                        return(jsonRewardThreshold);
                                    }));
                                }
                                if (t.Prerequisites != null)
                                {
                                    jsonTask.Prerequisites.AddRange(
                                        t.Prerequisites.Select(p => new TaskRootJson.Prerequisite()
                                    {
                                        Name        = ResolveHash(adf, p.Name),
                                        RewardIndex = p.RewardIndex,
                                        Tag         = ResolveHash(adf, p.Tag),
                                    }));
                                }
                                return(jsonTask);
                            }).ToArray();

                            var serializer = JsonSerializer.Create();
                            serializer.Serialize(writer, jsonTasks);
                        }
            }
            else if (mode == Mode.Import)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".onlinec");

                var adf = new AdfFile()
                {
                    Endian = Endian.Little,
                };
                var taskRoot = new TaskRoot();

                using (var input = File.OpenRead(inputPath))
                    using (var textReader = new StreamReader(input))
                        using (var reader = new JsonTextReader(textReader))
                        {
                            var serializer = JsonSerializer.Create();
                            var jsonTasks  = serializer.Deserialize <TaskRootJson.Task[]>(reader);

                            taskRoot.Tasks.AddRange(jsonTasks.Select(
                                                        jt =>
                            {
                                var task = new TaskRoot.Task()
                                {
                                    Name                      = ComputeHash(adf, jt.Name),
                                    TaskGroup                 = ComputeHash(adf, jt.TaskGroup),
                                    Type                      = jt.Type,
                                    ProvinceWeight            = jt.ProvinceWeight,
                                    LiberationPercent         = jt.LiberationPercent,
                                    RepeatableRewardSemantics = jt.RepeatableRewardSemantics,
                                    RepeatableReward          = new TaskRoot.Reward()
                                    {
                                        Skillpoints         = jt.RepeatableReward.Skillpoints,
                                        Chaos               = jt.RepeatableReward.Chaos,
                                        ItemRewardSemantics = jt.RepeatableReward.ItemRewardSemantics,
                                    },
                                    HasChurch     = jt.HasChurch,
                                    ShownOnMap    = jt.ShownOnMap,
                                    UIName        = ComputeHash(adf, jt.UIName),
                                    UIDescription = ComputeHash(adf, jt.UIDescription),
                                    UITip         = ComputeHash(adf, jt.UITip),
                                    UIOrderHint   = jt.UIOrderHint,
                                };
                                task.RepeatableReward.Items =
                                    jt.RepeatableReward.Items.Select(ji => new TaskRoot.ItemReward()
                                {
                                    Item      = ComputeHash(adf, ji.Item),
                                    Permanent = ji.Permanent,
                                    Duration  = ji.Duration,
                                    Quantity  = ji.Quantity,
                                    Delivery  = ji.Delivery,
                                }).ToArray();
                                task.RewardThresholds =
                                    jt.RewardThresholds.Select(
                                        jrt =>
                                {
                                    var rewardThreshold = new TaskRoot.RewardThreshold()
                                    {
                                        Threshold = jrt.Threshold,
                                        Reward    = new TaskRoot.Reward()
                                        {
                                            Skillpoints         = jrt.Reward.Skillpoints,
                                            Chaos               = jrt.Reward.Chaos,
                                            ItemRewardSemantics = jrt.Reward.ItemRewardSemantics,
                                        },
                                    };
                                    rewardThreshold.Reward.Items =
                                        jrt.Reward.Items.Select(ji => new TaskRoot.ItemReward()
                                    {
                                        Item      = ComputeHash(adf, ji.Item),
                                        Permanent = ji.Permanent,
                                        Duration  = ji.Duration,
                                        Quantity  = ji.Quantity,
                                        Delivery  = ji.Delivery,
                                    }).ToArray();
                                    return(rewardThreshold);
                                }).ToArray();
                                task.Prerequisites =
                                    jt.Prerequisites.Select(jp => new TaskRoot.Prerequisite()
                                {
                                    Name        = ComputeHash(adf, jp.Name),
                                    RewardIndex = jp.RewardIndex,
                                    Tag         = ComputeHash(adf, jp.Tag),
                                }).ToArray();
                                return(task);
                            }));
                        }

                using (var output = File.Create(outputPath))
                {
                    using (var data = new MemoryStream())
                    {
                        taskRoot.Serialize(data, adf.Endian);
                        data.Flush();
                        data.Position = 0;

                        output.Position = adf.EstimateHeaderSize();
                        var itemRootPosition = output.Position;
                        output.WriteFromStream(data, data.Length);

                        adf.InstanceInfos.Add(new AdfFile.InstanceInfo()
                        {
                            Name     = "Profile",
                            NameHash = "Profile".HashJenkins(),
                            Offset   = (uint)itemRootPosition,
                            Size     = (uint)data.Length,
                            TypeHash = TaskRoot.TypeHash,
                        });

                        adf.Serialize(output, 0);
                    }
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Exemplo n.º 12
0
        private static AdfFile.InstanceMemberInfo ImportInstanceMemberInfo(XPathNavigator memberNode, AdfFile adf)
        {
            AdfFile.InstanceMemberInfo member = new AdfFile.InstanceMemberInfo();

            member.Name = memberNode.GetAttribute("name", "");
            string stringId  = memberNode.GetAttribute("id", "");
            string ownIACopy = memberNode.GetAttribute("own-copy-of-inline-arrays", "");

            if (!string.IsNullOrEmpty(stringId))
            {
                member.Id = long.Parse(stringId, CultureInfo.InvariantCulture);
            }
            member.isReferenceToId = !string.IsNullOrEmpty(memberNode.GetAttribute("is-reference", ""));
            if (!string.IsNullOrEmpty(ownIACopy))
            {
                member.HasOwnCopyOfInlineArrays = true;
            }

            Enum.TryParse(memberNode.GetAttribute("gbltype", ""), out member.Type);
            string typeString = memberNode.GetAttribute("type", "");

            // Load the value
            if (member.Type == TypeDefinitionType.Primitive)
            {
                switch (typeString)
                {
                case "int8":
                    member.Data.WriteValueS8(sbyte.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int8;
                    break;

                case "uint8":
                    member.Data.WriteValueU8(byte.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt8;
                    break;

                case "int16":
                    member.Data.WriteValueS16(short.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int16;
                    break;

                case "uint16":
                    member.Data.WriteValueU16(ushort.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt16;
                    break;

                case "int32":
                    member.Data.WriteValueS32(int.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int32;
                    break;

                case "uint32":
                    member.Data.WriteValueU32(uint.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt32;
                    break;

                case "int64":
                    member.Data.WriteValueS64(long.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int64;
                    break;

                case "uint64":
                    member.Data.WriteValueU64(ulong.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt64;
                    break;

                case "float":
                    member.Data.WriteValueF32(float.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Float;
                    break;

                case "double":
                    member.Data.WriteValueF64(double.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Double;
                    break;

                case "string":
                    string strRef = memberNode.GetAttribute("reference-string-from", "");
                    if (!string.IsNullOrEmpty(strRef))
                    {
                        member.ReferenceToString = true;
                        member.StringTableId     = int.Parse(strRef, CultureInfo.InvariantCulture);
                    }
                    member.StringData = memberNode.Value;
                    member.TypeHash   = AdfTypeHashes.String;
                    break;
                }
            }
            else
            {
                uint typeHash = uint.Parse(memberNode.GetAttribute("type-hash", ""), CultureInfo.InvariantCulture);
                member.TypeDef  = adf.Runtime.GetTypeDefinition(typeHash);
                member.TypeHash = typeHash;
                if (member.TypeDef.Type != member.Type)
                {
                    throw new InvalidOperationException("do not touch things like type and type-name in the xml file, yo");
                }

                if (member.Type == TypeDefinitionType.StringHash)
                {
                    member.StringData = memberNode.Value;
                }
            }

            // handle sub members
            if (memberNode.GetAttribute("int8-array-is-string-array", "") == "yay")
            {
                // we found an array of inline-strings
                var subMembersList = memberNode.Select("inline-string");
                foreach (XPathNavigator subMemberNode in subMembersList)
                {
                    // it is an inline string. Get its value and write the string
                    byte[] str = Encoding.UTF8.GetBytes(subMemberNode.Value);
                    foreach (byte b in str)
                    {
                        AdfFile.InstanceMemberInfo subMember = new AdfFile.InstanceMemberInfo();
                        subMember.TypeHash = AdfTypeHashes.Primitive.Int8;
                        subMember.Type     = TypeDefinitionType.Primitive;
                        subMember.Data.WriteValueU8(b);
                        member.Members.Add(subMember);
                    }
                    AdfFile.InstanceMemberInfo lastByteMember = new AdfFile.InstanceMemberInfo();
                    lastByteMember.TypeHash = AdfTypeHashes.Primitive.Int8;
                    lastByteMember.Type     = TypeDefinitionType.Primitive;
                    lastByteMember.Data.WriteValueU8(0);
                    member.Members.Add(lastByteMember);
                }
            }
            else
            {
                var subMembersList = memberNode.Select("member");
                foreach (XPathNavigator subMemberNode in subMembersList)
                {
                    member.Members.Add(ImportInstanceMemberInfo(subMemberNode, adf));
                }
            }

            return(member);
        }
Exemplo n.º 13
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("  {0}  file.stringlookup", GetExecutableName());
                Console.WriteLine("  {0}  file.xml", GetExecutableName());
                return;
            }

            string inputPath = args[0];

            if (Path.GetExtension(inputPath).ToLowerInvariant() == ".xml") // IMPORT
            {
                using (var input = File.OpenRead(inputPath))
                {
                    var doc = new XPathDocument(input);
                    var nav = doc.CreateNavigator();

                    var root = nav.SelectSingleNode("/string-lookup");
                    if (root == null)
                    {
                        throw new FormatException();
                    }

                    // retrieve the original extension as stored in the XML file
                    var    outputExtension = root.GetAttribute("extension", "");
                    string outputPath      = Path.ChangeExtension(inputPath, outputExtension);


                    AdfFile adf = Importer.Import(root);

                    using (var output = File.Create(outputPath))
                    {
                        output.Position = adf.EstimateHeaderSize();
                        adf.Serialize(output, 0);
                    }
                }
            }
            else // EXPORT (to XML)
            {
                string outputPath = Path.ChangeExtension(inputPath, ".xml");
                using (var input = File.OpenRead(inputPath))
                {
                    var adf = new AdfFile(Path.GetExtension(inputPath));
                    adf.Deserialize(input);
                    var settings = new XmlWriterSettings
                    {
                        Indent          = true,
                        IndentChars     = "    ",
                        CheckCharacters = false,
                    };

                    using (var output = File.Create(outputPath))
                    {
                        var writer = XmlWriter.Create(output, settings);
                        Exporter.Export(adf, writer);
                        writer.Flush();
                    }
                }
            }
        }
Exemplo n.º 14
0
        private static void ImportInstanceInfo(XPathNavigator instanceNode, AdfFile adf)
        {
            InstanceInfo instance = new InstanceInfo()
            {
                Name     = instanceNode.GetAttribute("name", ""),
                NameHash = uint.Parse(instanceNode.GetAttribute("name-hash", "")),
            };

            TypeDefinitionType type;

            Enum.TryParse(instanceNode.GetAttribute("type", ""), out type);
            uint   typeHash   = uint.Parse(instanceNode.GetAttribute("type-hash", ""), CultureInfo.InvariantCulture);
            string typeString = instanceNode.GetAttribute("type-name", "");

            instance.Type     = adf.Runtime.GetTypeDefinition(typeHash);
            instance.TypeHash = instance.Type.NameHash;

            if (!int.TryParse(instanceNode.GetAttribute("inline-array-copy-index", ""), out instance.InlineArrayIndex))
            {
                instance.InlineArrayIndex = -1;
            }
            if (!uint.TryParse(instanceNode.GetAttribute("inline-array-copy-minsz", ""), out instance.MinInlineArraySize))
            {
                instance.MinInlineArraySize = 0;
            }

            if (type != instance.Type.Type)
            {
                throw new InvalidOperationException("do not touch things like type and type-name in the xml file, yo");
            }

            instance.Members = new List <AdfFile.InstanceMemberInfo>();

            // Hold the contents of the last Array (A[int8])
            List <byte> stringArray = new List <byte>();

            // parse members
            instance.Members.Add(null); // prepare the future
            var memberNode = instanceNode.SelectSingleNode("member");

            instance.Members[0] = (ImportInstanceMemberInfo(memberNode, instance, adf, stringArray));

            var stringArrayMemberIndex = 0;

            foreach (var member in instance.Members)
            {
                if (member.Id == 2)
                {
                    break;
                }
                ++stringArrayMemberIndex;
            }
            var stringArrayMember = instance.Members[stringArrayMemberIndex];

            // Generate the string array (type is array of int8)
            foreach (byte b in stringArray) // the foreach is sooo overkill...
            {
                var subMember = new AdfFile.InstanceMemberInfo()
                {
                    Type     = TypeDefinitionType.Primitive,
                    TypeHash = AdfTypeHashes.Primitive.Int8,
                    Name     = null,
                };
                subMember.Data.WriteByte(b);
                stringArrayMember.Members.Add(subMember);
            }

            // add instance to ADF structure
            adf.AddInstanceInfo(instance);
        }
Exemplo n.º 15
0
        private static AdfFile.InstanceMemberInfo ImportTextOffset(XPathNavigator memberNode, AdfFile.InstanceMemberInfo member, InstanceInfo ii, AdfFile adf, List <byte> stringArray)
        {
            member.TypeHash = AdfTypeHashes.Primitive.UInt32;
            member.Data.WriteValueU32((uint)stringArray.Count); // write the offset

            byte[] str = Encoding.UTF8.GetBytes(memberNode.Value);
            stringArray.AddRange(str);
            stringArray.Add(0); // the null byte to terminate the string

            return(member);
        }
Exemplo n.º 16
0
        private static AdfFile.InstanceMemberInfo ImportInstanceMemberInfo(XPathNavigator memberNode, AdfFile.InstanceInfo ii, AdfFile adf, List <byte> stringArray)
        {
            AdfFile.InstanceMemberInfo member = new AdfFile.InstanceMemberInfo();

            member.Name = memberNode.GetAttribute("name", "");
            string stringId  = memberNode.GetAttribute("id", "");
            string ownIACopy = memberNode.GetAttribute("own-copy-of-inline-arrays", "");

            if (!string.IsNullOrEmpty(stringId))
            {
                member.Id = long.Parse(stringId, CultureInfo.InvariantCulture);
            }
            else
            {
                member.Id = -1;
            }
            member.isReferenceToId = !string.IsNullOrEmpty(memberNode.GetAttribute("is-reference", ""));
            if (!string.IsNullOrEmpty(ownIACopy))
            {
                member.HasOwnCopyOfInlineArrays = true;
            }

            Enum.TryParse(memberNode.GetAttribute("gbltype", ""), out member.Type);
            string typeString = memberNode.GetAttribute("type", "");

            if (member.Name == "TextOffset" || member.Name == "NameOffset") // hardcoded :( thingy to handle string lookup
            {
                return(ImportTextOffset(memberNode, member, ii, adf, stringArray));
            }

            // Load the value
            if (member.Type == TypeDefinitionType.Primitive)
            {
                switch (typeString)
                {
                case "int8":
                    member.Data.WriteValueS8(sbyte.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int8;
                    break;

                case "uint8":
                    member.Data.WriteValueU8(byte.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt8;
                    break;

                case "int16":
                    member.Data.WriteValueS16(short.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int16;
                    break;

                case "uint16":
                    member.Data.WriteValueU16(ushort.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt16;
                    break;

                case "int32":
                    member.Data.WriteValueS32(int.Parse(memberNode.Value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int32;
                    break;

                case "uint32":
                    member.Data.WriteValueU32(uint.Parse(memberNode.Value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt32;
                    break;

                case "int64":
                    member.Data.WriteValueS64(long.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Int64;
                    break;

                case "uint64":
                    member.Data.WriteValueU64(ulong.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.UInt64;
                    break;

                case "float":
                    member.Data.WriteValueF32(float.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Float;
                    break;

                case "double":
                    member.Data.WriteValueF64(double.Parse(memberNode.Value, CultureInfo.InvariantCulture));
                    member.TypeHash = AdfTypeHashes.Primitive.Double;
                    break;

                case "string":
                    string strRef = memberNode.GetAttribute("reference-string-from", "");
                    if (!string.IsNullOrEmpty(strRef))
                    {
                        member.ReferenceToString = true;
                        member.StringTableId     = int.Parse(strRef, CultureInfo.InvariantCulture);
                    }
                    member.StringData = memberNode.Value;
                    member.TypeHash   = AdfTypeHashes.String;
                    break;
                }
            }
            else
            {
                uint typeHash = uint.Parse(memberNode.GetAttribute("type-hash", ""), CultureInfo.InvariantCulture);
                member.TypeDef  = adf.Runtime.GetTypeDefinition(typeHash);
                member.TypeHash = typeHash;
                if (member.TypeDef.Type != member.Type)
                {
                    throw new InvalidOperationException("do not touch things like type and type-name in the xml file, yo");
                }

                if (member.Type == TypeDefinitionType.StringHash)
                {
                    member.StringData = memberNode.Value;
                }

                if (member.Type == TypeDefinitionType.Array && member.isReferenceToId == true && member.Id != -1)
                {
                    // No child, create an empty element
                    if (!memberNode.HasChildren)
                    {
                        var subMember = new AdfFile.InstanceMemberInfo()
                        {
                            Name                     = member.Name,
                            Id                       = member.Id,
                            isReferenceToId          = false,
                            Type                     = member.Type,
                            TypeHash                 = member.TypeHash,
                            TypeDef                  = member.TypeDef,
                            HasOwnCopyOfInlineArrays = false,  // maybe _that_ will cause some issues...
                        };
                        ii.Members.Add(subMember);
                        return(member);
                    }
                    // the child node is in fact a global element.
                    XPathNavigator subMemberNode = memberNode.SelectSingleNode("member");
                    ii.Members.Add(ImportInstanceMemberInfo(subMemberNode, ii, adf, stringArray));
                    return(member);
                }
            }

            // handle sub members
            var subMembersList = memberNode.Select("member");

            foreach (XPathNavigator subMemberNode in subMembersList)
            {
                var subMember = ImportInstanceMemberInfo(subMemberNode, ii, adf, stringArray);
                if (member.Name != "SortedPairs") // another hardcoded thing
                {
                    member.Members.Add(subMember);
                }
                else // insert the new member at the right place
                {
                    subMember.Members[0].Data.Position = 0;
                    uint hash = subMember.Members[0].Data.ReadValueU32();
                    subMember.Members[0].Data.Position = 0;
                    int i = 0;
                    for (; i < member.Members.Count; ++i)
                    {
                        member.Members[i].Members[0].Data.Position = 0;
                        uint cmpHash = member.Members[i].Members[0].Data.ReadValueU32();
                        member.Members[i].Members[0].Data.Position = 0;
                        if (cmpHash > hash)
                        {
                            break;
                        }
                    }
                    member.Members.Insert(i, subMember);
                }
            }

            return(member);
        }
Exemplo n.º 17
0
        private static void Main(string[] args)
        {
            var  mode             = Mode.Unknown;
            bool showHelp         = false;
            var  typeLibraryPaths = new List <string>();

            var options = new OptionSet
            {
                // ReSharper disable AccessToModifiedClosure
                { "e|export", "convert from binary to XML", v => SetOption(v, ref mode, Mode.Export) },
                { "i|import", "convert from XML to binary", v => SetOption(v, ref mode, Mode.Import) },
                // ReSharper restore AccessToModifiedClosure
                { "t|type-library=", "load type library from file", v => typeLibraryPaths.Add(v) },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (mode == Mode.Unknown && extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);
                if (extension != null && extension.ToLowerInvariant() == ".xml")
                {
                    mode = Mode.Import;
                }
                else
                {
                    mode = Mode.Export;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true ||
                mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-e] input_adf [output_xml]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ [-i] input_xml [output_adf]", GetExecutableName());
                Console.WriteLine("Convert an ADF file between binary and XML format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var runtime = new RuntimeTypeLibrary();

            foreach (var typeLibraryPath in typeLibraryPaths)
            {
                var adf = new FileFormats.AdfFile("");

                using (var input = File.OpenRead(typeLibraryPath))
                {
                    adf.Deserialize(input);
                }

                runtime.AddTypeDefinitions(adf);
            }

            if (mode == Mode.Export)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".xml");

                using (var input = File.OpenRead(inputPath))
                {
                    var adf = new AdfFile(Path.GetExtension(inputPath));
                    adf.Deserialize(input);
                    runtime.AddTypeDefinitions(adf);


                    var settings = new XmlWriterSettings
                    {
                        Indent          = true,
                        IndentChars     = "    ",
                        CheckCharacters = false,
                    };

                    using (var output = File.Create(outputPath))
                    {
                        var writer = XmlWriter.Create(output, settings);
                        Exporter.Export(adf, writer /*, runtime, input, writer*/);
                        writer.Flush();
                    }
                }
            }
            else if (mode == Mode.Import)
            {
                string inputPath = extras[0];

                using (var input = File.OpenRead(inputPath))
                {
                    var doc = new XPathDocument(input);
                    var nav = doc.CreateNavigator();

                    var root = nav.SelectSingleNode("/adf");
                    if (root == null)
                    {
                        throw new FormatException();
                    }

                    // retrieve the original extension as stored in the XML file
                    var    outputExtension = root.GetAttribute("extension", "");
                    string outputPath      = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, outputExtension);


                    AdfFile adf = Importer.Import(root);

                    using (var output = File.Create(outputPath))
                    {
                        output.Position = adf.EstimateHeaderSize();
                        adf.Serialize(output, 0);
                    }
                }
            }
        }
Exemplo n.º 18
0
        private static void Main(string[] args)
        {
            var  mode     = Mode.Unknown;
            bool showHelp = false;

            var options = new OptionSet
            {
                // ReSharper disable AccessToModifiedClosure
                { "e|export", "convert from binary to JSON", v => SetOption(v, ref mode, Mode.Export) },
                { "i|import", "convert from JSON to binary", v => SetOption(v, ref mode, Mode.Import) },
                // ReSharper restore AccessToModifiedClosure
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (mode == Mode.Unknown && extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);
                if (extension != null && extension.ToLowerInvariant() == ".json")
                {
                    mode = Mode.Import;
                }
                else
                {
                    mode = Mode.Export;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true ||
                mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-e] input_upgrade_onlinec [output_json]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ [-i] input_json [output_upgrade_onlinec]", GetExecutableName());
                Console.WriteLine("Convert an upgrade file between binary and JSON format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            if (mode == Mode.Export)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".json");

                var adf      = new FileFormats.AdfFile();
                var itemRoot = new UpgradeRoot();

                using (var input = File.OpenRead(inputPath))
                {
                    adf.Deserialize(input);

                    var itemRootInfo = adf.InstanceInfos.FirstOrDefault(i => i.Name == "Profile");
                    if (itemRootInfo.TypeHash != UpgradeRoot.TypeHash)
                    {
                        throw new FormatException();
                    }

                    input.Position = itemRootInfo.Offset;
                    itemRoot.Deserialize(input, adf.Endian);
                }

                using (var output = File.Create(outputPath))
                    using (var textWriter = new StreamWriter(output))
                        using (var writer = new JsonTextWriter(textWriter))
                        {
                            writer.Indentation = 2;
                            writer.IndentChar  = ' ';
                            writer.Formatting  = Formatting.Indented;

                            var jsonItems = itemRoot.Upgrades.Select(
                                u =>
                            {
                                var jsonItem = new UpgradeRootJson.Upgrade()
                                {
                                    Name           = ResolveHash(adf, u.Name),
                                    TaskGroup      = ResolveHash(adf, u.TaskGroup),
                                    StarThreshold  = u.StarThreshold,
                                    Cost           = u.Cost,
                                    Ability        = ResolveHash(adf, u.Ability),
                                    UIName         = ResolveHash(adf, u.UIName),
                                    UIDescription  = ResolveHash(adf, u.UIDescription),
                                    UIDisplayOrder = u.UIDisplayOrder,
                                    UIImage        = u.UIImage,
                                    UIVideo        = u.UIVideo,
                                    UITreeName     = ResolveHash(adf, u.UITreeName),
                                    UITreeOrder    = u.UITreeOrder,
                                };
                                jsonItem.Prerequisites.AddRange(u.Prerequisites.Select(f => ResolveHash(adf, f)));
                                return(jsonItem);
                            }).ToArray();

                            var serializer = JsonSerializer.Create();
                            serializer.Serialize(writer, jsonItems);
                        }
            }
            else if (mode == Mode.Import)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".onlinec");

                var adf = new AdfFile()
                {
                    Endian = Endian.Little,
                };
                var itemRoot = new UpgradeRoot();

                using (var input = File.OpenRead(inputPath))
                    using (var textReader = new StreamReader(input))
                        using (var reader = new JsonTextReader(textReader))
                        {
                            var serializer = JsonSerializer.Create();
                            var jsonItems  = serializer.Deserialize <UpgradeRootJson.Upgrade[]>(reader);

                            itemRoot.Upgrades.AddRange(jsonItems.Select(
                                                           ju => new UpgradeRoot.Upgrade()
                            {
                                Name           = ComputeHash(adf, ju.Name),
                                TaskGroup      = ComputeHash(adf, ju.TaskGroup),
                                StarThreshold  = ju.StarThreshold,
                                Prerequisites  = ju.Prerequisites.Select(f => ComputeHash(adf, f)).ToArray(),
                                Cost           = ju.Cost,
                                Ability        = ComputeHash(adf, ju.Ability),
                                UIName         = ComputeHash(adf, ju.UIName),
                                UIDescription  = ComputeHash(adf, ju.UIDescription),
                                UIDisplayOrder = ju.UIDisplayOrder,
                                UIImage        = ju.UIImage,
                                UIVideo        = ju.UIVideo,
                                UITreeName     = ComputeHash(adf, ju.UITreeName),
                                UITreeOrder    = ju.UITreeOrder,
                            }));
                        }

                using (var output = File.Create(outputPath))
                {
                    using (var data = new MemoryStream())
                    {
                        itemRoot.Serialize(data, adf.Endian);
                        data.Flush();
                        data.Position = 0;

                        output.Position = adf.EstimateHeaderSize();
                        var itemRootPosition = output.Position;
                        output.WriteFromStream(data, data.Length);

                        adf.InstanceInfos.Add(new AdfFile.InstanceInfo()
                        {
                            Name     = "Profile",
                            NameHash = "Profile".HashJenkins(),
                            Offset   = (uint)itemRootPosition,
                            Size     = (uint)data.Length,
                            TypeHash = UpgradeRoot.TypeHash,
                        });

                        adf.Serialize(output, 0);
                    }
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Exemplo n.º 19
0
        private void ADFExtractStrings(AdfFile adf)
        {
            // load strings from the hash string table
            foreach (var stringItem in adf.StringHashInfos)
            {
                AddString(stringItem.Value);
            }
            // load strings from type definitions (why ? because an ADF file can contain types that aren't used !)
            foreach (var typeDef in adf.TypeDefinitions)
            {
                AddString(typeDef.Name);
                if (typeDef.Type != AdfFile.TypeDefinitionType.Structure)
                {
                    continue;
                }
                foreach (var member in typeDef.Members)
                {
                    AddString(member.Name);
                }
            }
            // load strings from the instance members (unfold the whole tree)
            foreach (var instance in adf.InstanceInfos)
            {
                AddString(instance.Name);
                foreach (var rootMember in instance.Members)
                {
                    var imiQueue = new Queue <AdfFile.InstanceMemberInfo>();
                    imiQueue.Enqueue(rootMember);

                    while (imiQueue.Count > 0)
                    {
                        var member = imiQueue.Dequeue();

                        AddString(member.Name);
                        AddString(member.StringData);

                        // this is a special case for stringlookup files, where there's a sometime a
                        // HUGE int8 array that contains and UTF-8 encoded string.
                        // so for the sake of finding the more string, we will need to parse
                        // int8 arrays that ends with a null byte
                        // We may be poluted with strings from other languages...
                        bool isString = false;

                        if (member.Type == AdfFile.TypeDefinitionType.Array && !member.isReferenceToId && member.Members.Count > 0 &&
                            (member.TypeDef.ElementTypeHash == AdfTypeHashes.Primitive.Int8 || member.TypeDef.ElementTypeHash == AdfTypeHashes.Primitive.UInt8))
                        {
                            // check if that's a string: it should end with \0
                            sbyte last = (sbyte)member.Members.Last().Data.ReadByte();
                            member.Members.Last().Data.Position = 0;
                            if (last == 0)
                            {
                                isString = true;
                                List <byte> accum = new List <byte>();
                                foreach (var character in member.Members)
                                {
                                    byte current = (byte)character.Data.ReadByte();
                                    if (current != 0)
                                    {
                                        accum.Add(current);
                                    }
                                    else // write the string
                                    {
                                        var str = Encoding.UTF8.GetString(accum.ToArray());
                                        if (!this._StringLookupList.Contains(str))
                                        {
                                            this._StringLookupList.Add(str);
                                        }
                                        accum.Clear();
                                    }
                                }
                            }
                        }

                        // if that's not a hidden string array:
                        if (!isString)
                        {
                            foreach (var subMember in member.Members)
                            {
                                imiQueue.Enqueue(subMember);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 20
0
        private void HandleStream(Stream file, string type)
        {
            file.Position = 0;
            if (type == "ADF")
            {
                // Got some AAF file
                bool inc = false;
                try
                {
                    var adf = new AdfFile();
                    try
                    {
                        adf.Deserialize(file);
                        ++ADFReadCount;
                    }
                    catch
                    {
                        inc = true;
                        ++ADFSkipCount;
                    }
                    ADFExtractStrings(adf);
                }
                catch
                {
                    if (!inc)
                    {
                        ++ADFSkipCount;
                    }
                }
            }
            else if (type == "RTPC")
            {
                // Got some RTPC file
                try
                {
                    var propertyContainerFile = new PropertyContainerFile();
                    propertyContainerFile.Deserialize(file);
                    RTPCExtractStrings(propertyContainerFile);
                    ++RTPCReadCount;
                }
                catch
                {
                    ++RTPCSkipCount;
                }
            }
            else if (type == "AAF")
            {
                // Got some AAF Archive
                using (var cool = CreateCoolArchiveStream(file))
                {
                    var input = cool ?? file;

                    var smallArchive = new SmallArchiveFile();
                    smallArchive.Deserialize(input);

                    foreach (var entry in smallArchive.Entries)
                    {
                        this.AddString(entry.Name);
                        if (entry.Offset == 0)
                        {
                            continue;
                        }

                        ++this.FileCount;
                        this.PrintProgress();

                        input.Position = entry.Offset;
                        string subtype = this.GetType(input);
                        if (string.IsNullOrEmpty(subtype))
                        {
                            continue;
                        }
                        using (var entryStream = entry.ReadToMemoryStream(input))
                        {
                            this.HandleStream(entryStream, subtype);
                        }
                    }

                    ++this.AAFExtractCount;
                }
            }
        }
Exemplo n.º 21
0
        private static void Main(string[] args)
        {
            var  mode     = Mode.Unknown;
            bool showHelp = false;

            var options = new OptionSet
            {
                // ReSharper disable AccessToModifiedClosure
                { "e|export", "convert from binary to JSON", v => SetOption(v, ref mode, Mode.Export) },
                { "i|import", "convert from JSON to binary", v => SetOption(v, ref mode, Mode.Import) },
                // ReSharper restore AccessToModifiedClosure
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (mode == Mode.Unknown && extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);
                if (extension != null && extension.ToLowerInvariant() == ".json")
                {
                    mode = Mode.Import;
                }
                else
                {
                    mode = Mode.Export;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true ||
                mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-e] input_item_onlinec [output_json]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ [-i] input_json [output_item_onlinec]", GetExecutableName());
                Console.WriteLine("Convert an item file between binary and JSON format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            if (mode == Mode.Export)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".json");

                var adf      = new AdfFile();
                var itemRoot = new ItemRoot();

                using (var input = File.OpenRead(inputPath))
                {
                    adf.Deserialize(input);

                    var itemRootInfo = adf.InstanceInfos.FirstOrDefault(i => i.Name == "Profile");
                    if (itemRootInfo.TypeHash != ItemRoot.TypeHash)
                    {
                        throw new FormatException();
                    }

                    input.Position = itemRootInfo.Offset;
                    itemRoot.Deserialize(input, adf.Endian);
                }

                using (var output = File.Create(outputPath))
                    using (var textWriter = new StreamWriter(output))
                        using (var writer = new JsonTextWriter(textWriter))
                        {
                            writer.Indentation = 2;
                            writer.IndentChar  = ' ';
                            writer.Formatting  = Formatting.Indented;

                            var jsonItems = itemRoot.Items.Select(
                                i =>
                            {
                                var jsonItem = new ItemRootJson.Item()
                                {
                                    Name              = ResolveHash(adf, i.Name),
                                    BaseName          = ResolveHash(adf, i.BaseName),
                                    Type              = i.Type,
                                    Purchasable       = i.Purchasable,
                                    Consumable        = i.Consumable,
                                    Rewardable        = i.Rewardable,
                                    Collectable       = i.Collectable,
                                    Region            = ResolveHash(adf, i.Region),
                                    RebelDropTimer    = i.RebelDropTimer,
                                    MaxInventory      = i.MaxInventory,
                                    UIType            = (UIItemType)i.UIType,
                                    UIFlag            = (UIItemSubtype)i.UIFlag,
                                    UIDisplayOrder    = i.UIDisplayOrder,
                                    UIName            = ResolveHash(adf, i.UIName),
                                    UIDescription     = ResolveHash(adf, i.UIDescription),
                                    UITypeDescription = ResolveHash(adf, i.UITypeDescription),
                                    UIFlagDescription = ResolveHash(adf, i.UIFlagDescription),
                                    UIImagePath       = i.UIImagePath,
                                    UIVideoPath       = i.UIVideoPath,
                                    UIPar0            = i.UIPar0,
                                    UIPar1            = i.UIPar1,
                                    UIPar2            = i.UIPar2,
                                    UIPar3            = i.UIPar3,
                                    UIPar4            = i.UIPar4,
                                };
                                jsonItem.Feats.AddRange(i.Feats.Select(f => ResolveHash(adf, f)));
                                return(jsonItem);
                            }).ToArray();

                            var serializer = JsonSerializer.Create();
                            serializer.Serialize(writer, jsonItems);
                        }
            }
            else if (mode == Mode.Import)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".onlinec");

                var adf = new AdfFile()
                {
                    Endian = Endian.Little,
                };
                var itemRoot = new ItemRoot();

                using (var input = File.OpenRead(inputPath))
                    using (var textReader = new StreamReader(input))
                        using (var reader = new JsonTextReader(textReader))
                        {
                            var serializer = JsonSerializer.Create();
                            var jsonItems  = serializer.Deserialize <ItemRootJson.Item[]>(reader);

                            itemRoot.Items.AddRange(jsonItems.Select(
                                                        ji => new ItemRoot.Item()
                            {
                                Name              = ComputeHash(adf, ji.Name),
                                BaseName          = ComputeHash(adf, ji.BaseName),
                                Type              = ji.Type,
                                Purchasable       = ji.Purchasable,
                                Consumable        = ji.Consumable,
                                Rewardable        = ji.Rewardable,
                                Collectable       = ji.Collectable,
                                Feats             = ji.Feats.Select(f => ComputeHash(adf, f)).ToArray(),
                                Region            = ComputeHash(adf, ji.Region),
                                RebelDropTimer    = ji.RebelDropTimer,
                                MaxInventory      = ji.MaxInventory,
                                UIType            = (int)ji.UIType,
                                UIFlag            = (int)ji.UIFlag,
                                UIDisplayOrder    = ji.UIDisplayOrder,
                                UIName            = ComputeHash(adf, ji.UIName),
                                UIDescription     = ComputeHash(adf, ji.UIDescription),
                                UITypeDescription = ComputeHash(adf, ji.UITypeDescription),
                                UIFlagDescription = ComputeHash(adf, ji.UIFlagDescription),
                                UIImagePath       = ji.UIImagePath,
                                UIVideoPath       = ji.UIVideoPath,
                                UIPar0            = ji.UIPar0,
                                UIPar1            = ji.UIPar1,
                                UIPar2            = ji.UIPar2,
                                UIPar3            = ji.UIPar3,
                                UIPar4            = ji.UIPar4,
                            }));
                        }

                using (var output = File.Create(outputPath))
                {
                    using (var data = new MemoryStream())
                    {
                        itemRoot.Serialize(data, adf.Endian);
                        data.Flush();
                        data.Position = 0;

                        output.Position = adf.EstimateHeaderSize();
                        var itemRootPosition = output.Position;
                        output.WriteFromStream(data, data.Length);

                        adf.InstanceInfos.Add(new AdfFile.InstanceInfo()
                        {
                            Name     = "Profile",
                            NameHash = "Profile".HashJenkins(),
                            Offset   = (uint)itemRootPosition,
                            Size     = (uint)data.Length,
                            TypeHash = ItemRoot.TypeHash,
                        });

                        adf.Serialize(output, 0);
                    }
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
        private void HandleStream(Stream file, string type)
        {
            // flush if the limit is reached
            if (this._EntryCount > 300000)
            {
                this.flush();
            }

            //file.Position = 0;
            if (type == "ADF")
            {
                // Got some AAF file
                bool inc = false;
                try
                {
                    var adf = new AdfFile();
                    try
                    {
                        adf.Deserialize(file);
                        ++ADFReadCount;
                    }
                    catch
                    {
                        inc = true;
                        ++ADFSkipCount;
                    }
                    ADFExtractStrings(adf);
                }
                catch
                {
                    if (!inc)
                    {
                        ++ADFSkipCount;
                    }
                }
            }
            else if (type == "RTPC")
            {
                // Got some RTPC file
                try
                {
                    var propertyContainerFile = new PropertyContainerFile();
                    propertyContainerFile.Deserialize(file);
                    RTPCExtractStrings(propertyContainerFile);
                    ++RTPCReadCount;
                }
                catch
                {
                    ++RTPCSkipCount;
                }
            }
            else if (type == "AAF")
            {
                // Got some AAF Archive
                using (var cool = CreateCoolArchiveStream(file))
                {
                    var input = cool ?? file;

                    var smallArchive = new SmallArchiveFile();
                    smallArchive.Deserialize(input);

                    this._CurrentFile.Add(null);

                    foreach (var entry in smallArchive.Entries)
                    {
                        this.AddString(entry.Name);
                        if (entry.Offset == 0)
                        {
                            continue;
                        }

                        ++this.FileCount;
                        this.PrintProgress();

                        input.Position = entry.Offset;
                        string subtype = this.GetType(input);
                        if (string.IsNullOrEmpty(subtype))
                        {
                            continue;
                        }
                        // insert the name
                        this._CurrentFile[this._CurrentFile.Count - 1] = entry.Name;
                        this.UpdateCurrentFile();
                        // process the file
                        using (var entryStream = entry.ReadToMemoryStream(input))
                        {
                            // I know that this copies a copy of a memory (that's a stupid thing)
                            // but without this the memories goes crazy and if I force GC Collect
                            // that's even worse. So a little copy doesn't look bad in front of
                            // the horrors produced when you don't have it.
                            // to see what it's like, replace entryStream with input.
                            this.HandleStream(entryStream, subtype);
                        }
                    }

                    this._CurrentFile.RemoveAt(this._CurrentFile.Count - 1);

                    ++this.AAFExtractCount;
                }
            }
        }