diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 6dd99c955..2f47e014b 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -44,6 +44,7 @@ namespace ArchiSteamFarm { internal sealed class Bot : IDisposable { private const ushort CallbackSleep = 500; // In miliseconds private const byte FamilySharingInactivityMinutes = 5; + private const byte LoginCooldownInMinutes = 25; // Captcha disappears after around 20 minutes, so we make it 25 private const uint LoginID = GlobalConfig.DefaultWCFPort; // This must be the same for all ASF bots and all ASF processes private const ushort MaxSteamMessageLength = 2048; private const byte MaxTwoFactorCodeFailures = 3; @@ -131,7 +132,7 @@ namespace ArchiSteamFarm { BotConfig = BotConfig.Load(botConfigFile); if (BotConfig == null) { - ArchiLogger.LogGenericError("Your bot config is invalid, please verify content of " + botConfigFile + " and try again!"); + ArchiLogger.LogGenericError(string.Format(Strings.ErrorBotConfigInvalid, botConfigFile)); return; } @@ -139,13 +140,13 @@ namespace ArchiSteamFarm { BotDatabase = BotDatabase.Load(botDatabaseFile); if (BotDatabase == null) { - ArchiLogger.LogGenericError("Bot database could not be loaded, refusing to create this bot instance! In order to recreate it, remove " + botDatabaseFile + " and try again!"); + ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, botDatabaseFile)); return; } // Register bot as available for ASF if (!Bots.TryAdd(botName, this)) { - throw new ArgumentException("That bot is already defined!"); + throw new ArgumentException(string.Format(Strings.ErrorIsInvalid, nameof(botName))); } if (HasMobileAuthenticator) { @@ -316,13 +317,13 @@ namespace ArchiSteamFarm { // Normally we wouldn't need to do this, but there is a case where our list might be invalid or outdated // Ensure that we always ask once for list of up-to-date servers, even if we have list saved - Program.ArchiLogger.LogGenericInfo("Initializing SteamDirectory..."); + Program.ArchiLogger.LogGenericInfo(string.Format(Strings.Initializing, nameof(SteamDirectory))); try { await SteamDirectory.Initialize(cellID).ConfigureAwait(false); Program.ArchiLogger.LogGenericInfo(Strings.Success); } catch { - Program.ArchiLogger.LogGenericWarning("Could not initialize SteamDirectory, connecting with Steam Network might take much longer than usual!"); + Program.ArchiLogger.LogGenericWarning(Strings.BotSteamDirectoryInitializationFailed); } } @@ -596,7 +597,7 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Stopping..."); + ArchiLogger.LogGenericInfo(Strings.BotStopping); KeepRunning = false; if (SteamClient.IsConnected) { @@ -613,19 +614,19 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Shared library has not been launched in given time period, farming process resumed!"); + ArchiLogger.LogGenericInfo(Strings.BotAutomaticIdlingPauseTimeout); StopFamilySharingInactivityTimer(); CardsFarmer.Resume(false); } private void CheckOccupationStatus() { if (!IsPlayingPossible) { - ArchiLogger.LogGenericInfo("Account is currently being used, ASF will resume farming when it's free..."); + ArchiLogger.LogGenericInfo(Strings.BotAccountOccupied); StopFamilySharingInactivityTimer(); return; } - ArchiLogger.LogGenericInfo("Account is no longer occupied, farming process resumed!"); + ArchiLogger.LogGenericInfo(Strings.BotAccountFree); CardsFarmer.Resume(false); } @@ -658,7 +659,7 @@ namespace ArchiSteamFarm { ); } - ArchiLogger.LogGenericInfo("Connecting..."); + ArchiLogger.LogGenericInfo(Strings.BotConnecting); SteamClient.Connect(); } } @@ -710,7 +711,9 @@ namespace ArchiSteamFarm { } string response = await Response(steamID, message).ConfigureAwait(false); - if (string.IsNullOrEmpty(response)) { // We respond with null when user is not authorized (and similar) + + // We respond with null when user is not authorized (and similar) + if (string.IsNullOrEmpty(response)) { return; } @@ -732,13 +735,13 @@ namespace ArchiSteamFarm { if (++HeartBeatFailures >= 15) { HeartBeatFailures = byte.MaxValue; - ArchiLogger.LogGenericError("HeartBeat failed to disconnect the client, abandoning this bot instance!"); + ArchiLogger.LogGenericError(Strings.BotHeartBeatFailed); Destroy(true); new Bot(BotName).Forget(); return; } - ArchiLogger.LogGenericWarning("Connection to Steam Network lost, reconnecting..."); + ArchiLogger.LogGenericWarning(Strings.BotConnectionLost); Connect(true).Forget(); } } @@ -748,7 +751,7 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Converting .maFile into ASF format..."); + ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorConverting); try { BotDatabase.MobileAuthenticator = JsonConvert.DeserializeObject(File.ReadAllText(maFilePath)); @@ -766,7 +769,7 @@ namespace ArchiSteamFarm { BotDatabase.MobileAuthenticator.Init(this); if (!BotDatabase.MobileAuthenticator.HasCorrectDeviceID) { - ArchiLogger.LogGenericWarning("Your DeviceID is incorrect or doesn't exist"); + ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID); string deviceID = Program.GetUserInput(ASF.EUserInputType.DeviceID, BotName); if (string.IsNullOrEmpty(deviceID)) { BotDatabase.MobileAuthenticator = null; @@ -777,12 +780,12 @@ namespace ArchiSteamFarm { BotDatabase.Save(); } - ArchiLogger.LogGenericInfo("Successfully finished importing mobile authenticator!"); + ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorImportFinished); } private async Task Initialize() { if (!BotConfig.Enabled) { - ArchiLogger.LogGenericInfo("Not starting this instance because it's disabled in config file"); + ArchiLogger.LogGenericInfo(Strings.BotInstanceNotStartingBecauseDisabled); return; } @@ -916,8 +919,8 @@ namespace ArchiSteamFarm { ArchiLogger.LogGenericTrace(callback.ChatRoomID.ConvertToUInt64() + "/" + callback.ChatterID.ConvertToUInt64() + ": " + callback.Message); - switch (callback.Message) { - case "!leave": + switch (callback.Message.ToUpperInvariant()) { + case "!LEAVE": if (!IsMaster(callback.ChatterID)) { break; } @@ -942,14 +945,14 @@ namespace ArchiSteamFarm { } if (callback.Result != EResult.OK) { - ArchiLogger.LogGenericError("Unable to connect to Steam: " + callback.Result); + ArchiLogger.LogGenericError(string.Format(Strings.BotUnableToConnect, callback.Result)); return; } - ArchiLogger.LogGenericInfo("Connected to Steam!"); + ArchiLogger.LogGenericInfo(Strings.BotConnected); if (!KeepRunning) { - ArchiLogger.LogGenericInfo("Disconnecting..."); + ArchiLogger.LogGenericInfo(Strings.BotDisconnecting); Disconnect(); return; } @@ -969,7 +972,7 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Logging in..."); + ArchiLogger.LogGenericInfo(Strings.LoggingIn); string password = BotConfig.SteamPassword; if (!string.IsNullOrEmpty(password)) { @@ -985,15 +988,15 @@ namespace ArchiSteamFarm { } SteamUser.LogOnDetails logOnDetails = new SteamUser.LogOnDetails { - Username = BotConfig.SteamLogin, - Password = password, AuthCode = AuthCode, CellID = Program.GlobalDatabase.CellID, LoginID = LoginID, LoginKey = loginKey, - TwoFactorCode = TwoFactorCode, + Password = password, SentryFileHash = sentryFileHash, - ShouldRememberPassword = true + ShouldRememberPassword = true, + TwoFactorCode = TwoFactorCode, + Username = BotConfig.SteamLogin }; try { @@ -1020,7 +1023,7 @@ namespace ArchiSteamFarm { EResult lastLogOnResult = LastLogOnResult; LastLogOnResult = EResult.Invalid; - ArchiLogger.LogGenericInfo("Disconnected from Steam!"); + ArchiLogger.LogGenericInfo(Strings.BotDisconnected); ArchiWebHandler.OnDisconnected(); CardsFarmer.OnDisconnected(); @@ -1047,7 +1050,7 @@ namespace ArchiSteamFarm { } BotDatabase.LoginKey = null; - ArchiLogger.LogGenericInfo("Removed expired login key"); + ArchiLogger.LogGenericInfo(Strings.BotRemovedExpiredLoginKey); break; case EResult.NoConnection: case EResult.ServiceUnavailable: @@ -1056,8 +1059,8 @@ namespace ArchiSteamFarm { await Task.Delay(5000).ConfigureAwait(false); break; case EResult.RateLimitExceeded: - ArchiLogger.LogGenericInfo("Will retry after 25 minutes..."); - await Task.Delay(25 * 60 * 1000).ConfigureAwait(false); // Captcha disappears after around 20 minutes, so we make it 25 + ArchiLogger.LogGenericInfo(string.Format(Strings.BotRateLimitExceeded, LoginCooldownInMinutes)); + await Task.Delay(LoginCooldownInMinutes * 60 * 1000).ConfigureAwait(false); break; } @@ -1065,7 +1068,7 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Reconnecting..."); + ArchiLogger.LogGenericInfo(Strings.BotReconnecting); await Connect().ConfigureAwait(false); } @@ -1158,18 +1161,18 @@ namespace ArchiSteamFarm { foreach (ulong gid in callback.GuestPasses.Select(guestPass => guestPass["gid"].AsUnsignedLong()).Where(gid => (gid != 0) && !HandledGifts.Contains(gid))) { HandledGifts.Add(gid); - ArchiLogger.LogGenericInfo("Accepting gift: " + gid + "..."); + ArchiLogger.LogGenericInfo(string.Join(Strings.BotAcceptingGift, gid)); await LimitGiftsRequestsAsync().ConfigureAwait(false); ArchiHandler.RedeemGuestPassResponseCallback response = await ArchiHandler.RedeemGuestPass(gid).ConfigureAwait(false); if (response != null) { if (response.Result == EResult.OK) { - ArchiLogger.LogGenericInfo("Success!"); + ArchiLogger.LogGenericInfo(Strings.Success); } else { - ArchiLogger.LogGenericWarning("Failed with error: " + response.Result); + ArchiLogger.LogGenericWarning(string.Format(Strings.WarningFailedWithError, response.Result)); } } else { - ArchiLogger.LogGenericWarning("Failed!"); + ArchiLogger.LogGenericWarning(Strings.WarningFailed); } } } @@ -1211,11 +1214,11 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericInfo("Logged off of Steam: " + callback.Result); + ArchiLogger.LogGenericInfo(string.Format(Strings.BotLoggedOff, callback.Result)); switch (callback.Result) { case EResult.LogonSessionReplaced: - ArchiLogger.LogGenericError("This account seems to be used in another ASF instance, which is undefined behaviour, refusing to keep it running!"); + ArchiLogger.LogGenericError(Strings.BotLogonSessionReplaced); Stop(); break; } @@ -1251,7 +1254,7 @@ namespace ArchiSteamFarm { break; case EResult.OK: - ArchiLogger.LogGenericInfo("Successfully logged on!"); + ArchiLogger.LogGenericInfo(Strings.BotLoggedOn); // Old status for these doesn't matter, we'll update them if needed LibraryLockedBySteamID = TwoFactorCodeFailures = 0; @@ -1259,7 +1262,7 @@ namespace ArchiSteamFarm { if (callback.AccountFlags.HasFlag(EAccountFlags.LimitedUser)) { IsLimitedUser = true; - ArchiLogger.LogGenericWarning("This account is limited, farming process is permanently unavailable until the restriction is removed!"); + ArchiLogger.LogGenericWarning(Strings.BotAccountLimited); } if ((callback.CellID != 0) && (Program.GlobalDatabase.CellID != callback.CellID)) { @@ -1314,19 +1317,19 @@ namespace ArchiSteamFarm { case EResult.Timeout: case EResult.TryAnotherCM: case EResult.TwoFactorCodeMismatch: - ArchiLogger.LogGenericWarning("Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult); + ArchiLogger.LogGenericWarning(string.Format(Strings.BotUnableToLogin, callback.Result, callback.ExtendedResult)); if ((callback.Result == EResult.TwoFactorCodeMismatch) && HasMobileAuthenticator) { if (++TwoFactorCodeFailures >= MaxTwoFactorCodeFailures) { TwoFactorCodeFailures = 0; - ArchiLogger.LogGenericError("Received TwoFactorCodeMismatch " + MaxTwoFactorCodeFailures + " times in a row, this almost always indicates invalid ASF 2FA credentials, aborting!"); + ArchiLogger.LogGenericError(string.Format(Strings.BotInvalidAuthenticatorDuringLogin, MaxTwoFactorCodeFailures)); Stop(); } } break; default: // Unexpected result, shutdown immediately - ArchiLogger.LogGenericError("Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult); + ArchiLogger.LogGenericError(string.Format(Strings.BotUnableToLogin, callback.Result, callback.ExtendedResult)); Stop(); break; } @@ -1512,15 +1515,11 @@ namespace ArchiSteamFarm { } if (!HasMobileAuthenticator) { - return "That bot doesn't have ASF 2FA enabled! Did you forget to import your authenticator as ASF 2FA?"; + return Strings.BotNoASFAuthenticator; } string token = await BotDatabase.MobileAuthenticator.GenerateToken().ConfigureAwait(false); - if (string.IsNullOrEmpty(token)) { - return "Error!"; - } - - return "2FA Token: " + token; + return !string.IsNullOrEmpty(token) ? string.Format(Strings.BotAuthenticatorToken, token) : Strings.WarningFailed; } private static async Task Response2FA(ulong steamID, string botName) { @@ -1552,14 +1551,14 @@ namespace ArchiSteamFarm { } if (!HasMobileAuthenticator) { - return "That bot doesn't have ASF 2FA enabled! Did you forget to import your authenticator as ASF 2FA?"; + return Strings.BotNoASFAuthenticator; } if (await AcceptConfirmations(confirm).ConfigureAwait(false)) { - return "Success!"; + return Strings.Success; } - return "Something went wrong!"; + return Strings.WarningFailed; } private static async Task Response2FAConfirm(ulong steamID, string botName, bool confirm) { @@ -1594,16 +1593,18 @@ namespace ArchiSteamFarm { foreach (uint gameID in gameIDs) { SteamApps.FreeLicenseCallback callback = await SteamApps.RequestFreeLicense(gameID); if (callback == null) { - result.AppendLine(Environment.NewLine + "Result: Timeout!"); + result.AppendLine(Environment.NewLine + string.Join(Strings.BotAddLicenseResponse, BotName, gameID, EResult.Timeout)); break; } - if ((callback.GrantedApps.Count != 0) || (callback.GrantedPackages.Count != 0)) { - result.AppendLine(Environment.NewLine + "Result: " + callback.Result + " | Granted apps:" + (callback.GrantedApps.Count != 0 ? " " + string.Join(", ", callback.GrantedApps) : "") + (callback.GrantedPackages.Count != 0 ? " " + string.Join(", ", callback.GrantedPackages) : "")); + if (callback.GrantedApps.Count > 0) { + result.AppendLine(Environment.NewLine + string.Join(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedApps))); + } else if (callback.GrantedPackages.Count > 0) { + result.AppendLine(Environment.NewLine + string.Join(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedPackages))); } else if (await ArchiWebHandler.AddFreeLicense(gameID).ConfigureAwait(false)) { - result.AppendLine(Environment.NewLine + "Result: " + EResult.OK + " | Granted apps: " + gameID); + result.AppendLine(Environment.NewLine + string.Join(Strings.BotAddLicenseResponseWithItems, BotName, gameID, EResult.OK, gameID)); } else { - result.AppendLine(Environment.NewLine + "Result: " + EResult.AccessDenied); + result.AppendLine(Environment.NewLine + string.Join(Strings.BotAddLicenseResponse, BotName, gameID, EResult.AccessDenied)); } } @@ -1627,14 +1628,14 @@ namespace ArchiSteamFarm { foreach (string game in gameIDs.Where(game => !string.IsNullOrEmpty(game))) { uint gameID; if (!uint.TryParse(game, out gameID)) { - return "Couldn't parse games list!"; + return string.Format(Strings.ErrorParsingObject, nameof(gameID)); } gamesToRedeem.Add(gameID); } if (gamesToRedeem.Count == 0) { - return "List of games is empty!"; + return string.Format(Strings.ErrorIsEmpty, nameof(gamesToRedeem)); } return await bot.ResponseAddLicense(steamID, gamesToRedeem).ConfigureAwait(false); @@ -1729,35 +1730,35 @@ namespace ArchiSteamFarm { } if (!LootingAllowed) { - return "Looting is temporarily disabled!"; + return Strings.BotLootingTemporarilyDisabled; } if (BotConfig.SteamMasterID == 0) { - return "Trade couldn't be send because SteamMasterID is not defined!"; + return Strings.BotLootingMasterNotDefined; } if (BotConfig.SteamMasterID == SteamClient.SteamID) { - return "You can't loot yourself!"; + return Strings.BotLootingYourself; } if (BotConfig.LootableTypes.Count == 0) { - return "You don't have any lootable types set!"; + return Strings.BotLootingNoLootableTypes; } await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false); HashSet inventory = await ArchiWebHandler.GetMySteamInventory(true, BotConfig.LootableTypes).ConfigureAwait(false); if ((inventory == null) || (inventory.Count == 0)) { - return "Nothing to send, inventory seems empty!"; + return string.Format(Strings.ErrorIsEmpty, nameof(inventory)); } if (!await ArchiWebHandler.SendTradeOffer(inventory, BotConfig.SteamMasterID, BotConfig.SteamTradeToken).ConfigureAwait(false)) { - return "Trade offer failed due to error!"; + return Strings.BotLootingFailed; } await Task.Delay(3000).ConfigureAwait(false); // Sometimes we can be too fast for Steam servers to generate confirmations, wait a short moment await AcceptConfirmations(true, Steam.ConfirmationDetails.EType.Trade, BotConfig.SteamMasterID).ConfigureAwait(false); - return "Trade offer sent successfully!"; + return Strings.BotLootingSuccess; } private static async Task ResponseLoot(ulong steamID, string botName) { @@ -1799,7 +1800,7 @@ namespace ArchiSteamFarm { } LootingAllowed = !LootingAllowed; - return LootingAllowed ? Strings.BotLootingEnabled : Strings.BotLootingDisabled; + return LootingAllowed ? Strings.BotLootingNowEnabled : Strings.BotLootingNowDisabled; } private static string ResponseLootSwitch(ulong steamID, string botName) { @@ -1957,7 +1958,7 @@ namespace ArchiSteamFarm { await CardsFarmer.Pause(sticky).ConfigureAwait(false); if (!SteamFamilySharingIDs.Contains(steamID)) { - return Strings.BotAutomaticIdlingPaused; + return Strings.BotAutomaticIdlingNowPaused; } StartFamilySharingInactivityTimer(); @@ -2132,7 +2133,7 @@ namespace ArchiSteamFarm { foreach (Bot bot in Bots.Where(bot => (bot.Value != previousBot) && (!redeemFlags.HasFlag(ERedeemFlags.SkipInitial) || (bot.Value != this)) && bot.Value.IsConnectedAndLoggedOn && ((items.Count == 0) || items.Keys.Any(packageID => !bot.Value.OwnedPackageIDs.Contains(packageID)))).OrderBy(bot => bot.Key).Select(bot => bot.Value)) { ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false); if (otherResult == null) { - response.Append(Environment.NewLine + string.Join(Strings.BotRedeemResponse, bot.BotName, key, "Timeout!")); + response.Append(Environment.NewLine + string.Join(Strings.BotRedeemResponse, bot.BotName, key, EResult.Timeout)); continue; } @@ -2262,7 +2263,7 @@ namespace ArchiSteamFarm { StopFamilySharingInactivityTimer(); CardsFarmer.Resume(true); - return Strings.BotAutomaticIdlingResumed; + return Strings.BotAutomaticIdlingNowResumed; } private static string ResponseResume(ulong steamID, string botName) { diff --git a/ArchiSteamFarm/Localization/Strings.Designer.cs b/ArchiSteamFarm/Localization/Strings.Designer.cs index 1c6dd0702..a9728e19f 100644 --- a/ArchiSteamFarm/Localization/Strings.Designer.cs +++ b/ArchiSteamFarm/Localization/Strings.Designer.cs @@ -78,6 +78,60 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Accepting gift: {0}.... + /// + internal static string BotAcceptingGift { + get { + return ResourceManager.GetString("BotAcceptingGift", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Account is no longer occupied, idling process resumed!. + /// + internal static string BotAccountFree { + get { + return ResourceManager.GetString("BotAccountFree", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This account is limited, farming process is permanently unavailable until the restriction is removed!. + /// + internal static string BotAccountLimited { + get { + return ResourceManager.GetString("BotAccountLimited", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Account is currently being used, ASF will resume idling when it's free.... + /// + internal static string BotAccountOccupied { + get { + return ResourceManager.GetString("BotAccountOccupied", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <{0}> GameID: {1} | Status: {2}. + /// + internal static string BotAddLicenseResponse { + get { + return ResourceManager.GetString("BotAddLicenseResponse", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <{0}> GameID: {1} | Status: {2} | Items: {3}. + /// + internal static string BotAddLicenseResponseWithItems { + get { + return ResourceManager.GetString("BotAddLicenseResponseWithItems", resourceCulture); + } + } + /// /// Looks up a localized string similar to That bot instance is already running!. /// @@ -96,12 +150,57 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Converting .maFile into ASF format.... + /// + internal static string BotAuthenticatorConverting { + get { + return ResourceManager.GetString("BotAuthenticatorConverting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully finished importing mobile authenticator!. + /// + internal static string BotAuthenticatorImportFinished { + get { + return ResourceManager.GetString("BotAuthenticatorImportFinished", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your DeviceID is incorrect or doesn't exist!. + /// + internal static string BotAuthenticatorInvalidDeviceID { + get { + return ResourceManager.GetString("BotAuthenticatorInvalidDeviceID", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 2FA Token: {0}. + /// + internal static string BotAuthenticatorToken { + get { + return ResourceManager.GetString("BotAuthenticatorToken", resourceCulture); + } + } + /// /// Looks up a localized string similar to Automatic idling is now paused!. /// - internal static string BotAutomaticIdlingPaused { + internal static string BotAutomaticIdlingNowPaused { get { - return ResourceManager.GetString("BotAutomaticIdlingPaused", resourceCulture); + return ResourceManager.GetString("BotAutomaticIdlingNowPaused", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatic idling is now resumed!. + /// + internal static string BotAutomaticIdlingNowResumed { + get { + return ResourceManager.GetString("BotAutomaticIdlingNowResumed", resourceCulture); } } @@ -124,11 +223,11 @@ namespace ArchiSteamFarm.Localization { } /// - /// Looks up a localized string similar to Automatic idling is now resumed!. + /// Looks up a localized string similar to Shared library has not been launched in given time period, idling process resumed!. /// - internal static string BotAutomaticIdlingResumed { + internal static string BotAutomaticIdlingPauseTimeout { get { - return ResourceManager.GetString("BotAutomaticIdlingResumed", resourceCulture); + return ResourceManager.GetString("BotAutomaticIdlingPauseTimeout", resourceCulture); } } @@ -141,6 +240,51 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Connected to Steam!. + /// + internal static string BotConnected { + get { + return ResourceManager.GetString("BotConnected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Connecting.... + /// + internal static string BotConnecting { + get { + return ResourceManager.GetString("BotConnecting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Connection to Steam Network lost, reconnecting.... + /// + internal static string BotConnectionLost { + get { + return ResourceManager.GetString("BotConnectionLost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disconnected from Steam!. + /// + internal static string BotDisconnected { + get { + return ResourceManager.GetString("BotDisconnected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disconnecting.... + /// + internal static string BotDisconnecting { + get { + return ResourceManager.GetString("BotDisconnecting", resourceCulture); + } + } + /// /// Looks up a localized string similar to [{0}] password: {1}. /// @@ -150,21 +294,147 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to HeartBeat failed to disconnect the client, abandoning this bot instance!. + /// + internal static string BotHeartBeatFailed { + get { + return ResourceManager.GetString("BotHeartBeatFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not starting this bot instance because it's disabled in config file!. + /// + internal static string BotInstanceNotStartingBecauseDisabled { + get { + return ResourceManager.GetString("BotInstanceNotStartingBecauseDisabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Received TwoFactorCodeMismatch error code {0} times in a row, this almost always indicates invalid ASF 2FA credentials, aborting!. + /// + internal static string BotInvalidAuthenticatorDuringLogin { + get { + return ResourceManager.GetString("BotInvalidAuthenticatorDuringLogin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logged off of Steam: {0}. + /// + internal static string BotLoggedOff { + get { + return ResourceManager.GetString("BotLoggedOff", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully logged on!. + /// + internal static string BotLoggedOn { + get { + return ResourceManager.GetString("BotLoggedOn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logging in.... + /// + internal static string BotLoggingIn { + get { + return ResourceManager.GetString("BotLoggingIn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This account seems to be used in another ASF instance, which is undefined behaviour, refusing to keep it running!. + /// + internal static string BotLogonSessionReplaced { + get { + return ResourceManager.GetString("BotLogonSessionReplaced", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trade offer failed!. + /// + internal static string BotLootingFailed { + get { + return ResourceManager.GetString("BotLootingFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trade couldn't be send because SteamMasterID is not defined!. + /// + internal static string BotLootingMasterNotDefined { + get { + return ResourceManager.GetString("BotLootingMasterNotDefined", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You don't have any lootable types set!. + /// + internal static string BotLootingNoLootableTypes { + get { + return ResourceManager.GetString("BotLootingNoLootableTypes", resourceCulture); + } + } + /// /// Looks up a localized string similar to Looting is now disabled!. /// - internal static string BotLootingDisabled { + internal static string BotLootingNowDisabled { get { - return ResourceManager.GetString("BotLootingDisabled", resourceCulture); + return ResourceManager.GetString("BotLootingNowDisabled", resourceCulture); } } /// /// Looks up a localized string similar to Looting is now enabled!. /// - internal static string BotLootingEnabled { + internal static string BotLootingNowEnabled { get { - return ResourceManager.GetString("BotLootingEnabled", resourceCulture); + return ResourceManager.GetString("BotLootingNowEnabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trade offer sent successfully!. + /// + internal static string BotLootingSuccess { + get { + return ResourceManager.GetString("BotLootingSuccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Looting is temporarily disabled!. + /// + internal static string BotLootingTemporarilyDisabled { + get { + return ResourceManager.GetString("BotLootingTemporarilyDisabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can't loot yourself!. + /// + internal static string BotLootingYourself { + get { + return ResourceManager.GetString("BotLootingYourself", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to That bot doesn't have ASF 2FA enabled! Did you forget to import your authenticator as ASF 2FA?. + /// + internal static string BotNoASFAuthenticator { + get { + return ResourceManager.GetString("BotNoASFAuthenticator", resourceCulture); } } @@ -204,6 +474,24 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Rate limit exceeded, we will retry after {0} minutes of cooldown.... + /// + internal static string BotRateLimitExceeded { + get { + return ResourceManager.GetString("BotRateLimitExceeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reconnecting.... + /// + internal static string BotReconnecting { + get { + return ResourceManager.GetString("BotReconnecting", resourceCulture); + } + } + /// /// Looks up a localized string similar to <{0}> Key: {1} | Status: {2}. /// @@ -222,6 +510,15 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Removed expired login key!. + /// + internal static string BotRemovedExpiredLoginKey { + get { + return ResourceManager.GetString("BotRemovedExpiredLoginKey", resourceCulture); + } + } + /// /// Looks up a localized string similar to Bot {0} is not idling anything.. /// @@ -303,6 +600,42 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Could not initialize SteamDirectory, connecting with Steam Network might take much longer than usual!. + /// + internal static string BotSteamDirectoryInitializationFailed { + get { + return ResourceManager.GetString("BotSteamDirectoryInitializationFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stopping.... + /// + internal static string BotStopping { + get { + return ResourceManager.GetString("BotStopping", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unable to connect to Steam: {0}. + /// + internal static string BotUnableToConnect { + get { + return ResourceManager.GetString("BotUnableToConnect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unable to login to Steam: {0}/{1}. + /// + internal static string BotUnableToLogin { + get { + return ResourceManager.GetString("BotUnableToLogin", resourceCulture); + } + } + /// /// Looks up a localized string similar to Checking first badge page.... /// @@ -349,6 +682,15 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Your bot config is invalid, please verify content of {0} and try again!. + /// + internal static string ErrorBotConfigInvalid { + get { + return ResourceManager.GetString("ErrorBotConfigInvalid", resourceCulture); + } + } + /// /// Looks up a localized string similar to Configured {0} property is invalid: {1}. /// @@ -358,6 +700,15 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Persistent database could not be loaded, if issue persists, please remove {0} in order to recreate the database!. + /// + internal static string ErrorDatabaseInvalid { + get { + return ResourceManager.GetString("ErrorDatabaseInvalid", resourceCulture); + } + } + /// /// Looks up a localized string similar to ASF V{0} has run into fatal exception before core logging module was even able to initialize!. /// @@ -414,15 +765,6 @@ namespace ArchiSteamFarm.Localization { } } - /// - /// Looks up a localized string similar to Global database could not be loaded, if issue persists, please remove {0} in order to recreate database!. - /// - internal static string ErrorGlobalDatabaseNotLoaded { - get { - return ResourceManager.GetString("ErrorGlobalDatabaseNotLoaded", resourceCulture); - } - } - /// /// Looks up a localized string similar to {0} is empty!. /// @@ -639,6 +981,15 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Initializing {0}.... + /// + internal static string Initializing { + get { + return ResourceManager.GetString("Initializing", resourceCulture); + } + } + /// /// Looks up a localized string similar to Logging in to {0}.... /// @@ -1044,6 +1395,15 @@ namespace ArchiSteamFarm.Localization { } } + /// + /// Looks up a localized string similar to Failed due to error: {0}. + /// + internal static string WarningFailedWithError { + get { + return ResourceManager.GetString("WarningFailedWithError", resourceCulture); + } + } + /// /// Looks up a localized string similar to Received unknown confirmation type, please report this: {0}. /// diff --git a/ArchiSteamFarm/Localization/Strings.resx b/ArchiSteamFarm/Localization/Strings.resx index 0539e232e..06de49912 100644 --- a/ArchiSteamFarm/Localization/Strings.resx +++ b/ArchiSteamFarm/Localization/Strings.resx @@ -155,10 +155,6 @@ StackTrace: Global config could not be loaded, please make sure that {0} exists and is valid! Follow setting up guide on the wiki if you're confused. {0} will be replaced by file's path - - Global database could not be loaded, if issue persists, please remove {0} in order to recreate database! - {0} will be replaced by file's path - {0} is invalid! {0} will be replaced by object's name @@ -468,13 +464,44 @@ StackTrace: Could not check cards status for: {0} ({1}), we will try again later! {0} will be replaced by game's appID (number), {1} will be replaced by game's name + + Accepting gift: {0}... + {0} will be replaced by giftID (number) + + + This account is limited, farming process is permanently unavailable until the restriction is removed! + + + <{0}> GameID: {1} | Status: {2} + {0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string + + + <{0}> GameID: {1} | Status: {2} | Items: {3} + {0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string, {3} will be replaced by list of granted appIDs (numbers), separated by a comma + That bot instance is already running! {0} will be replaced by bot's name - + + Converting .maFile into ASF format... + + + Successfully finished importing mobile authenticator! + + + Your DeviceID is incorrect or doesn't exist! + + + 2FA Token: {0} + {0} will be replaced by generated 2FA token (string) + + Automatic idling is now paused! + + Automatic idling is now resumed! + Automatic idling is paused already! @@ -482,22 +509,69 @@ StackTrace: Automatic idling is now paused! You have {0} minutes to start a game. {0} will be replaced by number of minutes - - Automatic idling is now resumed! - Automatic idling is resumed already! + + Connected to Steam! + + + Disconnected from Steam! + + + Disconnecting... + [{0}] password: {1} {0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string) - + + Not starting this bot instance because it's disabled in config file! + + + Received TwoFactorCodeMismatch error code {0} times in a row, this almost always indicates invalid ASF 2FA credentials, aborting! + {0} will be replaced by maximum allowed number of failed 2FA attempts + + + Logged off of Steam: {0} + {0} will be replaced by logging off reason (string) + + + Successfully logged on! + + + Logging in... + + + This account seems to be used in another ASF instance, which is undefined behaviour, refusing to keep it running! + + + Trade offer failed! + + + Trade couldn't be send because SteamMasterID is not defined! + + + You don't have any lootable types set! + + Looting is now disabled! - + Looting is now enabled! + + Trade offer sent successfully! + + + Looting is temporarily disabled! + + + You can't loot yourself! + + + That bot doesn't have ASF 2FA enabled! Did you forget to import your authenticator as ASF 2FA? + This bot instance is not connected! {0} will be replaced by bot's name @@ -510,6 +584,13 @@ StackTrace: <{0}> Owned already: {1} | {2} {0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name + + Rate limit exceeded, we will retry after {0} minutes of cooldown... + {0} will be replaced by number of minutes + + + Reconnecting... + <{0}> Key: {1} | Status: {2} {0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string @@ -518,6 +599,9 @@ StackTrace: <{0}> Key: {1} | Status: {2} | Items: {3} {0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string, {3} will be replaced by list of key-value pairs, separated by a comma + + Removed expired login key! + Bot {0} is not idling anything. {0} will be replaced by bot's name @@ -542,6 +626,14 @@ StackTrace: Bot {0} is currently being used. {0} will be replaced by bot's name + + Unable to connect to Steam: {0} + {0} will be replaced by failure reason (string) + + + Unable to login to Steam: {0}/{1} + {0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string) + {0} is empty! {0} will be replaced by object's name @@ -550,4 +642,44 @@ StackTrace: Unused keys: {0} {0} will be replaced by list of cd-keys (strings), separated by a comma + + Failed due to error: {0} + {0} will be replaced by failure reason (string) + + + Connection to Steam Network lost, reconnecting... + + + Account is no longer occupied, idling process resumed! + + + Account is currently being used, ASF will resume idling when it's free... + + + Shared library has not been launched in given time period, idling process resumed! + + + Connecting... + + + HeartBeat failed to disconnect the client, abandoning this bot instance! + + + Could not initialize SteamDirectory, connecting with Steam Network might take much longer than usual! + + + Stopping... + + + Your bot config is invalid, please verify content of {0} and try again! + {0} will be replaced by file's path + + + Persistent database could not be loaded, if issue persists, please remove {0} in order to recreate the database! + {0} will be replaced by file's path + + + Initializing {0}... + {0} will be replaced by service name that is being initialized + \ No newline at end of file diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 1aeae839c..69dc4a951 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -209,7 +209,7 @@ namespace ArchiSteamFarm { GlobalDatabase = GlobalDatabase.Load(globalDatabaseFile); if (GlobalDatabase == null) { - ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalDatabaseNotLoaded, globalDatabaseFile)); + ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile)); Thread.Sleep(5000); Exit(1); }