public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { string[] baseArgs = Environment.GetCommandLineArgs(); List <string> args = new List <string>(); string[] origFlags = baseArgs.Where(x => x[0] == '-').ToArray(); args.Add(flags.Positionals[0]); Dictionary <string, string> tracking = new Dictionary <string, string>(); tracking[Opt.ToString()] = string.Empty; tracking[FullOpt] = string.Empty; foreach (string modeargument in flags.Positionals.Skip(2)) { string modearg = modeargument; string subargs = null; if (modearg.Contains('[')) { modearg = modearg.Substring(0, modearg.Length - 1); subargs = modearg.Substring(modearg.IndexOf('[') + 1); modearg = modearg.Substring(0, modearg.IndexOf('[')); } string[] modes = modearg.Split('+'); foreach (string mode in modes) { tracking[mode] = subargs; } } foreach (KeyValuePair <string, string> modes in tracking) { string mode = modes.Key; if ((mode.Length == 1 && mode[0] == Opt) || mode == FullOpt) { continue; } if (!Program.toolsMap.ContainsKey(mode)) { continue; } string subargs = modes.Value; string global = tracking[Opt.ToString()] + " " + tracking[FullOpt]; List <string> tmp = new List <string>(); tmp.Add(baseArgs[0]); tmp.Add(mode.ToString()); tmp.Add(global); tmp.Add(subargs); string[] newargs = CommandLineToArgs(string.Join(" ", tmp)); tmp.Clear(); tmp.AddRange(origFlags); tmp.AddRange(args); tmp.AddRange(newargs.Skip(1)); OverToolFlags newflags = FlagParser.Parse <OverToolFlags>(null, tmp.ToArray()); IOvertool tool = Program.toolsMap[mode]; tool.Parse(track, map, handler, quiet, newflags); } }
private static void Main() { Console.OutputEncoding = Encoding.UTF8; Flags = FlagParser.Parse <ToolFlags>(); if (Flags == null) { return; } var f = Flags; InitStorage(); InitMisc(); InitKeys(); string[] modeArgs = Flags.Positionals.Skip(2).ToArray(); switch (Flags.Mode.ToLower()) { case "extract": Extract(modeArgs); break; case "extract-type": ExtractType(modeArgs); break; case "search": Search(modeArgs); break; case "search-type": SearchType(modeArgs); break; case "info": Info(modeArgs); break; case "convert": Convert(modeArgs); break; case "types": Types(modeArgs); break; default: Console.Out.WriteLine("Available modes: extract, search, search-type, info"); break; } }
private static void Convert(string[] args) { string output = args.FirstOrDefault(); ulong[] guids = args.Skip(1).Select(x => ulong.Parse(x, NumberStyles.HexNumber)).ToArray(); if (string.IsNullOrWhiteSpace(output)) { return; } Dictionary <ulong, PackageRecord[]> records = new Dictionary <ulong, PackageRecord[]>(); Dictionary <ulong, PackageHeader> packages = new Dictionary <ulong, PackageHeader>(); var apm = TankHandler.m_packageManifest; for (int i = 0; i < apm.m_packageEntries.Length; ++i) { PackageEntry entry = apm.m_packageEntries[i]; if (!guids.Contains(teResourceGUID.LongKey(entry.m_packageGUID)) && !guids.Contains(teResourceGUID.Index(entry.m_packageGUID)) && !guids.Contains(entry.m_packageGUID)) { continue; } packages[entry.m_packageGUID] = apm.m_packages[i]; records[entry.m_packageGUID] = apm.m_packageRecords[i]; } ICLIFlags flags = FlagParser.Parse <ExtractFlags>(); void Body(ulong key) { DataTool.FindLogic.Combo.ComboInfo info = new DataTool.FindLogic.Combo.ComboInfo(); string dest = Path.Combine(output, teResourceGUID.AsString(key)); foreach (PackageRecord record in records[key]) { DataTool.FindLogic.Combo.Find(info, record.m_GUID); } var context = new DataTool.SaveLogic.Combo.SaveContext(info); DataTool.SaveLogic.Combo.Save(flags, dest, context); context.Wait(); } Parallel.ForEach(records.Keys, Body); }
static void Main(string[] args) { FlagParser.Parse(args); var file = FlagParser.StringFlag("file", string.Empty, true); var hash = FlagParser.StringFlag("hash", string.Empty, true); if (string.IsNullOrWhiteSpace(file) || string.IsNullOrWhiteSpace(hash)) { Console.WriteLine("Invalid Parameters"); return; } using var hashAlgo = HashAlgorithm.Create(hash ?? "SHA512"); using var stream = File.OpenRead(file); var checksum = BitConverter.ToString(hashAlgo.ComputeHash(stream)).Replace("-", string.Empty).ToLowerInvariant(); Console.WriteLine("--- File Checksum ---"); Console.WriteLine(checksum); }
private static void Convert(string[] args) { string output = args.FirstOrDefault(); ulong[] guids = args.Skip(1).Select(x => ulong.Parse(x, NumberStyles.HexNumber)).ToArray(); if (string.IsNullOrWhiteSpace(output)) { return; } Dictionary <ulong, PackageRecord[]> records = new Dictionary <ulong, PackageRecord[]>(); Dictionary <ulong, Package> packages = new Dictionary <ulong, Package>(); foreach (ApplicationPackageManifest apm in Root.APMFiles) { for (int i = 0; i < apm.PackageEntries.Length; ++i) { PackageEntry entry = apm.PackageEntries[i]; if (guids.Contains(teResourceGUID.LongKey(entry.PackageGUID)) || guids.Contains(teResourceGUID.Index(entry.PackageGUID))) { packages[entry.PackageGUID] = apm.Packages[i]; records[entry.PackageGUID] = apm.Records[i]; } } } ICLIFlags flags = FlagParser.Parse <ExtractFlags>(); MapCMF(); LoadGUIDTable(); Sound.WwiseBank.GetReady(); Parallel.ForEach(records.Keys, (key) => { DataTool.FindLogic.Combo.ComboInfo info = new DataTool.FindLogic.Combo.ComboInfo(); string dest = Path.Combine(output, teResourceGUID.AsString(key)); foreach (PackageRecord record in records[key]) { DataTool.FindLogic.Combo.Find(info, record.GUID); } DataTool.SaveLogic.Combo.Save(flags, dest, info); }); }
private static void Main() { Console.OutputEncoding = Encoding.UTF8; Files = new Dictionary <ulong, PackageRecord>(); TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); #region Tool Detection HashSet <Type> tools = new HashSet <Type>(); { Assembly asm = typeof(ITool).Assembly; Type t = typeof(ITool); List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList(); foreach (Type tt in types) { ToolAttribute attrib = tt.GetCustomAttribute <ToolAttribute>(); if (tt.IsInterface || attrib == null) { continue; } tools.Add(tt); if (attrib.TrackTypes == null) { continue; } foreach (ushort type in attrib.TrackTypes) { if (!TrackedFiles.ContainsKey(type)) { TrackedFiles[type] = new HashSet <ulong>(); } } } } #endregion Flags = FlagParser.Parse <ToolFlags>(() => PrintHelp(tools)); if (Flags == null) { return; } Logger.EXIT = !Flags.GracefulExit; ITool targetTool = null; ICLIFlags targetToolFlags = null; #region Tool Activation foreach (Type type in tools) { ToolAttribute attrib = type.GetCustomAttribute <ToolAttribute>(); if (!string.Equals(attrib.Keyword, Flags.Mode, StringComparison.InvariantCultureIgnoreCase)) { continue; } targetTool = Activator.CreateInstance(type) as ITool; if (attrib.CustomFlags != null) { Type flags = attrib.CustomFlags; if (typeof(ICLIFlags).IsAssignableFrom(flags)) { targetToolFlags = typeof(FlagParser).GetMethod("Parse", new Type[] { }).MakeGenericMethod(flags).Invoke(null, null) as ICLIFlags; } } break; } #endregion if (targetTool == null) { FlagParser.Help <ToolFlags>(false); PrintHelp(tools); if (Debugger.IsAttached) { Debugger.Break(); } return; } #region Initialize CASC Log("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, Util.GetVersion()); Log("Initializing CASC..."); Log("Set language to {0}", Flags.Language); CDNIndexHandler.Cache.Enabled = Flags.UseCache; CDNIndexHandler.Cache.CacheData = Flags.CacheData; CDNIndexHandler.Cache.Validate = Flags.ValidateCache; // ngdp:us:pro // http:us:pro:us.patch.battle.net:1119 if (Flags.OverwatchDirectory.ToLowerInvariant().Substring(0, 5) == "ngdp:") { string cdn = Flags.OverwatchDirectory.Substring(5, 4); string[] parts = Flags.OverwatchDirectory.Substring(5).Split(':'); string region = "us"; string product = "pro"; if (parts.Length > 1) { region = parts[1]; } if (parts.Length > 2) { product = parts[2]; } if (cdn == "bnet") { Config = CASCConfig.LoadOnlineStorageConfig(product, region); } else { if (cdn == "http") { string host = string.Join(":", parts.Skip(3)); Config = CASCConfig.LoadOnlineStorageConfig(host, product, region, true, true, true); } } } else { Config = CASCConfig.LoadLocalStorageConfig(Flags.OverwatchDirectory, !Flags.SkipKeys, false); } Config.Languages = new HashSet <string>(new[] { Flags.Language }); #endregion foreach (Dictionary <string, string> build in Config.BuildInfo) { if (!build.ContainsKey("Tags")) { continue; } if (build["Tags"].Contains("XX?")) { IsPTR = true; } // us ptr region is known as XX, so just look for it in the tags. // this should work... untested for Asia } BuildVersion = uint.Parse(Config.BuildName.Split('.').Last()); if (Flags.SkipKeys) { Log("Disabling Key auto-detection..."); } Log("Using Overwatch Version {0}", Config.BuildName); CASC = CASCHandler.OpenStorage(Config); Root = CASC.Root as OwRootHandler; if (Root == null) { ErrorLog("Not a valid overwatch installation"); return; } // Fail when trying to extract data from a specified language with 2 or less files found. if (!Root.APMFiles.Any()) { ErrorLog("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", Flags.Language); if (!Flags.GracefulExit) { return; } } Log("Mapping..."); TrackedFiles[0x90] = new HashSet <ulong>(); IO.MapCMF(); IO.LoadGUIDTable(); Sound.WwiseBank.GetReady(); #region Key Detection if (!Flags.SkipKeys) { Log("Adding Encryption Keys..."); foreach (ulong key in TrackedFiles[0x90]) { if (!ValidKey(key)) { continue; } using (Stream stream = IO.OpenFile(Files[key])) { if (stream == null) { continue; } STUEncryptionKey encryptionKey = GetInstance <STUEncryptionKey>(key); if (encryptionKey != null && encryptionKey.LongKey != 0 && !KeyService.keys.ContainsKey(encryptionKey.LongRevKey)) { KeyService.keys.Add(encryptionKey.LongRevKey, encryptionKey.KeyValue); Log("Added Encryption Key {0}, Value: {1}", encryptionKey.KeyNameProper, encryptionKey.Key); } } } } #endregion Log("Tooling..."); targetTool.Parse(targetToolFlags); if (Debugger.IsAttached) { Debugger.Break(); } }
public IList <IRule> Parse(TextReader input) { string?line; var rules = new List <IRule>(); var builder = new RuleBuilder(); var lineNum = 0; // parsers var testStringParser = new TestStringParser(); var conditionParser = new ConditionPatternParser(); var regexParser = new RuleRegexParser(); var flagsParser = new FlagParser(); var tokenizer = new Tokenizer(); while ((line = input.ReadLine()) != null) { lineNum++; if (string.IsNullOrEmpty(line)) { continue; } if (line.StartsWith('#')) { continue; } var tokens = tokenizer.Tokenize(line) !; if (tokens.Count > 4) { // This means the line didn't have an appropriate format, throw format exception throw new FormatException(Resources.FormatError_ModRewriteParseError("Too many tokens on line", lineNum)); } switch (tokens[0]) { case "RewriteBase": // the notion of the path base spans across all rules, not just mod_rewrite // So not implemented for now throw new NotImplementedException("RewriteBase is not implemented"); case "RewriteCond": try { var pattern = testStringParser.Parse(tokens[1]); var condActionParsed = conditionParser.ParseActionCondition(tokens[2]); var flags = new Flags(); if (tokens.Count == 4) { flags = flagsParser.Parse(tokens[3]); } builder.AddConditionFromParts(pattern, condActionParsed, flags); } catch (FormatException formatException) { throw new FormatException(Resources.FormatError_ModRewriteGeneralParseError(lineNum), formatException); } break; case "RewriteRule": try { var regex = regexParser.ParseRuleRegex(tokens[1]); var pattern = testStringParser.Parse(tokens[2]); Flags flags; if (tokens.Count == 4) { flags = flagsParser.Parse(tokens[3]); } else { flags = new Flags(); } builder.AddMatch(regex, flags); builder.AddAction(pattern, flags); rules.Add(builder.Build()); builder = new RuleBuilder(); } catch (FormatException formatException) { throw new FormatException(Resources.FormatError_ModRewriteGeneralParseError(lineNum), formatException); } break; case "RewriteMap": // Lack of use throw new NotImplementedException("RewriteMap are not implemented"); case "RewriteEngine": // Explicitly do nothing here, no notion of turning on regex engine. break; default: throw new FormatException(Resources.FormatError_ModRewriteParseError("Unrecognized keyword: " + tokens[0], lineNum)); } } return(rules); }
private static void Main() { InitTankSettings(); HookConsole(); var tools = GetTools(); #if DEBUG FlagParser.CheckCollisions(typeof(ToolFlags), (flag, duplicate) => { Logger.Error("Flag", $"The flag \"{flag}\" from {duplicate} is a duplicate!"); }); #endif FlagParser.LoadArgs(); Logger.Info("Core", $"{Assembly.GetExecutingAssembly().GetName().Name} v{Util.GetVersion(typeof(Program).Assembly)}"); Logger.Info("Core", $"CommandLine: [{string.Join(", ", FlagParser.AppArgs.Select(x => $"\"{x}\""))}]"); Flags = FlagParser.Parse <ToolFlags>(full => PrintHelp(full, tools)); if (Flags == null) { return; } Logger.Info("Core", $"CommandLineFile: {FlagParser.ArgFilePath}"); if (Flags.SaveArgs) { FlagParser.AppArgs = FlagParser.AppArgs.Where(x => !x.StartsWith("--arg")) .ToArray(); FlagParser.SaveArgs(Flags.OverwatchDirectory); } else if (Flags.ResetArgs || Flags.DeleteArgs) { FlagParser.ResetArgs(); if (Flags.DeleteArgs) { FlagParser.DeleteArgs(); } Logger.Info("Core", $"CommandLineNew: [{string.Join(", ", FlagParser.AppArgs.Select(x => $"\"{x}\""))}]"); Flags = FlagParser.Parse <ToolFlags>(full => PrintHelp(full, tools)); if (Flags == null) { return; } } if (string.IsNullOrWhiteSpace(Flags.OverwatchDirectory) || string.IsNullOrWhiteSpace(Flags.Mode) || Flags.Help) { PrintHelp(false, tools); return; } ITool targetTool = null; ICLIFlags targetToolFlags = null; ToolAttribute targetToolAttributes = null; #region Tool Activation foreach (var type in tools) { var attribute = type.GetCustomAttribute <ToolAttribute>(); if (!string.Equals(attribute.Keyword, Flags.Mode, StringComparison.InvariantCultureIgnoreCase)) { continue; } targetTool = Activator.CreateInstance(type) as ITool; targetToolAttributes = attribute; if (attribute.CustomFlags != null) { var flags = attribute.CustomFlags; if (typeof(ICLIFlags).IsAssignableFrom(flags)) { targetToolFlags = typeof(FlagParser).GetMethod(nameof(FlagParser.Parse), new Type[] { }) ?.MakeGenericMethod(flags) .Invoke(null, null) as ICLIFlags; } } break; } if (targetToolFlags == null) { return; } #endregion if (targetTool == null) { FlagParser.Help <ToolFlags>(false, new Dictionary <string, string>()); PrintHelp(false, tools); return; } if (!targetToolAttributes.UtilNoArchiveNeeded) { InitStorage(); //foreach (KeyValuePair<ushort, HashSet<ulong>> type in TrackedFiles.OrderBy(x => x.Key)) { // //Console.Out.WriteLine($"Found type: {type.Key:X4} ({type.Value.Count} files)"); // Console.Out.WriteLine($"Found type: {type.Key:X4}"); //} InitKeys(); InitMisc(); } var stopwatch = new Stopwatch(); Logger.Info("Core", "Tooling..."); stopwatch.Start(); targetTool.Parse(targetToolFlags); stopwatch.Stop(); Logger.Success("Core", $"Execution finished in {stopwatch.Elapsed} seconds"); ShutdownMisc(); }
public static void Main(string[] args) { if (args.Length < 2) { Console.Out.WriteLine("Usage: Mp4Tool {overwatch dir} {file} [--json] [--out=outfile.json]"); return; } string gameDir = args[0]; string filePath = args[1]; var files = new List <string>(); var fileAttributes = File.GetAttributes(filePath); if (fileAttributes.HasFlag(FileAttributes.Directory)) { files.AddRange(Directory.GetFiles(filePath, "*.mp4", SearchOption.TopDirectoryOnly)); if (files.Count == 0) { Console.Out.WriteLine("Found no valid mp4 files."); return; } } else { if (!filePath.EndsWith(".mp4")) { Console.Out.WriteLine("Only MP4s are supported"); return; } files.Add(filePath); } var flags = FlagParser.Parse <ListFlags>(); var toolFlags = FlagParser.Parse <ToolFlags>(); DataTool.Program.Flags = new ToolFlags { OverwatchDirectory = gameDir, Language = toolFlags.Language ?? "enUS", SpeechLanguage = toolFlags.SpeechLanguage ?? "enUS", Quiet = true, Online = false }; DataTool.Program.InitStorage(false); var replays = ReplayThing.ParseReplays(files); if (flags.JSON) { new JSONTool().OutputJSON(replays, flags); } else { foreach (ReplayThing.Replay replay in replays) { Console.Out.WriteLine("Replay Info:"); Console.Out.WriteLine($" - Title: {replay.Title}"); Console.Out.WriteLine($" - Hero: {replay.Hero}"); Console.Out.WriteLine($" - Map: {replay.Map}"); Console.Out.WriteLine($" - Skin: {replay.Skin}"); Console.Out.WriteLine($" - Recorded At: {replay.RecordedAt}"); Console.Out.WriteLine($" - Type: {replay.HighlightType}"); Console.Out.WriteLine($" - Quality: {replay.Quality})"); Console.Out.WriteLine("\n"); } } }
static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; List <IOvertool> tools = new List <IOvertool>(); { Assembly asm = typeof(IOvertool).Assembly; Type t = typeof(IOvertool); List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList(); foreach (Type tt in types) { if (tt.IsInterface) { continue; } IOvertool toolinst = (IOvertool)Activator.CreateInstance(tt); if (toolinst.Display) { tools.Add(toolinst); } } } OverToolFlags flags = FlagParser.Parse <OverToolFlags>(() => PrintHelp(tools)); if (flags == null) { return; } bool quiet = flags.Quiet; string root = flags.OverwatchDirectory; char opt = flags.Mode[0]; IOvertool tool = null; Dictionary <ushort, List <ulong> > track = new Dictionary <ushort, List <ulong> >(); track[0x90] = new List <ulong>(); // internal requirements toolsMap = new Dictionary <char, IOvertool>(); foreach (IOvertool t in tools) { if (t.Opt == opt) { tool = t; } foreach (ushort tr in t.Track) { if (!track.ContainsKey(tr)) { track[tr] = new List <ulong>(); } } if (toolsMap.ContainsKey(t.Opt)) { Console.Out.WriteLine("Duplicate opt! {0} conflicts with {1}", t.Title, toolsMap[t.Opt].Title); } toolsMap[t.Opt] = t; } if (tool == null || flags.Positionals.Length - 2 < tool.MinimumArgs) { PrintHelp(tools); return; } Dictionary <ulong, Record> map = new Dictionary <ulong, Record>(); Console.Out.WriteLine("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, OWLib.Util.GetVersion()); Console.Out.WriteLine("Initializing CASC..."); Console.Out.WriteLine("Set language to {0}", flags.Language); CDNIndexHandler.Cache.Enabled = flags.UseCache; CDNIndexHandler.Cache.CacheData = flags.CacheData; CDNIndexHandler.Cache.Validate = flags.ValidateCache; CASCConfig config = null; // ngdp:us:pro // http:us:pro:us.patch.battle.net:1119 if (root.ToLowerInvariant().Substring(0, 5) == "ngdp:") { string cdn = root.Substring(5, 4); string[] parts = root.Substring(5).Split(':'); string region = "us"; string product = "pro"; if (parts.Length > 1) { region = parts[1]; } if (parts.Length > 2) { product = parts[2]; } if (cdn == "bnet") { config = CASCConfig.LoadOnlineStorageConfig(product, region); } else { if (cdn == "http") { string host = string.Join(":", parts.Skip(3)); config = CASCConfig.LoadOnlineStorageConfig(host, product, region, true, true, true); } } } else { config = CASCConfig.LoadLocalStorageConfig(root, !flags.SkipKeys, false); } config.Languages = new HashSet <string>(new string[1] { flags.Language }); if (flags.SkipKeys) { Console.Out.WriteLine("Disabling Key auto-detection..."); } Console.Out.WriteLine("Using Overwatch Version {0}", config.BuildName); CASCHandler handler = CASCHandler.OpenStorage(config); OwRootHandler ow = handler.Root as OwRootHandler; if (ow == null) { Console.Error.WriteLine("Not a valid overwatch installation"); return; } // Fail when trying to extract data from a specified language with 2 or less files found. if (ow.APMFiles.Count() == 0) { Console.Error.WriteLine("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", flags.Language); return; } Console.Out.WriteLine("Mapping..."); Util.MapCMF(ow, handler, map, track, flags); if (!flags.SkipKeys) { Console.Out.WriteLine("Adding Encryption Keys..."); foreach (ulong key in track[0x90]) { if (!map.ContainsKey(key)) { continue; } using (Stream stream = Util.OpenFile(map[key], handler)) { if (stream == null) { continue; } STUD stud = new STUD(stream); if (stud.Instances[0].Name != stud.Manager.GetName(typeof(EncryptionKey))) { continue; } EncryptionKey ek = (EncryptionKey)stud.Instances[0]; if (!KeyService.keys.ContainsKey(ek.KeyNameLong)) { KeyService.keys.Add(ek.KeyNameLong, ek.KeyValueText.ToByteArray()); Console.Out.WriteLine("Added Encryption Key {0}, Value: {1}", ek.KeyNameText, ek.KeyValueText); } } } } Console.Out.WriteLine("Tooling..."); tool.Parse(track, map, handler, quiet, flags); if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break(); } }
static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; List <IOvertool> tools = new List <IOvertool>(); { Assembly asm = typeof(IOvertool).Assembly; Type t = typeof(IOvertool); List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList(); foreach (Type tt in types) { if (tt.IsInterface) { continue; } IOvertool toolinst = (IOvertool)Activator.CreateInstance(tt); if (toolinst.Display) { tools.Add(toolinst); } } } OverToolFlags flags = FlagParser.Parse <OverToolFlags>(() => PrintHelp(tools)); if (flags == null) { return; } Logger.EXIT = !flags.GracefulExit; bool quiet = flags.Quiet; string root = flags.OverwatchDirectory; string opt = flags.Mode; IOvertool tool = null; Dictionary <ushort, List <ulong> > track = new Dictionary <ushort, List <ulong> > { [0x90] = new List <ulong>() // internal requirements }; toolsMap = new Dictionary <string, IOvertool>(); foreach (IOvertool t in tools) { if (t.FullOpt == opt || (opt.Length == 1 && t.Opt != (char)0 && t.Opt == opt[0])) { tool = t; } if (t.Track != null) { foreach (ushort tr in t.Track) { if (!track.ContainsKey(tr)) { track[tr] = new List <ulong>(); } } } if (toolsMap.ContainsKey(t.FullOpt)) { Console.Out.WriteLine("Duplicate opt! {0} conflicts with {1}", t.Title, toolsMap[t.FullOpt].Title); } if (t.FullOpt.Length == 1) { Console.Out.WriteLine("FullOpt should not be length 1 for {0}", t.Title); } toolsMap[t.FullOpt] = t; } if (tool == null || flags.Positionals.Length - 2 < tool.MinimumArgs) { PrintHelp(tools); return; } Dictionary <ulong, Record> map = new Dictionary <ulong, Record>(); Console.Out.WriteLine("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, OWLib.Util.GetVersion()); Console.Out.WriteLine("Initializing CASC..."); Console.Out.WriteLine("Set language to {0}", flags.Language); CDNIndexHandler.Cache.Enabled = flags.UseCache; CDNIndexHandler.Cache.CacheData = flags.CacheData; CDNIndexHandler.Cache.Validate = flags.ValidateCache; CASCConfig config = null; // ngdp:us:pro // http:us:pro:us.patch.battle.net:1119 if (root.ToLowerInvariant().Substring(0, 5) == "ngdp:") { string cdn = root.Substring(5, 4); string[] parts = root.Substring(5).Split(':'); string region = "us"; string product = "pro"; if (parts.Length > 1) { region = parts[1]; } if (parts.Length > 2) { product = parts[2]; } if (cdn == "bnet") { config = CASCConfig.LoadOnlineStorageConfig(product, region); } else { if (cdn == "http") { string host = string.Join(":", parts.Skip(3)); config = CASCConfig.LoadOnlineStorageConfig(host, product, region, true, true, true); } } } else { config = CASCConfig.LoadLocalStorageConfig(root, !flags.SkipKeys, false); } config.Languages = new HashSet <string>(new string[1] { flags.Language }); if (flags.SkipKeys) { Console.Out.WriteLine("Disabling Key auto-detection..."); } Regex versionRegex = new Regex(@"\d+\.\d+"); Match versionMatch = versionRegex.Match(config.BuildName); if (versionMatch.Success) { float version = float.Parse(versionMatch.Value); if (version > 1.13) { Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine("==========\nWARNING: Overtool only works with Overwatch version 1.13 and below! You are using {0}!", config.BuildName); Console.Out.WriteLine("You must use DataTool for Overwatch 1.14 and above!\n=========="); Console.ResetColor(); } } Console.Out.WriteLine("Using Overwatch Version {0}", config.BuildName); CASCHandler handler = CASCHandler.OpenStorage(config); OwRootHandler ow = handler.Root as OwRootHandler; if (ow == null) { Console.Error.WriteLine("Not a valid overwatch installation"); return; } // Fail when trying to extract data from a specified language with 2 or less files found. if (ow.APMFiles.Count() == 0) { Console.Error.WriteLine("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", flags.Language); if (!flags.GracefulExit) { return; } } Console.Out.WriteLine("Mapping..."); Util.MapCMF(ow, handler, map, track, flags.Language); if (!flags.SkipKeys) { Console.Out.WriteLine("Adding Encryption Keys..."); foreach (ulong key in track[0x90]) { if (!map.ContainsKey(key)) { continue; } using (Stream stream = Util.OpenFile(map[key], handler)) { if (stream == null) { continue; } ISTU stu = ISTU.NewInstance(stream, UInt32.Parse(config.BuildName.Split('.').Last())); if (!(stu.Instances.FirstOrDefault() is STUEncryptionKey)) { continue; } STUEncryptionKey ek = stu.Instances.FirstOrDefault() as STUEncryptionKey; if (ek != null && !KeyService.keys.ContainsKey(ek.LongRevKey)) { KeyService.keys.Add(ek.LongRevKey, ek.KeyValue); Console.Out.WriteLine("Added Encryption Key {0}, Value: {1}", ek.KeyNameProper, ek.Key); } } } } Console.Out.WriteLine("Tooling..."); tool.Parse(track, map, handler, quiet, flags); if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break(); } }
static void Main(string[] args) { FlagParser.Parse(args); Console.WriteLine(FlagParser.StringFlag("stringtest", "none", false)); Console.WriteLine(FlagParser.DecimalFlag("dectest", 0.45M, false)); }
static void Main(string[] args) { Dictionary <string, List <string> > admin1codes; Dictionary <string, List <string> > admin2codes; Dictionary <string, List <string> > countries; Dictionary <string, List <string> > features; List <string> filters; FlagParser.ContinueOnError = true; FlagParser.Parse(args); bool help = FlagParser.BoolFlag("help", false, false); if (help || args.Length == 0) { DisplayUsage(); return; } // process input flags string admin1File = FlagParser.StringFlag("admin1", string.Empty, true); string admin2File = FlagParser.StringFlag("admin2", string.Empty, true); string countryFile = FlagParser.StringFlag("countries", string.Empty, true); string featureFile = FlagParser.StringFlag("feature", string.Empty, true); string input = FlagParser.StringFlag("input", string.Empty, true); string output = FlagParser.StringFlag("output", string.Empty, true); string filter = FlagParser.StringFlag("filter", string.Empty, false); string outputType = FlagParser.StringFlag("type", "default", false); if (FlagParser.Errors.Count > 0) { foreach (var e in FlagParser.Errors) { Console.WriteLine(e); } return; } // read admin1 codes admin1codes = ReadAdmin1File(admin1File); if (admin1codes == null) { return; } // read admin2 codes admin2codes = ReadAdmin2File(admin2File); if (admin2codes == null) { return; } // read country codes countries = ReadCountryFile(countryFile); if (countries == null) { return; } // read feature codes features = ReadFeatureFile(featureFile); if (features == null) { return; } // put filters as list filters = new List <string>(); var fltrs = filter.Split(new char[] { ',' }); foreach (var fltr in fltrs) { filters.Add(fltr); } switch (outputType) { case "full-structured": GenerateFullStructuredOutput(input, output, features, filters, countries, admin1codes, admin2codes); break; case "full-flat": default: GenerateDefaultOutput(input, output, features, filters, countries, admin1codes, admin2codes); break; } }
static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; Files = new Dictionary <ulong, PackageRecord>(); TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); Flags = FlagParser.Parse <ToolFlags>(); if (Flags == null) { return; } #region Initialize CASC Log("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, Util.GetVersion()); Log("Initializing CASC..."); Log("Set language to {0}", Flags.Language); CDNIndexHandler.Cache.Enabled = Flags.UseCache; CDNIndexHandler.Cache.CacheData = Flags.CacheData; CDNIndexHandler.Cache.Validate = Flags.ValidateCache; // ngdp:us:pro // http:us:pro:us.patch.battle.net:1119 if (Flags.OverwatchDirectory.ToLowerInvariant().Substring(0, 5) == "ngdp:") { string cdn = Flags.OverwatchDirectory.Substring(5, 4); string[] parts = Flags.OverwatchDirectory.Substring(5).Split(':'); string region = "us"; string product = "pro"; if (parts.Length > 1) { region = parts[1]; } if (parts.Length > 2) { product = parts[2]; } if (cdn == "bnet") { Config = CASCConfig.LoadOnlineStorageConfig(product, region); } else { if (cdn == "http") { string host = string.Join(":", parts.Skip(3)); Config = CASCConfig.LoadOnlineStorageConfig(host, product, region, true, true, true); } } } else { Config = CASCConfig.LoadLocalStorageConfig(Flags.OverwatchDirectory, !Flags.SkipKeys, false); } Config.Languages = new HashSet <string>(new[] { Flags.Language }); #endregion BuildVersion = uint.Parse(Config.BuildName.Split('.').Last()); if (Flags.SkipKeys) { Log("Disabling Key auto-detection..."); } Log("Using Overwatch Version {0}", Config.BuildName); CASC = CASCHandler.OpenStorage(Config); Root = CASC.Root as OwRootHandler; if (Root == null) { ErrorLog("Not a valid overwatch installation"); return; } if (!Root.APMFiles.Any()) { ErrorLog("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", Flags.Language); if (!Flags.GracefulExit) { return; } } string[] modeArgs = Flags.Positionals.Skip(2).ToArray(); switch (Flags.Mode.ToLower()) { case "extract": Extract(modeArgs); break; case "search": Search(modeArgs); break; case "search-type": SearchType(modeArgs); break; case "info": Info(modeArgs); break; case "convert": Convert(modeArgs); break; case "types": Types(modeArgs); break; default: Console.Out.WriteLine("Available modes: extract, search, search-type, info"); break; } }
static void Main(string[] args) { FlagParser.Parse(args); var exeFile = FlagParser.StringFlag("exeFile", string.Empty, true); var exePath = FlagParser.StringFlag("exePath", string.Empty, true); var zipFile = FlagParser.StringFlag("zipFile", string.Empty, true); if (string.IsNullOrWhiteSpace(exeFile) || string.IsNullOrWhiteSpace(exePath) || string.IsNullOrWhiteSpace(zipFile)) { Console.WriteLine("Invalid Parameters"); return; } // make sure exe file to update is not running foreach (var proc in Process.GetProcesses()) { try { if (proc.MainModule.FileName.Equals(exeFile, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("-- Waiting for exit " + exeFile + " --"); proc.WaitForExit(); Console.WriteLine("-- Application closed " + exeFile + " --"); } } catch (Exception e) { Debug.WriteLine(e.Message); Debug.WriteLine(e.StackTrace); } } Console.WriteLine("-- Waiting for process to close --"); Thread.Sleep(5000); Console.WriteLine("-- Extrating Files --"); // open zip file using var zip = ZipStorer.Open(zipFile, FileAccess.Read); var dir = zip.Files.Values; foreach (var item in dir) { try { if (item.FilenameInZip.ToLower().Contains("zipextractor", StringComparison.OrdinalIgnoreCase)) { continue; } var extractFile = Path.Combine(exePath, item.FilenameInZip); if (File.Exists(extractFile)) { Console.WriteLine("-- Deleting File " + extractFile); File.Delete(extractFile); } Console.WriteLine("-- Extracting File " + extractFile); zip.ExtractFile(item, extractFile); Console.WriteLine("-- Done Extracting File " + extractFile); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); continue; } } zip.Close(); // done extract, run exe file again var psi = new ProcessStartInfo(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X64) { psi.FileName = exeFile; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X86) { psi.FileName = exeFile; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.Arm) { psi.FileName = exeFile; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.OSArchitecture == Architecture.X64) { psi.FileName = "/usr/bin/dotnet"; psi.Arguments = exeFile.Replace(".exe", ".dll"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.OSArchitecture == Architecture.Arm) { psi.FileName = "/usr/bin/dotnet"; psi.Arguments = exeFile.Replace(".exe", ".dll"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.OSArchitecture == Architecture.X64) { psi.FileName = "/usr/bin/dotnet"; psi.Arguments = exeFile.Replace(".exe", ".dll"); } Console.WriteLine("-- Running Application --"); Console.WriteLine("Filename : " + psi.FileName); Console.WriteLine("Args : " + psi.Arguments); Process.Start(psi).WaitForExit(); File.Delete(zipFile); Console.WriteLine("-- Update Done --"); return; }
static void Main() { Console.OutputEncoding = Encoding.UTF8; Files = new Dictionary <ulong, PackageRecord>(); TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); Flags = FlagParser.Parse <ToolFlags>(); if (Flags == null) { return; } #region Initialize CASC Log("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, Util.GetVersion()); Log("Initializing CASC..."); if (Flags.Language != null) { Log("Set language to {0}", Flags.Language); } if (Flags.SpeechLanguage != null) { Log("Set speech language to {0}", Flags.SpeechLanguage); } CASCHandler.Cache.CacheAPM = Flags.UseCache; CASCHandler.Cache.CacheCDN = Flags.UseCache; CASCHandler.Cache.CacheCDNData = Flags.CacheData; Config = CASCConfig.LoadFromString(Flags.OverwatchDirectory, Flags.SkipKeys); Config.SpeechLanguage = Flags.SpeechLanguage ?? Flags.Language ?? Config.SpeechLanguage; Config.TextLanguage = Flags.Language ?? Config.TextLanguage; #endregion BuildVersion = uint.Parse(Config.BuildVersion.Split('.').Last()); if (Flags.SkipKeys) { Log("Disabling Key auto-detection..."); } Log("Using Overwatch Version {0}", Config.BuildVersion); CASC = CASCHandler.Open(Config); Root = CASC.RootHandler; if (Root == null) { ErrorLog("Not a valid overwatch installation"); return; } if (!Root.APMFiles.Any()) { ErrorLog("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", Flags.Language); if (!Flags.GracefulExit) { return; } } string[] modeArgs = Flags.Positionals.Skip(2).ToArray(); switch (Flags.Mode.ToLower()) { case "extract": Extract(modeArgs); break; case "search": Search(modeArgs); break; case "search-type": SearchType(modeArgs); break; case "info": Info(modeArgs); break; case "convert": Convert(modeArgs); break; case "types": Types(modeArgs); break; default: Console.Out.WriteLine("Available modes: extract, search, search-type, info"); break; } }
private static void Main() { AppDomain.CurrentDomain.UnhandledException += ExceptionHandler; Process.GetCurrentProcess().EnableRaisingEvents = true; AppDomain.CurrentDomain.ProcessExit += (sender, @event) => Console.ForegroundColor = ConsoleColor.Gray; Console.CancelKeyPress += (sender, @event) => Console.ForegroundColor = ConsoleColor.Gray; Console.OutputEncoding = Encoding.UTF8; Files = new Dictionary <ulong, ApplicationPackageManifest.Types.PackageRecord>(); TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); #region Tool Detection HashSet <Type> tools = new HashSet <Type>(); { Assembly asm = typeof(ITool).Assembly; Type t = typeof(ITool); List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList(); foreach (Type tt in types) { ToolAttribute attrib = tt.GetCustomAttribute <ToolAttribute>(); if (tt.IsInterface || attrib == null) { continue; } tools.Add(tt); if (attrib.TrackTypes == null) { continue; } foreach (ushort type in attrib.TrackTypes) { if (!TrackedFiles.ContainsKey(type)) { TrackedFiles[type] = new HashSet <ulong>(); } } } } #endregion Flags = FlagParser.Parse <ToolFlags>(() => PrintHelp(tools)); if (Flags == null) { return; } //Logger.EXIT = !Flags.GracefulExit; ITool targetTool = null; ICLIFlags targetToolFlags = null; #region Tool Activation foreach (Type type in tools) { ToolAttribute attrib = type.GetCustomAttribute <ToolAttribute>(); if (!string.Equals(attrib.Keyword, Flags.Mode, StringComparison.InvariantCultureIgnoreCase)) { continue; } targetTool = Activator.CreateInstance(type) as ITool; if (attrib.CustomFlags != null) { Type flags = attrib.CustomFlags; if (typeof(ICLIFlags).IsAssignableFrom(flags)) { targetToolFlags = typeof(FlagParser).GetMethod(nameof(FlagParser.Parse), new Type[] { }).MakeGenericMethod(flags).Invoke(null, null) as ICLIFlags; } } break; } #endregion if (targetTool == null) { FlagParser.Help <ToolFlags>(false); PrintHelp(tools); if (Debugger.IsAttached) { Debugger.Break(); } return; } TankLib.Helpers.Logger.Info("Core", $"{Assembly.GetExecutingAssembly().GetName().Name} v{TankLib.Util.GetVersion(typeof(Program).Assembly)}"); TankLib.Helpers.Logger.Info("Core", $"CommandLine: [{string.Join(", ", Environment.GetCommandLineArgs().Skip(1).Select(x => $"\"{x}\""))}]"); #region Initialize CASC if (Flags.Language != null) { TankLib.Helpers.Logger.Info("CASC", $"Set language to {Flags.Language}"); } if (Flags.SpeechLanguage != null) { TankLib.Helpers.Logger.Info("CASC", $"Set speech language to {Flags.SpeechLanguage}"); } CASCHandler.Cache.CacheAPM = Flags.UseCache; CASCHandler.Cache.CacheCDN = Flags.UseCache; CASCHandler.Cache.CacheCDNData = Flags.CacheData; Config = CASCConfig.LoadFromString(Flags.OverwatchDirectory, Flags.SkipKeys); Config.SpeechLanguage = Flags.SpeechLanguage ?? Flags.Language ?? Config.SpeechLanguage; Config.TextLanguage = Flags.Language ?? Config.TextLanguage; if (Config != null) { if (Flags.Language != null && !Config.InstallData.Settings.Languages.Select(x => x.Language).Contains(Flags.Language)) { TankLib.Helpers.Logger.Warn("Core", "Battle.Net Agent reports that language {0} is not installed.", Flags.Language); } if (Config.InstallData.Uid != "prometheus") { TankLib.Helpers.Logger.Warn("Core", $"The branch \"{Config.InstallData.Uid}\" is not supported!. This might result in failure to load. Proceed with caution."); } } #endregion BuildVersion = uint.Parse(Config.BuildVersion.Split('.').Last()); if (BuildVersion < 39028) { TankLib.Helpers.Logger.Error("Core", "DataTool doesn't support Overwatch versions below 1.14. Please use OverTool"); } else if (BuildVersion < 39241) { TankLib.Helpers.Logger.Error("Core", "DataTool doesn't support this 1.14 release as it uses unmangeled hashes"); } else if (BuildVersion < 49154) { TankLib.Helpers.Logger.Error("Core", "This version of DataTool doesn't properly support versions below 1.26. Please downgrade DataTool."); } TankLib.Helpers.Logger.Info("Core", $"Using Overwatch Version {Config.BuildVersion}"); TankLib.Helpers.Logger.Info("CASC", "Initializing..."); CASC = CASCHandler.Open(Config); Root = CASC.RootHandler; //if (Root== null) { // ErrorLog("Not a valid overwatch installation"); // return; //} if (Config.InstallData != null) { } // Fail when trying to extract data from a specified language with 2 or less files found. if (!Root.APMFiles.Any()) { TankLib.Helpers.Logger.Error("Core", "Unable to load APM files for language {0}. Please confirm that you have that language installed.", Flags.Language); return; } TankLib.Helpers.Logger.Info("Core", "Mapping storage"); TrackedFiles[0x90] = new HashSet <ulong>(); IO.MapCMF(); IO.LoadGUIDTable(); Sound.WwiseBank.GetReady(); //foreach (KeyValuePair<ushort, HashSet<ulong>> type in TrackedFiles.OrderBy(x => x.Key)) { // //Console.Out.WriteLine($"Found type: {type.Key:X4} ({type.Value.Count} files)"); // Console.Out.WriteLine($"Found type: {type.Key:X4}"); //} #region Key Detection if (!Flags.SkipKeys) { TankLib.Helpers.Logger.Info("Core", "Checking ResourceKeys"); foreach (ulong key in TrackedFiles[0x90]) { if (!ValidKey(key)) { continue; } using (Stream stream = IO.OpenFile(Files[key])) { if (stream == null) { continue; } STUResourceKey resourceKey = GetInstance <STUResourceKey>(key); if (resourceKey == null || resourceKey.GetKeyID() == 0 || TACTKeyService.Keys.ContainsKey(resourceKey.GetReverseKeyID())) { continue; } TACTKeyService.Keys.Add(resourceKey.GetReverseKeyID(), resourceKey.m_key); TankLib.Helpers.Logger.Info("Core", $"Added ResourceKey {resourceKey.GetKeyIDString()}, Value: {resourceKey.GetKeyValueString()}"); } } } #endregion Stopwatch stopwatch = new Stopwatch(); TankLib.Helpers.Logger.Info("Core", "Tooling..."); var dbPath = Flags.ScratchDBPath; if (Flags.Deduplicate) { TankLib.Helpers.Logger.Warn("ScratchDB", "Will attempt to deduplicate files if extracting..."); if (!string.IsNullOrWhiteSpace(Flags.ScratchDBPath)) { TankLib.Helpers.Logger.Warn("ScratchDB", "Loading deduplication database..."); if (!File.Exists(dbPath)) { dbPath = Path.Combine(Path.GetFullPath(Flags.ScratchDBPath), "Scratch.db"); } SaveLogic.Combo.ScratchDBInstance.Load(dbPath); } } stopwatch.Start(); targetTool.Parse(targetToolFlags); stopwatch.Stop(); TankLib.Helpers.Logger.Success("Core", $"Execution finished in {stopwatch.Elapsed} seconds"); if (Flags.Deduplicate && !string.IsNullOrWhiteSpace(dbPath)) { TankLib.Helpers.Logger.Warn("ScratchDB", "Saving deduplication database..."); SaveLogic.Combo.ScratchDBInstance.Save(dbPath); } if (Debugger.IsAttached) { Debugger.Break(); } }