From 7025659151d515d5487a5253102afdcf28a44c1c Mon Sep 17 00:00:00 2001 From: JustArchi Date: Tue, 2 Aug 2016 06:04:44 +0200 Subject: [PATCH] Refactoring for upcoming GUI app --- ArchiSteamFarm/ASF.cs | 213 +++++++++++++++++ ArchiSteamFarm/ArchiSteamFarm.csproj | 1 + ArchiSteamFarm/Bot.cs | 24 +- ArchiSteamFarm/Logging.cs | 20 +- ArchiSteamFarm/Program.cs | 256 +++------------------ ArchiSteamFarm/Properties/AssemblyInfo.cs | 4 +- ArchiSteamFarm/SharedInfo.cs | 30 ++- ArchiSteamFarm/WCF.cs | 2 +- ArchiSteamFarm/WebBrowser.cs | 2 +- ConfigGenerator/ASFConfig.cs | 9 +- ConfigGenerator/MainForm.cs | 10 +- ConfigGenerator/Program.cs | 10 +- ConfigGenerator/Properties/AssemblyInfo.cs | 4 +- 13 files changed, 311 insertions(+), 274 deletions(-) create mode 100644 ArchiSteamFarm/ASF.cs diff --git a/ArchiSteamFarm/ASF.cs b/ArchiSteamFarm/ASF.cs new file mode 100644 index 000000000..ac0243d20 --- /dev/null +++ b/ArchiSteamFarm/ASF.cs @@ -0,0 +1,213 @@ +/* + _ _ _ ____ _ _____ + / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ + / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ + / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | +/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| + + Copyright 2015-2016 Łukasz "JustArchi" Domeradzki + Contact: JustArchi@JustArchi.net + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using ArchiSteamFarm.JSON; +using Newtonsoft.Json; + +namespace ArchiSteamFarm { + internal static class ASF { + private static Timer AutoUpdatesTimer; + + internal static async Task CheckForUpdate(bool updateOverride = false) { + string exeFile = Assembly.GetEntryAssembly().Location; + string oldExeFile = exeFile + ".old"; + + // We booted successfully so we can now remove old exe file + if (File.Exists(oldExeFile)) { + // It's entirely possible that old process is still running, allow at least a second before trying to remove the file + await Task.Delay(1000).ConfigureAwait(false); + + try { + File.Delete(oldExeFile); + } catch (Exception e) { + Logging.LogGenericException(e); + Logging.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!"); + } + } + + if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Unknown) { + return; + } + + if ((AutoUpdatesTimer == null) && Program.GlobalConfig.AutoUpdates) { + AutoUpdatesTimer = new Timer( + async e => await CheckForUpdate().ConfigureAwait(false), + null, + TimeSpan.FromDays(1), // Delay + TimeSpan.FromDays(1) // Period + ); + + Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours"); + } + + string releaseURL = SharedInfo.GithubReleaseURL; + if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) { + releaseURL += "/latest"; + } + + Logging.LogGenericInfo("Checking new version..."); + + string response = await Program.WebBrowser.UrlGetToContentRetry(releaseURL).ConfigureAwait(false); + if (string.IsNullOrEmpty(response)) { + Logging.LogGenericWarning("Could not check latest version!"); + return; + } + + GitHub.ReleaseResponse releaseResponse; + if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) { + try { + releaseResponse = JsonConvert.DeserializeObject(response); + } catch (JsonException e) { + Logging.LogGenericException(e); + return; + } + } else { + List releases; + try { + releases = JsonConvert.DeserializeObject>(response); + } catch (JsonException e) { + Logging.LogGenericException(e); + return; + } + + if ((releases == null) || (releases.Count == 0)) { + Logging.LogGenericWarning("Could not check latest version!"); + return; + } + + releaseResponse = releases[0]; + } + + if (string.IsNullOrEmpty(releaseResponse.Tag)) { + Logging.LogGenericWarning("Could not check latest version!"); + return; + } + + Version newVersion = new Version(releaseResponse.Tag); + + Logging.LogGenericInfo("Local version: " + SharedInfo.Version + " | Remote version: " + newVersion); + + if (SharedInfo.Version.CompareTo(newVersion) >= 0) { // If local version is the same or newer than remote version + return; + } + + if (!updateOverride && !Program.GlobalConfig.AutoUpdates) { + Logging.LogGenericInfo("New version is available!"); + Logging.LogGenericInfo("Consider updating yourself!"); + await Task.Delay(5000).ConfigureAwait(false); + return; + } + + if (File.Exists(oldExeFile)) { + Logging.LogGenericWarning("Refusing to proceed with auto update as old " + oldExeFile + " binary could not be removed, please remove it manually"); + return; + } + + // Auto update logic starts here + if (releaseResponse.Assets == null) { + Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!"); + return; + } + + string exeFileName = Path.GetFileName(exeFile); + GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(exeFileName, StringComparison.OrdinalIgnoreCase)); + + if (binaryAsset == null) { + Logging.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!"); + return; + } + + if (string.IsNullOrEmpty(binaryAsset.DownloadURL)) { + Logging.LogGenericWarning("Could not proceed with update because download URL is empty!"); + return; + } + + Logging.LogGenericInfo("Downloading new version..."); + Logging.LogGenericInfo("While waiting, consider donating if you appreciate the work being done :)"); + + byte[] result = await Program.WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false); + if (result == null) { + return; + } + + string newExeFile = exeFile + ".new"; + + // Firstly we create new exec + try { + File.WriteAllBytes(newExeFile, result); + } catch (Exception e) { + Logging.LogGenericException(e); + return; + } + + // Now we move current -> old + try { + File.Move(exeFile, oldExeFile); + } catch (Exception e) { + Logging.LogGenericException(e); + try { + // Cleanup + File.Delete(newExeFile); + } catch { + // Ignored + } + return; + } + + // Now we move new -> current + try { + File.Move(newExeFile, exeFile); + } catch (Exception e) { + Logging.LogGenericException(e); + try { + // Cleanup + File.Move(oldExeFile, exeFile); + File.Delete(newExeFile); + } catch { + // Ignored + } + return; + } + + Logging.LogGenericInfo("Update process finished!"); + + if (Program.GlobalConfig.AutoRestart) { + Logging.LogGenericInfo("Restarting..."); + await Task.Delay(5000).ConfigureAwait(false); + Program.Restart(); + } else { + Logging.LogGenericInfo("Exiting..."); + await Task.Delay(5000).ConfigureAwait(false); + Program.Exit(); + } + } + } +} diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 1f5f6e734..857a6ab7f 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -115,6 +115,7 @@ Component + diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 2d58b02be..3df52f89b 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -145,7 +145,7 @@ namespace ArchiSteamFarm { throw new Exception("That bot is already defined!"); } - string botPath = Path.Combine(Program.ConfigDirectory, botName); + string botPath = Path.Combine(SharedInfo.ConfigDirectory, botName); BotName = botName; SentryFile = botPath + ".bin"; @@ -184,10 +184,10 @@ namespace ArchiSteamFarm { // Initialize SteamClient = new SteamClient(Program.GlobalConfig.SteamProtocol); - if (Program.GlobalConfig.Debug && !Debugging.NetHookAlreadyInitialized && Directory.Exists(Program.DebugDirectory)) { + if (Program.GlobalConfig.Debug && !Debugging.NetHookAlreadyInitialized && Directory.Exists(SharedInfo.DebugDirectory)) { try { Debugging.NetHookAlreadyInitialized = true; - SteamClient.DebugNetworkListener = new NetHookNetworkListener(Program.DebugDirectory); + SteamClient.DebugNetworkListener = new NetHookNetworkListener(SharedInfo.DebugDirectory); } catch (Exception e) { Logging.LogGenericException(e, botName); } @@ -533,7 +533,7 @@ namespace ArchiSteamFarm { if (!BotDatabase.MobileAuthenticator.HasCorrectDeviceID) { Logging.LogGenericWarning("Your DeviceID is incorrect or doesn't exist", BotName); - string deviceID = Program.GetUserInput(Program.EUserInputType.DeviceID, BotName); + string deviceID = Program.GetUserInput(SharedInfo.EUserInputType.DeviceID, BotName); if (string.IsNullOrEmpty(deviceID)) { BotDatabase.MobileAuthenticator = null; return; @@ -1383,7 +1383,7 @@ namespace ArchiSteamFarm { return null; } - await Program.CheckForUpdate(true).ConfigureAwait(false); + await ASF.CheckForUpdate(true).ConfigureAwait(false); return "Done!"; } @@ -1397,7 +1397,7 @@ namespace ArchiSteamFarm { return null; } - return "ASF V" + Program.Version; + return "ASF V" + SharedInfo.Version; } private void HandleCallbacks() { @@ -1480,7 +1480,7 @@ namespace ArchiSteamFarm { private bool InitializeLoginAndPassword(bool requiresPassword) { if (string.IsNullOrEmpty(BotConfig.SteamLogin)) { - BotConfig.SteamLogin = Program.GetUserInput(Program.EUserInputType.Login, BotName); + BotConfig.SteamLogin = Program.GetUserInput(SharedInfo.EUserInputType.Login, BotName); if (string.IsNullOrEmpty(BotConfig.SteamLogin)) { return false; } @@ -1490,7 +1490,7 @@ namespace ArchiSteamFarm { return true; } - BotConfig.SteamPassword = Program.GetUserInput(Program.EUserInputType.Password, BotName); + BotConfig.SteamPassword = Program.GetUserInput(SharedInfo.EUserInputType.Password, BotName); return !string.IsNullOrEmpty(BotConfig.SteamPassword); } @@ -1810,7 +1810,7 @@ namespace ArchiSteamFarm { switch (callback.Result) { case EResult.AccountLogonDenied: - AuthCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName); + AuthCode = Program.GetUserInput(SharedInfo.EUserInputType.SteamGuard, BotName); if (string.IsNullOrEmpty(AuthCode)) { Stop(); } @@ -1818,7 +1818,7 @@ namespace ArchiSteamFarm { break; case EResult.AccountLoginDeniedNeedTwoFactor: if (BotDatabase.MobileAuthenticator == null) { - TwoFactorCode = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName); + TwoFactorCode = Program.GetUserInput(SharedInfo.EUserInputType.TwoFactorAuthentication, BotName); if (string.IsNullOrEmpty(TwoFactorCode)) { Stop(); } @@ -1842,14 +1842,14 @@ namespace ArchiSteamFarm { if (BotDatabase.MobileAuthenticator == null) { // Support and convert SDA files - string maFilePath = Path.Combine(Program.ConfigDirectory, callback.ClientSteamID.ConvertToUInt64() + ".maFile"); + string maFilePath = Path.Combine(SharedInfo.ConfigDirectory, callback.ClientSteamID.ConvertToUInt64() + ".maFile"); if (File.Exists(maFilePath)) { ImportAuthenticator(maFilePath); } } if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) { - BotConfig.SteamParentalPIN = Program.GetUserInput(Program.EUserInputType.SteamParentalPIN, BotName); + BotConfig.SteamParentalPIN = Program.GetUserInput(SharedInfo.EUserInputType.SteamParentalPIN, BotName); if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) { Stop(); return; diff --git a/ArchiSteamFarm/Logging.cs b/ArchiSteamFarm/Logging.cs index 941587000..5ab89a4c4 100644 --- a/ArchiSteamFarm/Logging.cs +++ b/ArchiSteamFarm/Logging.cs @@ -82,7 +82,7 @@ namespace ArchiSteamFarm { } else { FileTarget fileTarget = new FileTarget("File") { DeleteOldFileOnStartup = true, - FileName = Program.LogFile, + FileName = SharedInfo.LogFile, Layout = GeneralLayout }; @@ -122,7 +122,7 @@ namespace ArchiSteamFarm { LogManager.ReconfigExistingLoggers(); } - internal static void LogGenericError(string message, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogGenericError(string message, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (string.IsNullOrEmpty(message)) { LogNullError(nameof(message), botName); return; @@ -131,7 +131,7 @@ namespace ArchiSteamFarm { Logger.Error($"{botName}|{previousMethodName}() {message}"); } - internal static void LogGenericException(Exception exception, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogGenericException(Exception exception, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (exception == null) { LogNullError(nameof(exception), botName); return; @@ -140,7 +140,7 @@ namespace ArchiSteamFarm { Logger.Error(exception, $"{botName}|{previousMethodName}()"); } - internal static void LogFatalException(Exception exception, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogFatalException(Exception exception, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (exception == null) { LogNullError(nameof(exception), botName); return; @@ -154,10 +154,10 @@ namespace ArchiSteamFarm { } // Otherwise, if we run into fatal exception before logging module is even initialized, write exception to classic log file - File.WriteAllText(Program.LogFile, DateTime.Now + " ASF V" + Program.Version + " has run into fatal exception before core logging module was even able to initialize!" + Environment.NewLine); + File.WriteAllText(SharedInfo.LogFile, DateTime.Now + " ASF V" + SharedInfo.Version + " has run into fatal exception before core logging module was even able to initialize!" + Environment.NewLine); while (true) { - File.AppendAllText(Program.LogFile, "[!] EXCEPTION: " + previousMethodName + "() " + exception.Message + Environment.NewLine + "StackTrace:" + Environment.NewLine + exception.StackTrace); + File.AppendAllText(SharedInfo.LogFile, "[!] EXCEPTION: " + previousMethodName + "() " + exception.Message + Environment.NewLine + "StackTrace:" + Environment.NewLine + exception.StackTrace); if (exception.InnerException != null) { exception = exception.InnerException; continue; @@ -167,7 +167,7 @@ namespace ArchiSteamFarm { } } - internal static void LogGenericWarning(string message, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogGenericWarning(string message, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (string.IsNullOrEmpty(message)) { LogNullError(nameof(message), botName); return; @@ -176,7 +176,7 @@ namespace ArchiSteamFarm { Logger.Warn($"{botName}|{previousMethodName}() {message}"); } - internal static void LogGenericInfo(string message, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogGenericInfo(string message, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (string.IsNullOrEmpty(message)) { LogNullError(nameof(message), botName); return; @@ -186,7 +186,7 @@ namespace ArchiSteamFarm { } [SuppressMessage("ReSharper", "ExplicitCallerInfoArgument")] - internal static void LogNullError(string nullObjectName, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogNullError(string nullObjectName, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (string.IsNullOrEmpty(nullObjectName)) { return; } @@ -196,7 +196,7 @@ namespace ArchiSteamFarm { [Conditional("DEBUG")] [SuppressMessage("ReSharper", "UnusedMember.Global")] - internal static void LogGenericDebug(string message, string botName = Program.ASF, [CallerMemberName] string previousMethodName = null) { + internal static void LogGenericDebug(string message, string botName = SharedInfo.ASF, [CallerMemberName] string previousMethodName = null) { if (string.IsNullOrEmpty(message)) { LogNullError(nameof(message), botName); return; diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index d189961ce..1128c22df 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -22,7 +22,6 @@ */ -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -33,24 +32,9 @@ using System.Reflection; using System.ServiceProcess; using System.Threading; using System.Threading.Tasks; -using ArchiSteamFarm.JSON; namespace ArchiSteamFarm { internal static class Program { - internal enum EUserInputType : byte { - Unknown, - DeviceID, - Login, - Password, - PhoneNumber, - SMS, - SteamGuard, - SteamParentalPIN, - RevocationCode, - TwoFactorAuthentication, - WCFHostname - } - private enum EMode : byte { [SuppressMessage("ReSharper", "UnusedMember.Local")] Unknown, @@ -59,17 +43,6 @@ namespace ArchiSteamFarm { Server // Normal + WCF server } - internal const string ASF = "ASF"; - internal const string ConfigDirectory = "config"; - internal const string DebugDirectory = "debug"; - internal const string LogFile = "log.txt"; - - private const string GithubReleaseURL = "https://api.github.com/repos/" + SharedInfo.GithubRepo + "/releases"; // GitHub API is HTTPS only - private const string GlobalConfigFileName = ASF + ".json"; - private const string GlobalDatabaseFileName = ASF + ".db"; - - internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version; - private static readonly object ConsoleLock = new object(); private static readonly ManualResetEventSlim ShutdownResetEvent = new ManualResetEventSlim(false); private static readonly WCF WCF = new WCF(); @@ -77,185 +50,10 @@ namespace ArchiSteamFarm { internal static bool IsRunningAsService { get; private set; } internal static GlobalConfig GlobalConfig { get; private set; } internal static GlobalDatabase GlobalDatabase { get; private set; } + internal static WebBrowser WebBrowser { get; private set; } private static bool ShutdownSequenceInitialized; - private static Timer AutoUpdatesTimer; private static EMode Mode = EMode.Normal; - private static WebBrowser WebBrowser; - - internal static async Task CheckForUpdate(bool updateOverride = false) { - string exeFile = Assembly.GetEntryAssembly().Location; - string oldExeFile = exeFile + ".old"; - - // We booted successfully so we can now remove old exe file - if (File.Exists(oldExeFile)) { - // It's entirely possible that old process is still running, allow at least a second before trying to remove the file - await Task.Delay(1000).ConfigureAwait(false); - - try { - File.Delete(oldExeFile); - } catch (Exception e) { - Logging.LogGenericException(e); - Logging.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!"); - } - } - - if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Unknown) { - return; - } - - if ((AutoUpdatesTimer == null) && GlobalConfig.AutoUpdates) { - AutoUpdatesTimer = new Timer( - async e => await CheckForUpdate().ConfigureAwait(false), - null, - TimeSpan.FromDays(1), // Delay - TimeSpan.FromDays(1) // Period - ); - - Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours"); - } - - string releaseURL = GithubReleaseURL; - if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) { - releaseURL += "/latest"; - } - - Logging.LogGenericInfo("Checking new version..."); - - string response = await WebBrowser.UrlGetToContentRetry(releaseURL).ConfigureAwait(false); - if (string.IsNullOrEmpty(response)) { - Logging.LogGenericWarning("Could not check latest version!"); - return; - } - - GitHub.ReleaseResponse releaseResponse; - if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) { - try { - releaseResponse = JsonConvert.DeserializeObject(response); - } catch (JsonException e) { - Logging.LogGenericException(e); - return; - } - } else { - List releases; - try { - releases = JsonConvert.DeserializeObject>(response); - } catch (JsonException e) { - Logging.LogGenericException(e); - return; - } - - if ((releases == null) || (releases.Count == 0)) { - Logging.LogGenericWarning("Could not check latest version!"); - return; - } - - releaseResponse = releases[0]; - } - - if (string.IsNullOrEmpty(releaseResponse.Tag)) { - Logging.LogGenericWarning("Could not check latest version!"); - return; - } - - Version newVersion = new Version(releaseResponse.Tag); - - Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + newVersion); - - if (Version.CompareTo(newVersion) >= 0) { // If local version is the same or newer than remote version - return; - } - - if (!updateOverride && !GlobalConfig.AutoUpdates) { - Logging.LogGenericInfo("New version is available!"); - Logging.LogGenericInfo("Consider updating yourself!"); - await Task.Delay(5000).ConfigureAwait(false); - return; - } - - if (File.Exists(oldExeFile)) { - Logging.LogGenericWarning("Refusing to proceed with auto update as old " + oldExeFile + " binary could not be removed, please remove it manually"); - return; - } - - // Auto update logic starts here - if (releaseResponse.Assets == null) { - Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!"); - return; - } - - string exeFileName = Path.GetFileName(exeFile); - GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(exeFileName, StringComparison.OrdinalIgnoreCase)); - - if (binaryAsset == null) { - Logging.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!"); - return; - } - - if (string.IsNullOrEmpty(binaryAsset.DownloadURL)) { - Logging.LogGenericWarning("Could not proceed with update because download URL is empty!"); - return; - } - - Logging.LogGenericInfo("Downloading new version..."); - Logging.LogGenericInfo("While waiting, consider donating if you appreciate the work being done :)"); - - byte[] result = await WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false); - if (result == null) { - return; - } - - string newExeFile = exeFile + ".new"; - - // Firstly we create new exec - try { - File.WriteAllBytes(newExeFile, result); - } catch (Exception e) { - Logging.LogGenericException(e); - return; - } - - // Now we move current -> old - try { - File.Move(exeFile, oldExeFile); - } catch (Exception e) { - Logging.LogGenericException(e); - try { - // Cleanup - File.Delete(newExeFile); - } catch { - // Ignored - } - return; - } - - // Now we move new -> current - try { - File.Move(newExeFile, exeFile); - } catch (Exception e) { - Logging.LogGenericException(e); - try { - // Cleanup - File.Move(oldExeFile, exeFile); - File.Delete(newExeFile); - } catch { - // Ignored - } - return; - } - - Logging.LogGenericInfo("Update process finished!"); - - if (GlobalConfig.AutoRestart) { - Logging.LogGenericInfo("Restarting..."); - await Task.Delay(5000).ConfigureAwait(false); - Restart(); - } else { - Logging.LogGenericInfo("Exiting..."); - await Task.Delay(5000).ConfigureAwait(false); - Exit(); - } - } internal static void Exit(byte exitCode = 0) { Shutdown(); @@ -274,8 +72,8 @@ namespace ArchiSteamFarm { Environment.Exit(0); } - internal static string GetUserInput(EUserInputType userInputType, string botName = ASF, string extraInformation = null) { - if (userInputType == EUserInputType.Unknown) { + internal static string GetUserInput(SharedInfo.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) { + if (userInputType == SharedInfo.EUserInputType.Unknown) { return null; } @@ -288,35 +86,35 @@ namespace ArchiSteamFarm { lock (ConsoleLock) { Logging.OnUserInputStart(); switch (userInputType) { - case EUserInputType.DeviceID: + case SharedInfo.EUserInputType.DeviceID: Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): "); break; - case EUserInputType.Login: + case SharedInfo.EUserInputType.Login: Console.Write("<" + botName + "> Please enter your login: "); break; - case EUserInputType.Password: + case SharedInfo.EUserInputType.Password: Console.Write("<" + botName + "> Please enter your password: "); break; - case EUserInputType.PhoneNumber: + case SharedInfo.EUserInputType.PhoneNumber: Console.Write("<" + botName + "> Please enter your full phone number (e.g. +1234567890): "); break; - case EUserInputType.SMS: + case SharedInfo.EUserInputType.SMS: Console.Write("<" + botName + "> Please enter SMS code sent on your mobile: "); break; - case EUserInputType.SteamGuard: + case SharedInfo.EUserInputType.SteamGuard: Console.Write("<" + botName + "> Please enter the auth code sent to your email: "); break; - case EUserInputType.SteamParentalPIN: + case SharedInfo.EUserInputType.SteamParentalPIN: Console.Write("<" + botName + "> Please enter steam parental PIN: "); break; - case EUserInputType.RevocationCode: + case SharedInfo.EUserInputType.RevocationCode: Console.WriteLine("<" + botName + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation); Console.Write("<" + botName + "> Hit enter once ready..."); break; - case EUserInputType.TwoFactorAuthentication: + case SharedInfo.EUserInputType.TwoFactorAuthentication: Console.Write("<" + botName + "> Please enter your 2 factor auth code from your authenticator app: "); break; - case EUserInputType.WCFHostname: + case SharedInfo.EUserInputType.WCFHostname: Console.Write("<" + botName + "> Please enter your WCF hostname: "); break; default: @@ -378,7 +176,7 @@ namespace ArchiSteamFarm { } private static void InitServices() { - string globalConfigFile = Path.Combine(ConfigDirectory, GlobalConfigFileName); + string globalConfigFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName); GlobalConfig = GlobalConfig.Load(globalConfigFile); if (GlobalConfig == null) { @@ -387,7 +185,7 @@ namespace ArchiSteamFarm { Exit(1); } - string globalDatabaseFile = Path.Combine(ConfigDirectory, GlobalDatabaseFileName); + string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName); GlobalDatabase = GlobalDatabase.Load(globalDatabaseFile); if (GlobalDatabase == null) { @@ -400,7 +198,7 @@ namespace ArchiSteamFarm { WebBrowser.Init(); WCF.Init(); - WebBrowser = new WebBrowser(ASF); + WebBrowser = new WebBrowser(SharedInfo.ASF); } private static void ParsePreInitArgs(IEnumerable args) { @@ -486,7 +284,7 @@ namespace ArchiSteamFarm { TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler; Logging.InitCoreLoggers(); - Logging.LogGenericInfo("ASF V" + Version); + Logging.LogGenericInfo("ASF V" + SharedInfo.Version); if (!Runtime.IsRuntimeSupported()) { Logging.LogGenericError("ASF detected unsupported runtime version, program might NOT run correctly in current environment. You're running it at your own risk!"); @@ -503,13 +301,13 @@ namespace ArchiSteamFarm { // Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up for (byte i = 0; i < 4; i++) { Directory.SetCurrentDirectory(".."); - if (Directory.Exists(ConfigDirectory)) { + if (Directory.Exists(SharedInfo.ConfigDirectory)) { break; } } // If config directory doesn't exist after our adjustment, abort all of that - if (!Directory.Exists(ConfigDirectory)) { + if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Directory.SetCurrentDirectory(homeDirectory); } } @@ -524,13 +322,13 @@ namespace ArchiSteamFarm { // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { - if (Directory.Exists(DebugDirectory)) { - Directory.Delete(DebugDirectory, true); + if (Directory.Exists(SharedInfo.DebugDirectory)) { + Directory.Delete(SharedInfo.DebugDirectory, true); Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync } - Directory.CreateDirectory(DebugDirectory); + Directory.CreateDirectory(SharedInfo.DebugDirectory); - SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(DebugDirectory, "debug.txt"))); + SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(SharedInfo.DebugDirectory, "debug.txt"))); SteamKit2.DebugLog.Enabled = true; } @@ -547,22 +345,22 @@ namespace ArchiSteamFarm { // From now on it's server mode Logging.InitEnhancedLoggers(); - if (!Directory.Exists(ConfigDirectory)) { + if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Logging.LogGenericError("Config directory doesn't exist!"); Thread.Sleep(5000); Exit(1); } - CheckForUpdate().Wait(); + ASF.CheckForUpdate().Wait(); // Before attempting to connect, initialize our list of CMs Bot.InitializeCMs(GlobalDatabase.CellID, GlobalDatabase.ServerListProvider); bool isRunning = false; - foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) { + foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) { switch (botName) { - case ASF: + case SharedInfo.ASF: case "example": case "minimal": continue; diff --git a/ArchiSteamFarm/Properties/AssemblyInfo.cs b/ArchiSteamFarm/Properties/AssemblyInfo.cs index 47077a833..201de5b1d 100644 --- a/ArchiSteamFarm/Properties/AssemblyInfo.cs +++ b/ArchiSteamFarm/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using ArchiSteamFarm; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion(SharedInfo.Version)] -[assembly: AssemblyFileVersion(SharedInfo.Version)] +[assembly: AssemblyVersion(SharedInfo.VersionNumber)] +[assembly: AssemblyFileVersion(SharedInfo.VersionNumber)] diff --git a/ArchiSteamFarm/SharedInfo.cs b/ArchiSteamFarm/SharedInfo.cs index ff5afdc55..510e3aad5 100644 --- a/ArchiSteamFarm/SharedInfo.cs +++ b/ArchiSteamFarm/SharedInfo.cs @@ -22,9 +22,26 @@ */ +using System; +using System.Reflection; + namespace ArchiSteamFarm { internal static class SharedInfo { - internal const string Version = "2.1.3.8"; + internal enum EUserInputType : byte { + Unknown, + DeviceID, + Login, + Password, + PhoneNumber, + SMS, + SteamGuard, + SteamParentalPIN, + RevocationCode, + TwoFactorAuthentication, + WCFHostname + } + + internal const string VersionNumber = "2.1.3.8"; internal const string Copyright = "Copyright © ArchiSteamFarm 2015-2016"; internal const string GithubRepo = "JustArchi/ArchiSteamFarm"; @@ -34,5 +51,16 @@ namespace ArchiSteamFarm { internal const string EventLog = ServiceName; internal const string EventLogSource = EventLog + "Logger"; + + internal const string ASF = "ASF"; + internal const string ConfigDirectory = "config"; + internal const string DebugDirectory = "debug"; + internal const string LogFile = "log.txt"; + + internal const string GithubReleaseURL = "https://api.github.com/repos/" + GithubRepo + "/releases"; // GitHub API is HTTPS only + internal const string GlobalConfigFileName = ASF + ".json"; + internal const string GlobalDatabaseFileName = ASF + ".db"; + + internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version; } } diff --git a/ArchiSteamFarm/WCF.cs b/ArchiSteamFarm/WCF.cs index 5900e3500..73c7e7986 100644 --- a/ArchiSteamFarm/WCF.cs +++ b/ArchiSteamFarm/WCF.cs @@ -47,7 +47,7 @@ namespace ArchiSteamFarm { internal static void Init() { if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) { - Program.GlobalConfig.WCFHostname = Program.GetUserInput(Program.EUserInputType.WCFHostname); + Program.GlobalConfig.WCFHostname = Program.GetUserInput(SharedInfo.EUserInputType.WCFHostname); if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) { return; } diff --git a/ArchiSteamFarm/WebBrowser.cs b/ArchiSteamFarm/WebBrowser.cs index 325e7104a..788e8f639 100644 --- a/ArchiSteamFarm/WebBrowser.cs +++ b/ArchiSteamFarm/WebBrowser.cs @@ -87,7 +87,7 @@ namespace ArchiSteamFarm { }; // Most web services expect that UserAgent is set, so we declare it globally - HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd("ArchiSteamFarm/" + Program.Version); + HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd("ArchiSteamFarm/" + SharedInfo.Version); } internal async Task UrlHeadRetry(string request, string referer = null) { diff --git a/ConfigGenerator/ASFConfig.cs b/ConfigGenerator/ASFConfig.cs index 9d262ddc1..76198336e 100644 --- a/ConfigGenerator/ASFConfig.cs +++ b/ConfigGenerator/ASFConfig.cs @@ -26,6 +26,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; +using ArchiSteamFarm; namespace ConfigGenerator { internal abstract class ASFConfig { @@ -60,7 +61,7 @@ namespace ConfigGenerator { internal void Remove() { string queryPath = Path.GetFileNameWithoutExtension(FilePath); lock (FileLock) { - foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) { + foreach (string botFile in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, queryPath + ".*")) { try { File.Delete(botFile); } catch (Exception e) { @@ -80,15 +81,15 @@ namespace ConfigGenerator { string queryPath = Path.GetFileNameWithoutExtension(FilePath); lock (FileLock) { - foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) { + foreach (string botFile in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, queryPath + ".*")) { try { - File.Move(botFile, Path.Combine(Program.ConfigDirectory, botName + Path.GetExtension(botFile))); + File.Move(botFile, Path.Combine(SharedInfo.ConfigDirectory, botName + Path.GetExtension(botFile))); } catch (Exception e) { Logging.LogGenericException(e); } } - FilePath = Path.Combine(Program.ConfigDirectory, botName + ".json"); + FilePath = Path.Combine(SharedInfo.ConfigDirectory, botName + ".json"); } } } diff --git a/ConfigGenerator/MainForm.cs b/ConfigGenerator/MainForm.cs index 4401d8aac..980f1d64b 100644 --- a/ConfigGenerator/MainForm.cs +++ b/ConfigGenerator/MainForm.cs @@ -52,14 +52,14 @@ namespace ConfigGenerator { return; } - ASFTab = new ConfigPage(GlobalConfig.Load(Path.Combine(Program.ConfigDirectory, Program.GlobalConfigFile))); + ASFTab = new ConfigPage(GlobalConfig.Load(Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName))); MainTab.TabPages.Add(ASFTab); - foreach (string configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) { + foreach (string configFile in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json")) { string botName = Path.GetFileNameWithoutExtension(configFile); switch (botName) { - case Program.ASF: + case SharedInfo.ASF: case "example": case "minimal": continue; @@ -161,7 +161,7 @@ namespace ConfigGenerator { } switch (input) { - case Program.ASF: + case SharedInfo.ASF: case "example": case "minimal": Logging.LogGenericErrorWithoutStacktrace("This name is reserved!"); @@ -173,7 +173,7 @@ namespace ConfigGenerator { return; } - input = Path.Combine(Program.ConfigDirectory, input + ".json"); + input = Path.Combine(SharedInfo.ConfigDirectory, input + ".json"); ConfigPage newConfigPage = new ConfigPage(BotConfig.Load(input)); MainTab.TabPages.Insert(MainTab.TabPages.Count - ReservedTabs, newConfigPage); diff --git a/ConfigGenerator/Program.cs b/ConfigGenerator/Program.cs index 9b3fe55df..9b4a37894 100644 --- a/ConfigGenerator/Program.cs +++ b/ConfigGenerator/Program.cs @@ -32,12 +32,8 @@ using ArchiSteamFarm; namespace ConfigGenerator { internal static class Program { - internal const string ASF = "ASF"; - internal const string ConfigDirectory = "config"; - internal const string GlobalConfigFile = ASF + ".json"; - private const string ASFDirectory = "ArchiSteamFarm"; - private const string ASFExecutableFile = ASF + ".exe"; + private const string ASFExecutableFile = SharedInfo.ASF + ".exe"; /// /// The main entry point for the application. @@ -73,13 +69,13 @@ namespace ConfigGenerator { } // If config directory doesn't exist after our adjustment, abort all of that - if (!Directory.Exists(ConfigDirectory)) { + if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Directory.SetCurrentDirectory(homeDirectory); } } } - if (!Directory.Exists(ConfigDirectory)) { + if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Logging.LogGenericErrorWithoutStacktrace("Config directory could not be found!"); Environment.Exit(1); } diff --git a/ConfigGenerator/Properties/AssemblyInfo.cs b/ConfigGenerator/Properties/AssemblyInfo.cs index 625f83e9e..af8ea2e46 100644 --- a/ConfigGenerator/Properties/AssemblyInfo.cs +++ b/ConfigGenerator/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using ArchiSteamFarm; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion(SharedInfo.Version)] -[assembly: AssemblyFileVersion(SharedInfo.Version)] +[assembly: AssemblyVersion(SharedInfo.VersionNumber)] +[assembly: AssemblyFileVersion(SharedInfo.VersionNumber)]