public void installGame(int id, string folder, bool validate = false)
        {
            if (instance.LoginState)
            {
                instance.requestAppLicense(id);

                instance.AppUpdateStateChanged += (sender, updateArgs) =>
                {
                    AppUpdateStateChanged?.Invoke(sender, updateArgs);
                };
                instance.AppUpdated += (sender, e) =>
                {
                    AppUpdated?.Invoke(sender, e);
                };

                instance.updateApp(id, folder, validate);
            }
            else
            {
                throw new LoginRequiredException();
            }
        }
        private void Steam_DataReceived(object sender, string e)
        {
            if (string.IsNullOrEmpty(e))
            {
                return;
            }
            string line = e;

            Console.WriteLine(e);

            SteamOutput?.Invoke(this, line);

            if (line.Equals("Loading Steam API...OK."))
            {
                waitStartAsync.Set();
                //SteamExited?.Invoke(this, SteamExitReason.NonEnglishCharachers);
            }
            else if (line.Contains("cannot run from a folder path that includes non-English characters"))
            {
                close(SteamExitReason.NonEnglishCharachers);
            }
            else if (line.Equals("FAILED with result code 5") | line.Equals("Login with cached credentials FAILED with result code 5"))
            {
                LoginCallback?.Invoke(this, LoginResult.WrongInformation);
            }
            else if (line.Equals("FAILED with result code 88"))
            {
                LoginCallback?.Invoke(this, LoginResult.SteamGuardCodeWrong);
            }
            else if (line.Equals("FAILED with result code 65"))
            {
                LoginCallback?.Invoke(this, LoginResult.SteamGuardCodeWrong);
            }
            else if (line.Equals("FAILED with result code 71"))
            {
                LoginCallback?.Invoke(this, LoginResult.ExpiredCode);
            }
            else if (line.Equals("FAILED with result code 84"))
            {
                LoginCallback?.Invoke(this, LoginResult.RateLimitedExceeded);
            }
            else if (line.Contains("using 'set_steam_guard_code'"))
            {
                LoginCallback?.Invoke(this, LoginResult.SteamGuardNotSupported);
            }
            else if (line.Contains("Enter the current code from your Steam Guard Mobile Authenticator app"))
            {
                LoginCallback?.Invoke(this, LoginResult.WaitingForSteamGuard);
            }
            else if (line.Contains("FAILED with result code 50"))
            {
                LoginCallback?.Invoke(this, LoginResult.AlreadyLoggedIn);
            }
            else if (LoginState == false & (line.Contains("Waiting for license info...OK") | line.Contains("Logged in OK")))
            {
                LoginState = true;
                LoginCallback?.Invoke(this, LoginResult.OK);
            }
            else if (Regex.IsMatch(line, "ERROR! Download item [0-9]+ failed (Access Denied)."))
            {
                ModDownloaded?.Invoke(this, null);
            }
            else if (Regex.IsMatch(line, "Error! App '[0-9]+' state is 0x[0-9]+ after update job."))
            {
                AppUpdated?.Invoke(true);
            }
            else if (Regex.IsMatch(line, @"Update state \(0x5\) validating, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)"))
            {
                Regex pattern = new Regex(@"Update state \(0x5\) validating, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)");
                Match match   = pattern.Match(line);


                SteamAppUpdateState state = new SteamAppUpdateState();
                state.percentage    = Convert.ToInt32(match.Groups[1].Value);
                state.receivedBytes = Convert.ToInt64(match.Groups[3].Value);
                state.totalBytes    = Convert.ToInt64(match.Groups[4].Value);
                state.stage         = UpdateStateStage.Validating;

                AppUpdateStateChanged?.Invoke(this, state);
            }
            else if (Regex.IsMatch(line, @"Update state \(0x61\) downloading, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)"))
            {
                Regex pattern = new Regex(@"Update state \(0x61\) downloading, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)");
                Match match   = pattern.Match(line);


                SteamAppUpdateState state = new SteamAppUpdateState();
                state.percentage    = Convert.ToInt32(match.Groups[1].Value);
                state.receivedBytes = Convert.ToInt64(match.Groups[3].Value);
                state.totalBytes    = Convert.ToInt64(match.Groups[4].Value);
                state.stage         = UpdateStateStage.Downloading;

                AppUpdateStateChanged?.Invoke(this, state);
            }
            else if (Regex.IsMatch(line, @"Update state \(0x81\) commiting, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)"))
            {
                Regex pattern = new Regex(@"Update state \(0x81\) commiting, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)");
                Match match   = pattern.Match(line);


                SteamAppUpdateState state = new SteamAppUpdateState();
                state.percentage    = Convert.ToInt32(match.Groups[1].Value);
                state.receivedBytes = Convert.ToInt64(match.Groups[3].Value);
                state.totalBytes    = Convert.ToInt64(match.Groups[4].Value);
                state.stage         = UpdateStateStage.Commiting;

                AppUpdateStateChanged?.Invoke(this, state);
            }
            else if (Regex.IsMatch(line, @"Update state \(0x11\) preallocating, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)"))
            {
                Regex pattern = new Regex(@"Update state \(0x11\) preallocating, progress: ([0-9]+)\.([0-9]+) \(([0-9]+) / ([0-9]+)\)");
                Match match   = pattern.Match(line);


                SteamAppUpdateState state = new SteamAppUpdateState();
                state.percentage    = Convert.ToInt32(match.Groups[1].Value);
                state.receivedBytes = Convert.ToInt64(match.Groups[3].Value);
                state.totalBytes    = Convert.ToInt64(match.Groups[4].Value);
                state.stage         = UpdateStateStage.Preallocating;
                AppUpdateStateChanged?.Invoke(this, state);
            }
            else if (line.Contains("Success! App '") & line.Contains("' fully installed."))
            {
                AppUpdated?.Invoke(this);
            }
            else if (line.Contains("Success! App '") & line.Contains("' already up to date."))
            {
                AppUpdated?.Invoke(this);
            }
            else if (line.Contains("Success. Downloaded item") & line.Contains("bytes"))
            {
                ModDownloaded?.Invoke(this, line.Split('"')[1]);
            }
        }