private static async Task InitASF(IReadOnlyCollection <string>?args) { OS.CoreInit(); Console.Title = SharedInfo.ProgramIdentifier; ASF.ArchiLogger.LogGenericInfo(SharedInfo.ProgramIdentifier); if (!await InitGlobalConfigAndLanguage().ConfigureAwait(false)) { return; } if (ASF.GlobalConfig == null) { throw new ArgumentNullException(nameof(ASF.GlobalConfig)); } // Parse post-init args if (args != null) { ParsePostInitArgs(args); } OS.Init(SystemRequired, ASF.GlobalConfig.OptimizationMode); await InitGlobalDatabaseAndServices().ConfigureAwait(false); await ASF.Init().ConfigureAwait(false); }
private static async Task InitGlobalDatabaseAndServices() { string globalDatabaseFile = ASF.GetFilePath(ASF.EFileType.Database); if (string.IsNullOrEmpty(globalDatabaseFile)) { ASF.ArchiLogger.LogNullError(nameof(globalDatabaseFile)); return; } if (!File.Exists(globalDatabaseFile)) { ASF.ArchiLogger.LogGenericInfo(Strings.Welcome); await Task.Delay(10 * 1000).ConfigureAwait(false); ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy); await Task.Delay(5 * 1000).ConfigureAwait(false); } GlobalDatabase globalDatabase = await GlobalDatabase.CreateOrLoad(globalDatabaseFile).ConfigureAwait(false); if (globalDatabase == null) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile)); await Task.Delay(5 * 1000).ConfigureAwait(false); await Exit(1).ConfigureAwait(false); return; } ASF.InitGlobalDatabase(globalDatabase); // If debugging is on, we prepare debug directory prior to running if (Debugging.IsUserDebugging) { ASF.ArchiLogger.LogGenericDebug(globalDatabaseFile + ": " + JsonConvert.SerializeObject(ASF.GlobalDatabase, Formatting.Indented)); Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } WebBrowser.Init(); }
private async void MainForm_Load(object sender, EventArgs e) { Logging.InitFormLogger(); BotListView.LargeImageList = BotListView.SmallImageList = AvatarImageList; await Task.Run(async() => { Program.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Program.ArchiLogger.LogGenericError("Config directory could not be found!"); Environment.Exit(1); } await ASF.CheckForUpdate().ConfigureAwait(false); // Before attempting to connect, initialize our list of CMs await Bot.InitializeCMs(Program.GlobalDatabase.CellID, Program.GlobalDatabase.ServerListProvider).ConfigureAwait(false); }); foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) { switch (botName) { case SharedInfo.ASF: case "example": case "minimal": continue; } Bot bot = new Bot(botName); BotStatusForm botStatusForm = new BotStatusForm(bot); BotIndexes[botName] = AvatarImageList.Images.Count; AvatarImageList.Images.Add(botName, botStatusForm.AvatarPictureBox.Image); botStatusForm.TopLevel = false; BotStatusPanel.Controls.Add(botStatusForm); ListViewItem botListViewItem = new ListViewItem { ImageIndex = BotIndexes[botName], Text = botName }; BotListView.Items.Add(botListViewItem); } if (BotListView.Items.Count > 0) { BotListView.Items[0].Selected = true; BotListView.Select(); } }
private static async Task InitASF(string[] args) { ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); await InitGlobalConfigAndLanguage().ConfigureAwait(false); if (!Runtime.IsRuntimeSupported) { ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported); await Task.Delay(60 * 1000).ConfigureAwait(false); } await InitGlobalDatabaseAndServices().ConfigureAwait(false); // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } // Parse post-init args if (args != null) { await ParsePostInitArgs(args).ConfigureAwait(false); } // If we ran ASF as a client, we're done by now if (Mode.HasFlag(EMode.Client) && !Mode.HasFlag(EMode.Server)) { await Exit().ConfigureAwait(false); } await ASF.CheckForUpdate().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitEvents(); }
private static async Task ParsePostInitArgs(IEnumerable <string> args) { if (args == null) { ASF.ArchiLogger.LogNullError(nameof(args)); return; } foreach (string arg in args) { switch (arg) { case "": break; case "--client": Mode |= EMode.Client; break; case "--server": Mode |= EMode.Server; WCF.StartServer(); await ASF.InitBots().ConfigureAwait(false); break; default: if (arg.StartsWith("--", StringComparison.Ordinal)) { if (arg.StartsWith("--cryptkey=", StringComparison.Ordinal) && (arg.Length > 11)) { CryptoHelper.SetEncryptionKey(arg.Substring(11)); } break; } if (!Mode.HasFlag(EMode.Client)) { ASF.ArchiLogger.LogGenericWarning(string.Format(Strings.WarningWCFIgnoringCommand, arg)); break; } string response = WCF.SendCommand(arg); ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFResponseReceived, response)); break; } } }
private static void ParsePostInitArgs(IEnumerable <string> args) { if (args == null) { ASF.ArchiLogger.LogNullError(nameof(args)); return; } foreach (string arg in args) { switch (arg) { case "": break; case "--client": Mode |= EMode.Client; break; case "--server": Mode |= EMode.Server; WCF.StartServer(); ASF.InitBots(); break; default: if (arg.StartsWith("--", StringComparison.Ordinal)) { if (arg.StartsWith("--cryptkey=", StringComparison.Ordinal) && (arg.Length > 11)) { CryptoHelper.SetEncryptionKey(arg.Substring(11)); } break; } if (!Mode.HasFlag(EMode.Client)) { ASF.ArchiLogger.LogGenericWarning("Ignoring command because --client wasn't specified: " + arg); break; } ASF.ArchiLogger.LogGenericInfo("Command sent: " + arg); ASF.ArchiLogger.LogGenericInfo("Response received: " + WCF.SendCommand(arg)); break; } } }
private static async Task InitASF(IReadOnlyCollection <string> args) { ASF.ArchiLogger.LogGenericInfo(SharedInfo.PublicIdentifier + " V" + SharedInfo.Version + " (" + SharedInfo.BuildInfo.Variant + "/" + SharedInfo.ModuleVersion + " | " + OS.Variant + ")"); await InitGlobalConfigAndLanguage().ConfigureAwait(false); // Parse post-init args if (args != null) { ParsePostInitArgs(args); } OS.Init(SystemRequired, GlobalConfig.OptimizationMode); await InitGlobalDatabaseAndServices().ConfigureAwait(false); await ASF.Init().ConfigureAwait(false); }
private static async Task InitASF(string[] args) { ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version + " (" + SharedInfo.ModuleVersion + ")"); await InitGlobalConfigAndLanguage().ConfigureAwait(false); await InitGlobalDatabaseAndServices().ConfigureAwait(false); // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } // Parse post-init args if (args != null) { ParsePostInitArgs(args); } await ASF.CheckForUpdate().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitEvents(); }
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) => null; // TODO internal static async Task InitASF() { ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); await InitGlobalConfigAndLanguage().ConfigureAwait(false); if (!Runtime.IsRuntimeSupported) { ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported); await Task.Delay(60 * 1000).ConfigureAwait(false); } await InitGlobalDatabaseAndServices().ConfigureAwait(false); // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } await ASF.CheckForUpdate().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitEvents(); }
private static async Task InitASF(IReadOnlyCollection <string> args) { ASF.ArchiLogger.LogGenericInfo(SharedInfo.PublicIdentifier + " V" + SharedInfo.Version + " (" + SharedInfo.ModuleVersion + ")"); await InitGlobalConfigAndLanguage().ConfigureAwait(false); // Parse post-init args if (args != null) { ParsePostInitArgs(args); } OS.Init(SystemRequired); await InitGlobalDatabaseAndServices().ConfigureAwait(false); await ASF.CheckAndUpdateProgram().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitEvents(); }
internal async Task OnNewConfigLoaded(ASF.BotConfigEventArgs args) { if (args == null) { Logging.LogNullError(nameof(args), BotName); return; } if (args.BotConfig == null) { Destroy(); return; } if (args.BotConfig == BotConfig) { return; } try { if (args.BotConfig == BotConfig) { return; } Stop(); BotConfig = args.BotConfig; CardsFarmer.Paused = BotConfig.Paused; if (BotConfig.AcceptConfirmationsPeriod > 0) { TimeSpan delay = TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod) + TimeSpan.FromMinutes(0.2 * Bots.Count); TimeSpan period = TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod); if (AcceptConfirmationsTimer == null) { AcceptConfirmationsTimer = new Timer( async e => await AcceptConfirmations(true).ConfigureAwait(false), null, delay, // Delay period // Period ); } else { AcceptConfirmationsTimer.Change(delay, period); } } else { AcceptConfirmationsTimer?.Change(Timeout.Infinite, Timeout.Infinite); AcceptConfirmationsTimer?.Dispose(); } if ((BotConfig.SendTradePeriod > 0) && (BotConfig.SteamMasterID != 0)) { TimeSpan delay = TimeSpan.FromHours(BotConfig.SendTradePeriod) + TimeSpan.FromMinutes(Bots.Count); TimeSpan period = TimeSpan.FromHours(BotConfig.SendTradePeriod); if (SendItemsTimer == null) { SendItemsTimer = new Timer( async e => await ResponseLoot(BotConfig.SteamMasterID).ConfigureAwait(false), null, delay, // Delay period // Period ); } else { SendItemsTimer.Change(delay, period); } } else { SendItemsTimer?.Change(Timeout.Infinite, Timeout.Infinite); SendItemsTimer?.Dispose(); } await Initialize().ConfigureAwait(false); } finally { InitializationSemaphore.Release(); } }
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) { if (userInputType == ASF.EUserInputType.Unknown) { return null; } if (GlobalConfig.Headless || !Runtime.IsUserInteractive) { ASF.ArchiLogger.LogGenericWarning("Received a request for user input, but process is running in headless mode!"); return null; } string result; lock (ConsoleLock) { Logging.OnUserInputStart(); switch (userInputType) { case ASF.EUserInputType.DeviceID: Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): "); break; case ASF.EUserInputType.Login: Console.Write("<" + botName + "> Please enter your login: "******"<" + botName + "> Please enter your password: "******"<" + botName + "> Please enter your full phone number (e.g. +1234567890): "); break; case ASF.EUserInputType.SMS: Console.Write("<" + botName + "> Please enter SMS code sent on your mobile: "); break; case ASF.EUserInputType.SteamGuard: Console.Write("<" + botName + "> Please enter the auth code sent to your email: "); break; case ASF.EUserInputType.SteamParentalPIN: Console.Write("<" + botName + "> Please enter steam parental PIN: "); break; case ASF.EUserInputType.RevocationCode: Console.WriteLine("<" + botName + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation); Console.Write("<" + botName + "> Hit enter once ready..."); break; case ASF.EUserInputType.TwoFactorAuthentication: Console.Write("<" + botName + "> Please enter your 2 factor auth code from your authenticator app: "); break; case ASF.EUserInputType.WCFHostname: Console.Write("<" + botName + "> Please enter your WCF host: "); break; default: Console.Write("<" + botName + "> Please enter not documented yet value of \"" + userInputType + "\": "); break; } result = Console.ReadLine(); if (!Console.IsOutputRedirected) { Console.Clear(); // For security purposes } Logging.OnUserInputEnd(); } return !string.IsNullOrEmpty(result) ? result.Trim() : null; }
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) { return null; // TODO }
private static async Task InitGlobalConfigAndLanguage() { string globalConfigFile = ASF.GetFilePath(ASF.EFileType.Config); if (string.IsNullOrEmpty(globalConfigFile)) { ASF.ArchiLogger.LogNullError(nameof(globalConfigFile)); return; } GlobalConfig globalConfig; if (File.Exists(globalConfigFile)) { globalConfig = await GlobalConfig.Load(globalConfigFile).ConfigureAwait(false); if (globalConfig == null) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalConfigNotLoaded, globalConfigFile)); await Task.Delay(5 * 1000).ConfigureAwait(false); await Exit(1).ConfigureAwait(false); return; } } else { globalConfig = GlobalConfig.Create(); } ASF.InitGlobalConfig(globalConfig); if (Debugging.IsUserDebugging) { ASF.ArchiLogger.LogGenericDebug(globalConfigFile + ": " + JsonConvert.SerializeObject(ASF.GlobalConfig, Formatting.Indented)); } if (!string.IsNullOrEmpty(ASF.GlobalConfig.CurrentCulture)) { try { // GetCultureInfo() would be better but we can't use it for specifying neutral cultures such as "en" CultureInfo culture = CultureInfo.CreateSpecificCulture(ASF.GlobalConfig.CurrentCulture); CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = culture; } catch (Exception) { ASF.ArchiLogger.LogGenericError(Strings.ErrorInvalidCurrentCulture); } } if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("en")) { return; } ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true); if (defaultResourceSet == null) { ASF.ArchiLogger.LogNullError(nameof(defaultResourceSet)); return; } HashSet <DictionaryEntry> defaultStringObjects = defaultResourceSet.Cast <DictionaryEntry>().ToHashSet(); if (defaultStringObjects.Count == 0) { ASF.ArchiLogger.LogNullError(nameof(defaultStringObjects)); return; } ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true); if (currentResourceSet == null) { ASF.ArchiLogger.LogNullError(nameof(currentResourceSet)); return; } HashSet <DictionaryEntry> currentStringObjects = currentResourceSet.Cast <DictionaryEntry>().ToHashSet(); if (currentStringObjects.Count >= defaultStringObjects.Count) { // Either we have 100% finished translation, or we're missing it entirely and using en-US HashSet <DictionaryEntry> testStringObjects = currentStringObjects.ToHashSet(); testStringObjects.ExceptWith(defaultStringObjects); // If we got 0 as final result, this is the missing language // Otherwise it's just a small amount of strings that happen to be the same if (testStringObjects.Count == 0) { currentStringObjects = testStringObjects; } } if (currentStringObjects.Count < defaultStringObjects.Count) { float translationCompleteness = currentStringObjects.Count / (float)defaultStringObjects.Count; ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentUICulture.Name, translationCompleteness.ToString("P1"))); } }
private static async Task <bool> InitGlobalConfigAndLanguage() { string globalConfigFile = ASF.GetFilePath(ASF.EFileType.Config); if (string.IsNullOrEmpty(globalConfigFile)) { throw new ArgumentNullException(nameof(globalConfigFile)); } GlobalConfig?globalConfig; if (File.Exists(globalConfigFile)) { globalConfig = await GlobalConfig.Load(globalConfigFile).ConfigureAwait(false); if (globalConfig == null) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalConfigNotLoaded, globalConfigFile)); await Task.Delay(5 * 1000).ConfigureAwait(false); await Exit(1).ConfigureAwait(false); return(false); } } else { globalConfig = new GlobalConfig(); } ASF.InitGlobalConfig(globalConfig); if (Debugging.IsDebugConfigured) { ASF.ArchiLogger.LogGenericDebug(globalConfigFile + ": " + JsonConvert.SerializeObject(ASF.GlobalConfig, Formatting.Indented)); } if (!string.IsNullOrEmpty(ASF.GlobalConfig?.CurrentCulture)) { try { // GetCultureInfo() would be better but we can't use it for specifying neutral cultures such as "en" CultureInfo culture = CultureInfo.CreateSpecificCulture(ASF.GlobalConfig !.CurrentCulture !); CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = culture; } catch (Exception e) { ASF.ArchiLogger.LogGenericWarningException(e); ASF.ArchiLogger.LogGenericError(Strings.ErrorInvalidCurrentCulture); } } // Skip translation progress for English and invariant (such as "C") cultures switch (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName) { case "en": case "iv": return(true); } // We can't dispose this resource set, as we can't be sure if it isn't used somewhere else, rely on GC in this case ResourceSet?defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true); if (defaultResourceSet == null) { ASF.ArchiLogger.LogNullError(nameof(defaultResourceSet)); return(true); } HashSet <DictionaryEntry> defaultStringObjects = defaultResourceSet.Cast <DictionaryEntry>().ToHashSet(); if (defaultStringObjects.Count == 0) { ASF.ArchiLogger.LogNullError(nameof(defaultStringObjects)); return(true); } // We can't dispose this resource set, as we can't be sure if it isn't used somewhere else, rely on GC in this case ResourceSet?currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true); if (currentResourceSet == null) { ASF.ArchiLogger.LogNullError(nameof(currentResourceSet)); return(true); } HashSet <DictionaryEntry> currentStringObjects = currentResourceSet.Cast <DictionaryEntry>().ToHashSet(); if (currentStringObjects.Count >= defaultStringObjects.Count) { // Either we have 100% finished translation, or we're missing it entirely and using en-US HashSet <DictionaryEntry> testStringObjects = currentStringObjects.ToHashSet(); testStringObjects.ExceptWith(defaultStringObjects); // If we got 0 as final result, this is the missing language // Otherwise it's just a small amount of strings that happen to be the same if (testStringObjects.Count == 0) { currentStringObjects = testStringObjects; } } if (currentStringObjects.Count < defaultStringObjects.Count) { float translationCompleteness = currentStringObjects.Count / (float)defaultStringObjects.Count; ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentUICulture.Name, translationCompleteness.ToString("P1"))); } return(true); }
private static void Init(string[] args) { AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler; TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler; string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); if (!string.IsNullOrEmpty(homeDirectory)) { Directory.SetCurrentDirectory(homeDirectory); // Allow loading configs from source tree if it's a debug build if (Debugging.IsDebugBuild) { // 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(SharedInfo.ConfigDirectory)) { break; } } // If config directory doesn't exist after our adjustment, abort all of that if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Directory.SetCurrentDirectory(homeDirectory); } } } // Parse pre-init args if (args != null) { ParsePreInitArgs(args); } Logging.InitLoggers(); ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); if (!Runtime.IsRuntimeSupported) { ASF.ArchiLogger.LogGenericError("ASF detected unsupported runtime version, program might NOT run correctly in current environment. You're running it at your own risk!"); Thread.Sleep(10000); } InitServices(); // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { if (Directory.Exists(SharedInfo.DebugDirectory)) { Directory.Delete(SharedInfo.DebugDirectory, true); Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync } Directory.CreateDirectory(SharedInfo.DebugDirectory); SteamKit2.DebugLog.AddListener(new Debugging.DebugListener()); SteamKit2.DebugLog.Enabled = true; } // Parse post-init args if (args != null) { ParsePostInitArgs(args); } // If we ran ASF as a client, we're done by now if (Mode == EMode.Client) { Exit(); } // From now on it's server mode if (!Directory.Exists(SharedInfo.ConfigDirectory)) { ASF.ArchiLogger.LogGenericError("Config directory doesn't exist!"); Thread.Sleep(5000); Exit(1); } ASF.CheckForUpdate().Wait(); // Before attempting to connect, initialize our list of CMs Bot.InitializeCMs(GlobalDatabase.CellID, GlobalDatabase.ServerListProvider); foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) { switch (botName) { case SharedInfo.ASF: case "example": case "minimal": continue; } new Bot(botName).Forget(); } if (Bot.Bots.Count == 0) { ASF.ArchiLogger.LogGenericWarning("No bots are defined, did you forget to configure your ASF?"); } ASF.InitFileWatcher(); }
private static async Task InitCore(string[] args) { AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler; TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler; string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); if (!string.IsNullOrEmpty(homeDirectory)) { Directory.SetCurrentDirectory(homeDirectory); // Allow loading configs from source tree if it's a debug build if (Debugging.IsDebugBuild) { // 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(SharedInfo.ConfigDirectory)) { break; } } // If config directory doesn't exist after our adjustment, abort all of that if (!Directory.Exists(SharedInfo.ConfigDirectory)) { Directory.SetCurrentDirectory(homeDirectory); } } } // Parse pre-init args if (args != null) { ParsePreInitArgs(args); } Logging.InitLoggers(); ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); await InitServices().ConfigureAwait(false); if (!Runtime.IsRuntimeSupported) { ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported); await Task.Delay(10 * 1000).ConfigureAwait(false); } // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } // Parse post-init args if (args != null) { await ParsePostInitArgs(args).ConfigureAwait(false); } // If we ran ASF as a client, we're done by now if (Mode.HasFlag(EMode.Client) && !Mode.HasFlag(EMode.Server)) { Exit(); } await ASF.CheckForUpdate().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitFileWatcher(); }