<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using DataTool.ConvertLogic;
using DataTool.Flag;
using DataTool.Helper;
using DataTool.SaveLogic;
using Microsoft.Win32;
using TankLib;
using TankLib.STU;
using TankLib.STU.Types;
using TankLib.TACT;
using TACTLib.Client;
using TACTLib.Client.HandlerArgs;
using TACTLib.Core.Product.Tank;
using TACTLib.Exceptions;
using TankLib.Helpers;
using static DataTool.Helper.Logger;
using static DataTool.Helper.STUHelper;
using Logger = TankLib.Helpers.Logger;
using static DataTool.Helper.SpellCheckUtils;

namespace DataTool {
    public static class Program {
        public static ClientHandler Client;
        public static ProductHandler_Tank TankHandler;
        public static Dictionary<ushort, HashSet<ulong>> TrackedFiles;

        public static ToolFlags Flags;
        public static uint BuildVersion;
        public static bool IsPTR => Client?.ProductCode == "prot";
        public static bool IsBeta => Client?.ProductCode == "prob";

        public static string[] ValidLanguages = {"deDE", "enUS", "esES", "esMX", "frFR", "itIT", "jaJP", "koKR", "plPL", "ptBR", "ruRU", "zhCN", "zhTW"};

        public static bool ValidKey(ulong key) {
            return TankHandler.m_assets.ContainsKey(key);
        }

        public static HashSet<Type> GetTools(bool noDebugTools = false) {
            var tools = new HashSet<Type>();
            {
                var t = typeof(ITool);
                var asm = t.Assembly;
                var types = AppDomain.CurrentDomain.GetAssemblies()
                    .SelectMany(s => s.GetTypes())
                    .Where(p => p.IsClass && t.IsAssignableFrom(p));

                foreach (var tt in types) {
                    var attribute = tt.GetCustomAttribute<ToolAttribute>();
                    if (tt.IsInterface || attribute == null) continue;

                    tools.Add(tt);
                }
            }
            return tools;
        }

        public 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;
            }
<commit_msg>datatool: support overriding Overwatch Directory via environment variable<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using DataTool.ConvertLogic;
using DataTool.Flag;
using DataTool.Helper;
using DataTool.SaveLogic;
using Microsoft.Win32;
using TankLib;
using TankLib.STU;
using TankLib.STU.Types;
using TankLib.TACT;
using TACTLib.Client;
using TACTLib.Client.HandlerArgs;
using TACTLib.Core.Product.Tank;
using TACTLib.Exceptions;
using TankLib.Helpers;
using static DataTool.Helper.Logger;
using static DataTool.Helper.STUHelper;
using Logger = TankLib.Helpers.Logger;
using static DataTool.Helper.SpellCheckUtils;

namespace DataTool {
    public static class Program {
        public static ClientHandler Client;
        public static ProductHandler_Tank TankHandler;
        public static Dictionary<ushort, HashSet<ulong>> TrackedFiles;

        public static ToolFlags Flags;
        public static uint BuildVersion;
        public static bool IsPTR => Client?.ProductCode == "prot";
        public static bool IsBeta => Client?.ProductCode == "prob";

        public static string[] ValidLanguages = {"deDE", "enUS", "esES", "esMX", "frFR", "itIT", "jaJP", "koKR", "plPL", "ptBR", "ruRU", "zhCN", "zhTW"};

        public static bool ValidKey(ulong key) {
            return TankHandler.m_assets.ContainsKey(key);
        }

        public static HashSet<Type> GetTools(bool noDebugTools = false) {
            var tools = new HashSet<Type>();
            {
                var t = typeof(ITool);
                var asm = t.Assembly;
                var types = AppDomain.CurrentDomain.GetAssemblies()
                    .SelectMany(s => s.GetTypes())
                    .Where(p => p.IsClass && t.IsAssignableFrom(p));

                foreach (var tt in types) {
                    var attribute = tt.GetCustomAttribute<ToolAttribute>();
                    if (tt.IsInterface || attribute == null) continue;

                    tools.Add(tt);
                }
            }
            return tools;
        }

        public 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;

            // Overrides the Overwatch Directory with the path set in the Environment variable.
            // Useful for debugging as you can use saved configurations without having to edit the directory saved in the arguments
            var overwatchDirectoryOverride = Environment.GetEnvironmentVariable("DATATOOL_OVERWATCH_DIR");
            if (!string.IsNullOrEmpty(overwatchDirectoryOverride)) {
                Flags.OverwatchDirectory = overwatchDirectoryOverride;
            }

            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;
            }

{'fraction_non_alphanumeric': 0.12132175590931017, 'fraction_numerical': 0.000482392667631452, 'mean_word_length': 2.3265142398716407, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5151996', 'n_tokens_mistral': 2309, 'n_tokens_neox': 2203, 'n_words': 519}