Use string interpolation wherever possible

Majority of cases still need to go through string.Format() due to localization requirements
This commit is contained in:
Archi 2021-09-27 19:59:00 +02:00
parent de19010820
commit f2d3a2a894
No known key found for this signature in database
GPG key ID: 6B138B4C64555AEA
29 changed files with 160 additions and 160 deletions

View file

@ -38,7 +38,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
throw new ArgumentNullException(nameof(webBrowser));
}
Uri request = new(URL + "/meow");
Uri request = new($"{URL}/meow");
ObjectResponse<MeowResponse>? response = await webBrowser.UrlGetToJsonObject<MeowResponse>(request).ConfigureAwait(false);

View file

@ -70,7 +70,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
switch (configProperty) {
case nameof(ExamplePlugin) + "TestProperty" when configValue.Type == JTokenType.Boolean:
bool exampleBooleanValue = configValue.Value<bool>();
ASF.ArchiLogger.LogGenericInfo(nameof(ExamplePlugin) + "TestProperty boolean property has been found with a value of: " + exampleBooleanValue);
ASF.ArchiLogger.LogGenericInfo($"{nameof(ExamplePlugin)}TestProperty boolean property has been found with a value of: {exampleBooleanValue}");
break;
}
@ -121,7 +121,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
// In general you should do that only when you have a particular need of custom modules or alike, since ASF's plugin system will always provide bot to you as a function argument
public void OnBotInit(Bot bot) {
// Apart of those two that are already provided by ASF, you can also initialize your own logger with your plugin's name, if needed
bot.ArchiLogger.LogGenericInfo("Our bot named " + bot.BotName + " has been initialized, and we're letting you know about it from our " + nameof(ExamplePlugin) + "!");
bot.ArchiLogger.LogGenericInfo($"Our bot named {bot.BotName} has been initialized, and we're letting you know about it from our {nameof(ExamplePlugin)}!");
ASF.ArchiLogger.LogGenericWarning("In case we won't have a bot reference or have something process-wide to log, we can also use ASF's logger!");
}
@ -177,7 +177,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
// At this point you can access core ASF's functionality, such as logging, but more advanced structures (like ASF's WebBrowser) will be available in OnASFInit(), which itself takes place after every plugin gets OnLoaded()
// Typically you should use this function only for preparing core structures of your plugin, and optionally also sending a message to the user (e.g. support link, welcome message or similar), ASF-specific things should usually happen in OnASFInit()
public void OnLoaded() {
ASF.ArchiLogger.LogGenericInfo("Hey! Thanks for checking if our example plugin works fine, this is a confirmation that indeed " + nameof(OnLoaded) + "() method was called!");
ASF.ArchiLogger.LogGenericInfo($"Hey! Thanks for checking if our example plugin works fine, this is a confirmation that indeed {nameof(OnLoaded)}() method was called!");
ASF.ArchiLogger.LogGenericInfo("Good luck in whatever you're doing!");
}
}

View file

@ -43,7 +43,7 @@ namespace ArchiSteamFarm.CustomPlugins.PeriodicGC {
public void OnLoaded() {
TimeSpan timeSpan = TimeSpan.FromSeconds(GCPeriod);
ASF.ArchiLogger.LogGenericWarning("Periodic GC will occur every " + timeSpan.ToHumanReadable() + ". Please keep in mind that this plugin should be used for debugging tests only.");
ASF.ArchiLogger.LogGenericWarning($"Periodic GC will occur every {timeSpan.ToHumanReadable()}. Please keep in mind that this plugin should be used for debugging tests only.");
lock (LockObject) {
PeriodicGCTimer.Change(timeSpan, timeSpan);
@ -51,14 +51,14 @@ namespace ArchiSteamFarm.CustomPlugins.PeriodicGC {
}
private static void PerformGC(object? state = null) {
ASF.ArchiLogger.LogGenericWarning("Performing GC, current memory: " + (GC.GetTotalMemory(false) / 1024) + " KB.");
ASF.ArchiLogger.LogGenericWarning($"Performing GC, current memory: {GC.GetTotalMemory(false) / 1024} KB.");
lock (LockObject) {
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
}
ASF.ArchiLogger.LogGenericWarning("GC finished, current memory: " + (GC.GetTotalMemory(false) / 1024) + " KB.");
ASF.ArchiLogger.LogGenericWarning($"GC finished, current memory: {GC.GetTotalMemory(false) / 1024} KB.");
}
}
}

View file

@ -39,7 +39,7 @@ using SteamKit2;
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal sealed class GlobalCache : SerializableFile {
private static string SharedFilePath => Path.Combine(ArchiSteamFarm.SharedInfo.ConfigDirectory, nameof(SteamTokenDumper) + ".cache");
private static string SharedFilePath => Path.Combine(ArchiSteamFarm.SharedInfo.ConfigDirectory, $"{nameof(SteamTokenDumper)}.cache");
[JsonProperty(Required = Required.DisallowNull)]
private readonly ConcurrentDictionary<uint, uint> AppChangeNumbers = new();

View file

@ -497,7 +497,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
return;
}
Uri request = new(SharedInfo.ServerURL + "/submit");
Uri request = new($"{SharedInfo.ServerURL}/submit");
RequestData requestData = new(contributorSteamID, appTokens, packageTokens, depotKeys);
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionInProgress, appTokens.Count, packageTokens.Count, depotKeys.Count));

View file

@ -52,7 +52,7 @@ namespace ArchiSteamFarm.Tests {
[TestMethod]
public async Task DoesntSkipEmptyNewlines() {
string message = "asdf" + Environment.NewLine + Environment.NewLine + "asdf";
string message = $"asdf{Environment.NewLine}{Environment.NewLine}asdf";
List<string> output = await GetMessageParts(message).ToListAsync().ConfigureAwait(false);
@ -99,12 +99,12 @@ namespace ArchiSteamFarm.Tests {
int longLineLength = maxMessageBytes - ReservedContinuationMessageBytes;
string longLine = new('a', longLineLength - 2);
string message = longLine + @"\";
string message = $@"{longLine}\";
List<string> output = await GetMessageParts(message, isAccountLimited: isAccountLimited).ToListAsync().ConfigureAwait(false);
Assert.AreEqual(1, output.Count);
Assert.AreEqual(message + @"\", output.First());
Assert.AreEqual($@"{message}\", output.First());
}
[DataRow(false)]
@ -115,19 +115,19 @@ namespace ArchiSteamFarm.Tests {
int longLineLength = maxMessageBytes - ReservedContinuationMessageBytes;
string longLine = new('a', longLineLength - 1);
string message = longLine + "[";
string message = $"{longLine}[";
List<string> output = await GetMessageParts(message, isAccountLimited: isAccountLimited).ToListAsync().ConfigureAwait(false);
Assert.AreEqual(2, output.Count);
Assert.AreEqual(longLine + ContinuationCharacter, output[0]);
Assert.AreEqual(ContinuationCharacter + @"\[", output[1]);
Assert.AreEqual($@"{ContinuationCharacter}\[", output[1]);
}
[TestMethod]
public async Task NoNeedForAnySplittingWithNewlines() {
string message = "abcdef" + Environment.NewLine + "ghijkl" + Environment.NewLine + "mnopqr";
string message = $"abcdef{Environment.NewLine}ghijkl{Environment.NewLine}mnopqr";
List<string> output = await GetMessageParts(message).ToListAsync().ConfigureAwait(false);

View file

@ -253,7 +253,7 @@ namespace ArchiSteamFarm.Core {
return null;
}
string targetFile = SharedInfo.ASF + "-" + SharedInfo.BuildInfo.Variant + ".zip";
string targetFile = $"{SharedInfo.ASF}-{SharedInfo.BuildInfo.Variant}.zip";
GitHub.ReleaseResponse.Asset? binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name!.Equals(targetFile, StringComparison.OrdinalIgnoreCase));
if (binaryAsset == null) {
@ -397,11 +397,11 @@ namespace ArchiSteamFarm.Core {
using SHA256 hashingAlgorithm = SHA256.Create();
// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
networkGroupText = "-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Program.NetworkGroup!))).Replace("-", "", StringComparison.Ordinal);
networkGroupText = $"-{BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Program.NetworkGroup!))).Replace("-", "", StringComparison.Ordinal)}";
} else if (!string.IsNullOrEmpty(GlobalConfig.WebProxyText)) {
using SHA256 hashingAlgorithm = SHA256.Create();
networkGroupText = "-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(GlobalConfig.WebProxyText!))).Replace("-", "", StringComparison.Ordinal);
networkGroupText = $"-{BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(GlobalConfig.WebProxyText!))).Replace("-", "", StringComparison.Ordinal)}";
}
ConfirmationsSemaphore ??= await PluginsCore.GetCrossProcessSemaphore(nameof(ConfirmationsSemaphore) + networkGroupText).ConfigureAwait(false);
@ -412,10 +412,10 @@ namespace ArchiSteamFarm.Core {
RateLimitingSemaphore ??= await PluginsCore.GetCrossProcessSemaphore(nameof(RateLimitingSemaphore) + networkGroupText).ConfigureAwait(false);
WebLimitingSemaphores ??= new Dictionary<Uri, (ICrossProcessSemaphore RateLimitingSemaphore, SemaphoreSlim OpenConnectionsSemaphore)>(4) {
{ ArchiWebHandler.SteamCommunityURL, (await PluginsCore.GetCrossProcessSemaphore(nameof(ArchiWebHandler) + networkGroupText + "-" + nameof(ArchiWebHandler.SteamCommunityURL)).ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamHelpURL, (await PluginsCore.GetCrossProcessSemaphore(nameof(ArchiWebHandler) + networkGroupText + "-" + nameof(ArchiWebHandler.SteamHelpURL)).ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamStoreURL, (await PluginsCore.GetCrossProcessSemaphore(nameof(ArchiWebHandler) + networkGroupText + "-" + nameof(ArchiWebHandler.SteamStoreURL)).ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ WebAPI.DefaultBaseAddress, (await PluginsCore.GetCrossProcessSemaphore(nameof(ArchiWebHandler) + networkGroupText + "-" + nameof(WebAPI)).ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) }
{ ArchiWebHandler.SteamCommunityURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}{networkGroupText}-{nameof(ArchiWebHandler.SteamCommunityURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamHelpURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}{networkGroupText}-{nameof(ArchiWebHandler.SteamHelpURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamStoreURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}{networkGroupText}-{nameof(ArchiWebHandler.SteamStoreURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ WebAPI.DefaultBaseAddress, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}{networkGroupText}-{nameof(WebAPI)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) }
}.ToImmutableDictionary();
}
@ -823,7 +823,7 @@ namespace ArchiSteamFarm.Core {
private static async Task RegisterBots() {
if ((GlobalConfig == null) || (GlobalDatabase == null) || (WebBrowser == null)) {
throw new ArgumentNullException(nameof(GlobalConfig) + " || " + nameof(GlobalDatabase) + " || " + nameof(WebBrowser));
throw new ArgumentNullException($"{nameof(GlobalConfig)} || {nameof(GlobalDatabase)} || {nameof(WebBrowser)}");
}
// Ensure that we ask for a list of servers if we don't have any saved servers available
@ -848,7 +848,7 @@ namespace ArchiSteamFarm.Core {
HashSet<string> botNames;
try {
botNames = Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*" + SharedInfo.JsonConfigExtension).Select(Path.GetFileNameWithoutExtension).Where(botName => !string.IsNullOrEmpty(botName) && IsValidBotName(botName)).ToHashSet(Bot.BotsComparer)!;
botNames = Directory.EnumerateFiles(SharedInfo.ConfigDirectory, $"*{SharedInfo.JsonConfigExtension}").Select(Path.GetFileNameWithoutExtension).Where(botName => !string.IsNullOrEmpty(botName) && IsValidBotName(botName)).ToHashSet(Bot.BotsComparer)!;
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
@ -1003,7 +1003,7 @@ namespace ArchiSteamFarm.Core {
if (File.Exists(file)) {
// This is possible only with files that we decided to leave in place during our backup function
string targetBackupFile = file + ".bak";
string targetBackupFile = $"{file}.bak";
File.Move(file, targetBackupFile, true);
}

View file

@ -37,10 +37,10 @@ namespace ArchiSteamFarm.Core {
internal sealed class DebugListener : IDebugListener {
public void WriteLine(string category, string msg) {
if (string.IsNullOrEmpty(category) && string.IsNullOrEmpty(msg)) {
throw new InvalidOperationException(nameof(category) + " && " + nameof(msg));
throw new InvalidOperationException($"{nameof(category)} && {nameof(msg)}");
}
ASF.ArchiLogger.LogGenericDebug(category + " | " + msg);
ASF.ArchiLogger.LogGenericDebug($"{category} | {msg}");
}
}
}

View file

@ -85,7 +85,7 @@ namespace ArchiSteamFarm.Core {
description = "Unknown OS";
}
BackingVersion = framework + "; " + runtime + "; " + description;
BackingVersion = $"{framework}; {runtime}; {description}";
return BackingVersion;
}
@ -120,7 +120,7 @@ namespace ArchiSteamFarm.Core {
throw new ArgumentNullException(nameof(objectName));
}
return SharedInfo.AssemblyName + "-" + objectName;
return $"{SharedInfo.AssemblyName}-{objectName}";
}
internal static void Init(GlobalConfig.EOptimizationMode optimizationMode) {
@ -153,7 +153,7 @@ namespace ArchiSteamFarm.Core {
// At the same time it'd be the best if we avoided all special characters, such as '/' found e.g. in base64, as we can't be sure that it's not a prohibited character in regards to native OS implementation
// Because of that, SHA256 is sufficient for our case, as it generates alphanumeric characters only, and is barely 256-bit long. We don't need any kind of complex cryptography or collision detection here, any hashing algorithm will do, and the shorter the better
using (SHA256 hashingAlgorithm = SHA256.Create()) {
uniqueName = "Global\\" + GetOsResourceName(nameof(SingleInstance)) + "-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Directory.GetCurrentDirectory()))).Replace("-", "", StringComparison.Ordinal);
uniqueName = $"Global\\{GetOsResourceName(nameof(SingleInstance))}-{BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Directory.GetCurrentDirectory()))).Replace("-", "", StringComparison.Ordinal)}";
}
Mutex? singleInstance = null;
@ -195,7 +195,7 @@ namespace ArchiSteamFarm.Core {
}
if (!File.Exists(path) && !Directory.Exists(path)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, "!" + nameof(path)));
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"!{nameof(path)}"));
return;
}

View file

@ -112,7 +112,7 @@ namespace ArchiSteamFarm.Core {
return;
}
Uri request = new(URL + "/Api/HeartBeat");
Uri request = new($"{URL}/Api/HeartBeat");
Dictionary<string, string> data = new(2, StringComparer.Ordinal) {
{ "Guid", (ASF.GlobalDatabase?.Identifier ?? Guid.NewGuid()).ToString("N") },
@ -221,7 +221,7 @@ namespace ArchiSteamFarm.Core {
return;
}
Uri request = new(URL + "/Api/Announce");
Uri request = new($"{URL}/Api/Announce");
Dictionary<string, string> data = new(9, StringComparer.Ordinal) {
{ "AvatarHash", avatarHash ?? "" },
@ -258,7 +258,7 @@ namespace ArchiSteamFarm.Core {
}
private async Task<ImmutableHashSet<ListedUser>?> GetListedUsers() {
Uri request = new(URL + "/Api/Bots");
Uri request = new($"{URL}/Api/Bots");
ObjectResponse<ImmutableHashSet<ListedUser>>? response = await Bot.ArchiWebHandler.WebBrowser.UrlGetToJsonObject<ImmutableHashSet<ListedUser>>(request).ConfigureAwait(false);
@ -276,7 +276,7 @@ namespace ArchiSteamFarm.Core {
bool? hasPublicInventory = await Bot.HasPublicInventory().ConfigureAwait(false);
if (hasPublicInventory != true) {
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.HasPublicInventory) + ": " + (hasPublicInventory?.ToString() ?? "null")));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.HasPublicInventory)}: {hasPublicInventory?.ToString() ?? "null"}"));
return hasPublicInventory;
}
@ -287,21 +287,21 @@ namespace ArchiSteamFarm.Core {
private async Task<bool?> IsEligibleForMatching() {
// Bot must have ASF 2FA
if (!Bot.HasMobileAuthenticator) {
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.HasMobileAuthenticator) + ": " + Bot.HasMobileAuthenticator));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.HasMobileAuthenticator)}: {Bot.HasMobileAuthenticator}"));
return false;
}
// Bot must have STM enable in TradingPreferences
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.BotConfig.TradingPreferences) + ": " + Bot.BotConfig.TradingPreferences));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.TradingPreferences)}: {Bot.BotConfig.TradingPreferences}"));
return false;
}
// Bot must have at least one accepted matchable type set
if ((Bot.BotConfig.MatchableTypes.Count == 0) || Bot.BotConfig.MatchableTypes.All(type => !AcceptedMatchableTypes.Contains(type))) {
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.BotConfig.MatchableTypes) + ": " + string.Join(", ", Bot.BotConfig.MatchableTypes)));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.MatchableTypes)}: {string.Join(", ", Bot.BotConfig.MatchableTypes)}"));
return false;
}
@ -310,7 +310,7 @@ namespace ArchiSteamFarm.Core {
bool? hasValidApiKey = await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false);
if (hasValidApiKey != true) {
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.ArchiWebHandler.HasValidApiKey) + ": " + (hasValidApiKey?.ToString() ?? "null")));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.ArchiWebHandler.HasValidApiKey)}: {hasValidApiKey?.ToString() ?? "null"}"));
return hasValidApiKey;
}
@ -407,7 +407,7 @@ namespace ArchiSteamFarm.Core {
if (Trading.IsEmptyForMatching(ourFullState, ourTradableState)) {
// User doesn't have any more dupes in the inventory
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(ourFullState) + " || " + nameof(ourTradableState)));
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, $"{nameof(ourFullState)} || {nameof(ourTradableState)}"));
return (false, false);
}
@ -436,7 +436,7 @@ namespace ArchiSteamFarm.Core {
break;
}
Bot.ArchiLogger.LogGenericTrace(listedUser.SteamID + "...");
Bot.ArchiLogger.LogGenericTrace($"{listedUser.SteamID}...");
byte? holdDuration = await Bot.ArchiWebHandler.GetTradeHoldDurationForUser(listedUser.SteamID, listedUser.TradeToken).ConfigureAwait(false);
@ -446,7 +446,7 @@ namespace ArchiSteamFarm.Core {
continue;
case > 0 when holdDuration.Value > maxTradeHoldDuration:
Bot.ArchiLogger.LogGenericTrace(holdDuration.Value + " > " + maxTradeHoldDuration);
Bot.ArchiLogger.LogGenericTrace($"{holdDuration.Value} > {maxTradeHoldDuration}");
continue;
}
@ -662,7 +662,7 @@ namespace ArchiSteamFarm.Core {
triedSteamIDs[listedUser.SteamID] = (++previousAttempt.Tries, previousAttempt.GivenAssetIDs, previousAttempt.ReceivedAssetIDs);
Bot.ArchiLogger.LogGenericTrace(Bot.SteamID + " <- " + string.Join(", ", itemsToReceive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " | " + string.Join(", ", itemsToGive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " -> " + listedUser.SteamID);
Bot.ArchiLogger.LogGenericTrace($"{Bot.SteamID} <- {string.Join(", ", itemsToReceive.Select(item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} | {string.Join(", ", itemsToGive.Select(item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} -> {listedUser.SteamID}");
(bool success, HashSet<ulong>? mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(listedUser.SteamID, itemsToGive, itemsToReceive, listedUser.TradeToken, true).ConfigureAwait(false);

View file

@ -49,7 +49,7 @@ namespace ArchiSteamFarm.Core {
}
if (args.Length <= argsToSkip) {
throw new InvalidOperationException(nameof(args.Length) + " && " + nameof(argsToSkip));
throw new InvalidOperationException($"{nameof(args.Length)} && {nameof(argsToSkip)}");
}
if (string.IsNullOrEmpty(delimiter)) {
@ -228,7 +228,7 @@ namespace ArchiSteamFarm.Core {
[PublicAPI]
public static int RandomNext(int minValue, int maxValue) {
if (minValue > maxValue) {
throw new InvalidOperationException(nameof(minValue) + " && " + nameof(maxValue));
throw new InvalidOperationException($"{nameof(minValue)} && {nameof(maxValue)}");
}
if (minValue >= maxValue - 1) {

View file

@ -87,7 +87,7 @@ namespace ArchiSteamFarm.Helpers {
}
// We always want to write entire content to temporary file first, in order to never load corrupted data, also when target file doesn't exist
string newFilePath = FilePath + ".new";
string newFilePath = $"{FilePath}.new";
if (File.Exists(FilePath)) {
string currentJson = await File.ReadAllTextAsync(FilePath!).ConfigureAwait(false);
@ -138,7 +138,7 @@ namespace ArchiSteamFarm.Helpers {
throw new ArgumentNullException(nameof(json));
}
string newFilePath = filePath + ".new";
string newFilePath = $"{filePath}.new";
await GlobalFileSemaphore.WaitAsync().ConfigureAwait(false);

View file

@ -104,7 +104,7 @@ namespace ArchiSteamFarm.IPC {
if (!string.IsNullOrEmpty(json)) {
JObject jObject = JObject.Parse(json);
ASF.ArchiLogger.LogGenericDebug(SharedInfo.IPCConfigFile + ": " + jObject.ToString(Formatting.Indented));
ASF.ArchiLogger.LogGenericDebug($"{SharedInfo.IPCConfigFile}: {jObject.ToString(Formatting.Indented)}");
}
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);

View file

@ -271,7 +271,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
}
if ((request.Type == ASF.EUserInputType.None) || !Enum.IsDefined(typeof(ASF.EUserInputType), request.Type) || string.IsNullOrEmpty(request.Value)) {
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(request.Type) + " || " + nameof(request.Value))));
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, $"{nameof(request.Type)} || {nameof(request.Value)}")));
}
HashSet<Bot>? bots = Bot.GetBots(botNames);

View file

@ -60,7 +60,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
}
if (!HttpContext.WebSockets.IsWebSocketRequest) {
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError!, nameof(HttpContext.WebSockets.IsWebSocketRequest) + ": " + HttpContext.WebSockets.IsWebSocketRequest)));
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError!, $"{nameof(HttpContext.WebSockets.IsWebSocketRequest)}: {HttpContext.WebSockets.IsWebSocketRequest}")));
}
// From now on we can return only EmptyResult as the response stream is already being used by existing websocket connection

View file

@ -175,7 +175,7 @@ namespace ArchiSteamFarm.IPC {
options.DisplayRequestDuration();
options.EnableDeepLinking();
options.ShowExtensions();
options.SwaggerEndpoint(SharedInfo.ASF + "/swagger.json", SharedInfo.ASF + " API");
options.SwaggerEndpoint($"{SharedInfo.ASF}/swagger.json", $"{SharedInfo.ASF} API");
}
);
}
@ -202,7 +202,7 @@ namespace ArchiSteamFarm.IPC {
if ((addressParts.Length != 2) || !IPAddress.TryParse(addressParts[0], out IPAddress? ipAddress) || !byte.TryParse(addressParts[1], out byte prefixLength)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(knownNetworkText)));
ASF.ArchiLogger.LogGenericDebug(nameof(knownNetworkText) + ": " + knownNetworkText);
ASF.ArchiLogger.LogGenericDebug($"{nameof(knownNetworkText)}: {knownNetworkText}");
continue;
}
@ -245,7 +245,7 @@ namespace ArchiSteamFarm.IPC {
options => {
options.AddSecurityDefinition(
nameof(GlobalConfig.IPCPassword), new OpenApiSecurityScheme {
Description = nameof(GlobalConfig.IPCPassword) + " authentication using request headers. Check " + SharedInfo.ProjectURL + "/wiki/IPC#authentication for more info.",
Description = $"{nameof(GlobalConfig.IPCPassword)} authentication using request headers. Check {SharedInfo.ProjectURL}/wiki/IPC#authentication for more info.",
In = ParameterLocation.Header,
Name = ApiAuthenticationMiddleware.HeadersField,
Type = SecuritySchemeType.ApiKey
@ -285,7 +285,7 @@ namespace ArchiSteamFarm.IPC {
Url = new Uri(SharedInfo.LicenseURL)
},
Title = SharedInfo.ASF + " API"
Title = $"{SharedInfo.ASF} API"
}
);

View file

@ -37,7 +37,7 @@ namespace ArchiSteamFarm.IPC {
throw new ArgumentNullException(nameof(type));
}
return type.GenericTypeArguments.Length == 0 ? type.FullName : type.Namespace + "." + type.Name + string.Join("", type.GenericTypeArguments.Select(innerType => '[' + innerType.GetUnifiedName() + ']'));
return type.GenericTypeArguments.Length == 0 ? type.FullName : $"{type.Namespace}.{type.Name}{string.Join("", type.GenericTypeArguments.Select(innerType => $"[{innerType.GetUnifiedName()}]"))}";
}
internal static Type? ParseType(string typeText) {
@ -58,7 +58,7 @@ namespace ArchiSteamFarm.IPC {
return null;
}
return Type.GetType(typeText + "," + typeText[..index]);
return Type.GetType($"{typeText},{typeText[..index]}");
}
internal static async Task WriteJsonAsync<TValue>(this HttpResponse response, TValue? value, JsonSerializerSettings? jsonSerializerSettings = null) {

View file

@ -138,16 +138,16 @@ namespace ArchiSteamFarm.NLog {
}
if (((chatGroupID == 0) || (chatID == 0)) && (steamID == 0)) {
throw new InvalidOperationException("((" + nameof(chatGroupID) + " || " + nameof(chatID) + ") && " + nameof(steamID) + ")");
throw new InvalidOperationException($"(({nameof(chatGroupID)} || {nameof(chatID)}) && {nameof(steamID)})");
}
StringBuilder loggedMessage = new(previousMethodName + "() " + message + " " + (echo ? "->" : "<-") + " ");
StringBuilder loggedMessage = new($"{previousMethodName}() {message} {(echo ? "->" : "<-")} ");
if ((chatGroupID != 0) && (chatID != 0)) {
loggedMessage.Append(chatGroupID + "-" + chatID);
loggedMessage.Append($"{chatGroupID}-{chatID}");
if (steamID != 0) {
loggedMessage.Append("/" + steamID);
loggedMessage.Append($"/{steamID}");
}
} else if (steamID != 0) {
loggedMessage.Append(steamID);
@ -225,7 +225,7 @@ namespace ArchiSteamFarm.NLog {
ulong steamID64 = steamID;
string loggedMessage = previousMethodName + "() " + steamID.AccountType + " " + steamID64 + (handled.HasValue ? " = " + handled.Value : "");
string loggedMessage = $"{previousMethodName}() {steamID.AccountType} {steamID64}{(handled.HasValue ? $" = {handled.Value}" : "")}";
LogEventInfo logEventInfo = new(LogLevel.Trace, Logger.Name, loggedMessage) {
Properties = {

View file

@ -322,7 +322,7 @@ namespace ArchiSteamFarm.NLog {
OnUserInputStart();
try {
Console.Write(@">> " + Strings.EnterCommand);
Console.Write($@">> {Strings.EnterCommand}");
string? command = ConsoleReadLine();
if (string.IsNullOrEmpty(command)) {
@ -347,12 +347,12 @@ namespace ArchiSteamFarm.NLog {
Bot? targetBot = Bot.Bots?.OrderBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value).FirstOrDefault();
if (targetBot == null) {
Console.WriteLine(@"<< " + Strings.ErrorNoBotsDefined);
Console.WriteLine($@"<< {Strings.ErrorNoBotsDefined}");
continue;
}
Console.WriteLine(@"<> " + Strings.Executing);
Console.WriteLine($@"<> {Strings.Executing}");
ulong steamOwnerID = ASF.GlobalConfig?.SteamOwnerID ?? GlobalConfig.DefaultSteamOwnerID;
@ -365,7 +365,7 @@ namespace ArchiSteamFarm.NLog {
continue;
}
Console.WriteLine(@"<< " + response);
Console.WriteLine($@"<< {response}");
} finally {
OnUserInputEnd();
}

View file

@ -254,7 +254,7 @@ namespace ArchiSteamFarm {
}
if (globalConfig.Debug) {
ASF.ArchiLogger.LogGenericDebug(globalConfigFile + ": " + JsonConvert.SerializeObject(globalConfig, Formatting.Indented));
ASF.ArchiLogger.LogGenericDebug($"{globalConfigFile}: {JsonConvert.SerializeObject(globalConfig, Formatting.Indented)}");
}
if (!string.IsNullOrEmpty(globalConfig.CurrentCulture)) {
@ -333,7 +333,7 @@ namespace ArchiSteamFarm {
if (currentStringObjects.Count < defaultStringObjects.Count) {
float translationCompleteness = currentStringObjects.Count / (float) defaultStringObjects.Count;
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.TranslationIncomplete, CultureInfo.CurrentUICulture.Name + " (" + CultureInfo.CurrentUICulture.EnglishName + ")", translationCompleteness.ToString("P1", CultureInfo.CurrentCulture)));
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.TranslationIncomplete, $"{CultureInfo.CurrentUICulture.Name} ({CultureInfo.CurrentUICulture.EnglishName})", translationCompleteness.ToString("P1", CultureInfo.CurrentCulture)));
}
return true;
@ -367,7 +367,7 @@ namespace ArchiSteamFarm {
// If debugging is on, we prepare debug directory prior to running
if (Debugging.IsUserDebugging) {
if (Debugging.IsDebugConfigured) {
ASF.ArchiLogger.LogGenericDebug(globalDatabaseFile + ": " + JsonConvert.SerializeObject(ASF.GlobalDatabase, Formatting.Indented));
ASF.ArchiLogger.LogGenericDebug($"{globalDatabaseFile}: {JsonConvert.SerializeObject(ASF.GlobalDatabase, Formatting.Indented)}");
}
Logging.EnableTraceLogging();

View file

@ -83,7 +83,7 @@ namespace ArchiSteamFarm {
}
}
internal static string ProgramIdentifier => PublicIdentifier + " V" + Version + " (" + BuildInfo.Variant + "/" + ModuleVersion + " | " + OS.Version + ")";
internal static string ProgramIdentifier => $"{PublicIdentifier} V{Version} ({BuildInfo.Variant}/{ModuleVersion} | {OS.Version})";
internal static string PublicIdentifier => AssemblyName + (BuildInfo.IsCustomBuild ? "-custom" : PluginsCore.HasCustomPluginsLoaded ? "-modded" : "");
internal static Version Version => Assembly.GetExecutingAssembly().GetName().Version ?? throw new InvalidOperationException(nameof(Version));

View file

@ -568,7 +568,7 @@ namespace ArchiSteamFarm.Steam {
}
if (itemsPerSet < itemsPerClassID.Count) {
throw new InvalidOperationException(nameof(inventory) + " && " + nameof(amountsToExtract));
throw new InvalidOperationException($"{nameof(inventory)} && {nameof(amountsToExtract)}");
}
if (itemsPerSet > itemsPerClassID.Count) {
@ -985,7 +985,7 @@ namespace ArchiSteamFarm.Steam {
throw new ArgumentNullException(nameof(botName));
}
return Environment.NewLine + "<" + botName + "> " + response;
return $"{Environment.NewLine}<{botName}> {response}";
}
internal async Task<(uint PlayableAppID, DateTime IgnoredUntil, bool IgnoredGlobally)> GetAppDataForIdling(uint appID, float hoursPlayed, bool allowRecursiveDiscovery = true, bool optimisticDiscovery = true) {
@ -1495,7 +1495,7 @@ namespace ArchiSteamFarm.Steam {
}
if (Debugging.IsDebugConfigured) {
ASF.ArchiLogger.LogGenericDebug(configFilePath + ": " + JsonConvert.SerializeObject(botConfig, Formatting.Indented));
ASF.ArchiLogger.LogGenericDebug($"{configFilePath}: {JsonConvert.SerializeObject(botConfig, Formatting.Indented)}");
}
if (!string.IsNullOrEmpty(latestJson)) {
@ -1524,7 +1524,7 @@ namespace ArchiSteamFarm.Steam {
}
if (Debugging.IsDebugConfigured) {
ASF.ArchiLogger.LogGenericDebug(databaseFilePath + ": " + JsonConvert.SerializeObject(botDatabase, Formatting.Indented));
ASF.ArchiLogger.LogGenericDebug($"{databaseFilePath}: {JsonConvert.SerializeObject(botDatabase, Formatting.Indented)}");
}
Bot bot;
@ -2138,7 +2138,7 @@ namespace ArchiSteamFarm.Steam {
private static async Task LimitLoginRequestsAsync() {
if ((ASF.LoginSemaphore == null) || (ASF.LoginRateLimitingSemaphore == null)) {
ASF.ArchiLogger.LogNullError(nameof(ASF.LoginSemaphore) + " || " + nameof(ASF.LoginRateLimitingSemaphore));
ASF.ArchiLogger.LogNullError($"{nameof(ASF.LoginSemaphore)} || {nameof(ASF.LoginRateLimitingSemaphore)}");
return;
}
@ -2476,7 +2476,7 @@ namespace ArchiSteamFarm.Steam {
}
if ((notification.chat_group_id == 0) || (notification.chat_id == 0) || (notification.steamid_sender == 0)) {
ArchiLogger.LogNullError(nameof(notification.chat_group_id) + " || " + nameof(notification.chat_id) + " || " + nameof(notification.steamid_sender));
ArchiLogger.LogNullError($"{nameof(notification.chat_group_id)} || {nameof(notification.chat_id)} || {nameof(notification.steamid_sender)}");
return;
}
@ -2716,7 +2716,7 @@ namespace ArchiSteamFarm.Steam {
AccountFlags = callback.AccountFlags;
SteamID = callback.ClientSteamID ?? throw new InvalidOperationException(nameof(callback.ClientSteamID));
ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotLoggedOn, SteamID + (!string.IsNullOrEmpty(callback.VanityURL) ? "/" + callback.VanityURL : "")));
ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotLoggedOn, SteamID + (!string.IsNullOrEmpty(callback.VanityURL) ? $"/{callback.VanityURL}" : "")));
// Old status for these doesn't matter, we'll update them if needed
InvalidPasswordFailures = TwoFactorCodeFailures = 0;
@ -3091,7 +3091,7 @@ namespace ArchiSteamFarm.Steam {
PastNotifications.TryRemove(notification, out _);
}
ArchiLogger.LogGenericTrace(notification + " = " + count);
ArchiLogger.LogGenericTrace($"{notification} = {count}");
switch (notification) {
case UserNotificationsCallback.EUserNotification.Gifts when newNotification && BotConfig.AcceptGifts:
@ -3151,7 +3151,7 @@ namespace ArchiSteamFarm.Steam {
(string? key, string? name) = BotDatabase.GetGameToRedeemInBackground();
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(name)) {
ArchiLogger.LogNullError(nameof(key) + " || " + nameof(name));
ArchiLogger.LogNullError($"{nameof(key)} || {nameof(name)}");
break;
}
@ -3177,7 +3177,7 @@ namespace ArchiSteamFarm.Steam {
}
}
ArchiLogger.LogGenericDebug(result.Items?.Count > 0 ? string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, result.Result + "/" + result.PurchaseResultDetail, string.Join(", ", result.Items)) : string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, result.Result + "/" + result.PurchaseResultDetail));
ArchiLogger.LogGenericDebug(result.Items?.Count > 0 ? string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, $"{result.Result}/{result.PurchaseResultDetail}", string.Join(", ", result.Items)) : string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, $"{result.Result}/{result.PurchaseResultDetail}"));
bool rateLimited = false;
bool redeemed = false;
@ -3219,7 +3219,7 @@ namespace ArchiSteamFarm.Steam {
name = string.Join(", ", result.Items.Values);
}
string logEntry = name + DefaultBackgroundKeysRedeemerSeparator + "[" + result.PurchaseResultDetail + "]" + (result.Items?.Count > 0 ? DefaultBackgroundKeysRedeemerSeparator + string.Join(", ", result.Items) : "") + DefaultBackgroundKeysRedeemerSeparator + key;
string logEntry = $"{name}{DefaultBackgroundKeysRedeemerSeparator}[{result.PurchaseResultDetail}]{(result.Items?.Count > 0 ? DefaultBackgroundKeysRedeemerSeparator + string.Join(", ", result.Items) : "")}{DefaultBackgroundKeysRedeemerSeparator}{key}";
string filePath = GetFilePath(redeemed ? EFileType.KeysToRedeemUsed : EFileType.KeysToRedeemUnused);

View file

@ -541,14 +541,14 @@ namespace ArchiSteamFarm.Steam.Exchange {
if (tradeOffer.OtherSteamID64 != 0) {
// Always accept trades from SteamMasterID
if (Bot.HasAccess(tradeOffer.OtherSteamID64, BotConfig.EAccess.Master)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Accepted, nameof(tradeOffer.OtherSteamID64) + " " + tradeOffer.OtherSteamID64 + ": " + BotConfig.EAccess.Master));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Accepted, $"{nameof(tradeOffer.OtherSteamID64)} {tradeOffer.OtherSteamID64}: {BotConfig.EAccess.Master}"));
return ParseTradeResult.EResult.Accepted;
}
// Always deny trades from blacklisted steamIDs
if (Bot.IsBlacklistedFromTrades(tradeOffer.OtherSteamID64)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Blacklisted, nameof(tradeOffer.OtherSteamID64) + " " + tradeOffer.OtherSteamID64));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Blacklisted, $"{nameof(tradeOffer.OtherSteamID64)} {tradeOffer.OtherSteamID64}"));
return ParseTradeResult.EResult.Blacklisted;
}
@ -558,7 +558,7 @@ namespace ArchiSteamFarm.Steam.Exchange {
switch (tradeOffer.ItemsToGive.Count) {
case 0 when tradeOffer.ItemsToReceive.Count == 0:
// If it's steam issue, try again later
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.TryAgain, nameof(tradeOffer.ItemsToReceive.Count) + " = 0"));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.TryAgain, $"{nameof(tradeOffer.ItemsToReceive.Count)} = 0"));
return ParseTradeResult.EResult.TryAgain;
case 0:
@ -569,13 +569,13 @@ namespace ArchiSteamFarm.Steam.Exchange {
switch (acceptDonations) {
case true when acceptBotTrades:
// If we accept donations and bot trades, accept it right away
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Accepted, nameof(acceptDonations) + " = " + true + " && " + nameof(acceptBotTrades) + " = " + true));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Accepted, $"{nameof(acceptDonations)} = {true} && {nameof(acceptBotTrades)} = {true}"));
return ParseTradeResult.EResult.Accepted;
case false when !acceptBotTrades:
// If we don't accept donations, neither bot trades, deny it right away
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, nameof(acceptDonations) + " = " + false + " && " + nameof(acceptBotTrades) + " = " + false));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(acceptDonations)} = {false} && {nameof(acceptBotTrades)} = {false}"));
return ParseTradeResult.EResult.Rejected;
}
@ -585,28 +585,28 @@ namespace ArchiSteamFarm.Steam.Exchange {
ParseTradeResult.EResult result = (acceptDonations && !isBotTrade) || (acceptBotTrades && isBotTrade) ? ParseTradeResult.EResult.Accepted : ParseTradeResult.EResult.Rejected;
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, result, nameof(acceptDonations) + " = " + acceptDonations + " && " + nameof(acceptBotTrades) + " = " + acceptBotTrades + " && " + nameof(isBotTrade) + " = " + isBotTrade));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, result, $"{nameof(acceptDonations)} = {acceptDonations} && {nameof(acceptBotTrades)} = {acceptBotTrades} && {nameof(isBotTrade)} = {isBotTrade}"));
return result;
}
// If we don't have SteamTradeMatcher enabled, this is the end for us
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, nameof(BotConfig.ETradingPreferences.SteamTradeMatcher) + " = " + false));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(BotConfig.ETradingPreferences.SteamTradeMatcher)} = {false}"));
return ParseTradeResult.EResult.Rejected;
}
// Decline trade if we're giving more count-wise, this is a very naive pre-check, it'll be strengthened in more detailed fair types exchange next
if (tradeOffer.ItemsToGive.Count > tradeOffer.ItemsToReceive.Count) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, nameof(tradeOffer.ItemsToGive.Count) + ": " + tradeOffer.ItemsToGive.Count + " > " + tradeOffer.ItemsToReceive.Count));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(tradeOffer.ItemsToGive.Count)}: {tradeOffer.ItemsToGive.Count} > {tradeOffer.ItemsToReceive.Count}"));
return ParseTradeResult.EResult.Rejected;
}
// Decline trade if we're requested to handle any not-accepted item type or if it's not fair games/types exchange
if (!tradeOffer.IsValidSteamItemsRequest(Bot.BotConfig.MatchableTypes) || !IsFairExchange(tradeOffer.ItemsToGive, tradeOffer.ItemsToReceive)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, nameof(tradeOffer.IsValidSteamItemsRequest) + " || " + nameof(IsFairExchange)));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(tradeOffer.IsValidSteamItemsRequest)} || {nameof(IsFairExchange)}"));
return ParseTradeResult.EResult.Rejected;
}
@ -626,7 +626,7 @@ namespace ArchiSteamFarm.Steam.Exchange {
// If user has a trade hold, we add extra logic
// If trade hold duration exceeds our max, or user asks for cards with short lifespan, reject the trade
case > 0 when (holdDuration.Value > ASF.GlobalConfig.MaxTradeHoldDuration) || tradeOffer.ItemsToGive.Any(item => item.Type is Asset.EType.FoilTradingCard or Asset.EType.TradingCard && CardsFarmer.SalesBlacklist.Contains(item.RealAppID)):
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, nameof(holdDuration) + " > 0: " + holdDuration.Value));
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(holdDuration)} > 0: {holdDuration.Value}"));
return ParseTradeResult.EResult.Rejected;
}

View file

@ -121,7 +121,7 @@ namespace ArchiSteamFarm.Steam.Integration {
}
}
return string.IsNullOrEmpty(VanityURL) ? "/profiles/" + Bot.SteamID : "/id/" + VanityURL;
return string.IsNullOrEmpty(VanityURL) ? $"/profiles/{Bot.SteamID}" : $"/id/{VanityURL}";
}
[PublicAPI]
@ -165,7 +165,7 @@ namespace ArchiSteamFarm.Steam.Integration {
await ASF.InventorySemaphore.WaitAsync().ConfigureAwait(false);
try {
Uri request = new(SteamCommunityURL, "/inventory/" + steamID + "/" + appID + "/" + contextID + "?count=" + MaxItemsInSingleInventoryRequest + "&l=english" + (startAssetID > 0 ? "&start_assetid=" + startAssetID : ""));
Uri request = new(SteamCommunityURL, $"/inventory/{steamID}/{appID}/{contextID}?count={MaxItemsInSingleInventoryRequest}&l=english{(startAssetID > 0 ? $"&start_assetid={startAssetID}" : "")}");
ObjectResponse<InventoryResponse>? response = await UrlGetToJsonObjectWithSession<InventoryResponse>(request).ConfigureAwait(false);
@ -185,7 +185,7 @@ namespace ArchiSteamFarm.Steam.Integration {
assetIDs ??= new HashSet<ulong>((int) response.Content.TotalInventoryCount);
if ((response.Content.Assets.Count == 0) || (response.Content.Descriptions.Count == 0)) {
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, nameof(response.Content.Assets) + " || " + nameof(response.Content.Descriptions)));
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, $"{nameof(response.Content.Assets)} || {nameof(response.Content.Descriptions)}"));
}
Dictionary<(ulong ClassID, ulong InstanceID), InventoryResponse.Description> descriptions = new();
@ -326,7 +326,7 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(groupID));
}
Uri request = new(SteamCommunityURL, "/gid/" + groupID);
Uri request = new(SteamCommunityURL, $"/gid/{groupID}");
// Extra entry for sessionID
Dictionary<string, string> data = new(2, StringComparer.Ordinal) { { "action", "join" } };
@ -341,7 +341,7 @@ namespace ArchiSteamFarm.Steam.Integration {
}
if (((itemsToGive == null) || (itemsToGive.Count == 0)) && ((itemsToReceive == null) || (itemsToReceive.Count == 0))) {
throw new ArgumentException(nameof(itemsToGive) + " && " + nameof(itemsToReceive));
throw new ArgumentException($"{nameof(itemsToGive)} && {nameof(itemsToReceive)}");
}
if (itemsPerTrade <= 2) {
@ -389,7 +389,7 @@ namespace ArchiSteamFarm.Steam.Integration {
{ "partner", steamID.ToString(CultureInfo.InvariantCulture) },
{ "serverid", "1" },
{ "trade_offer_create_params", !string.IsNullOrEmpty(token) ? new JObject { { "trade_offer_access_token", token } }.ToString(Formatting.None) : "" },
{ "tradeoffermessage", "Sent by " + SharedInfo.PublicIdentifier + "/" + SharedInfo.Version }
{ "tradeoffermessage", $"Sent by {SharedInfo.PublicIdentifier}/{SharedInfo.Version}" }
};
HashSet<ulong> mobileTradeOfferIDs = new();
@ -1259,8 +1259,8 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(tradeID));
}
Uri request = new(SteamCommunityURL, "/tradeoffer/" + tradeID + "/accept");
Uri referer = new(SteamCommunityURL, "/tradeoffer/" + tradeID);
Uri request = new(SteamCommunityURL, $"/tradeoffer/{tradeID}/accept");
Uri referer = new(SteamCommunityURL, $"/tradeoffer/{tradeID}");
// Extra entry for sessionID
Dictionary<string, string> data = new(3, StringComparer.Ordinal) {
@ -1353,7 +1353,7 @@ namespace ArchiSteamFarm.Steam.Integration {
return false;
}
Uri request = new(SteamCommunityURL, profileURL + "/ajaxsetprivacy");
Uri request = new(SteamCommunityURL, $"{profileURL}/ajaxsetprivacy");
// Extra entry for sessionID
Dictionary<string, string> data = new(3, StringComparer.Ordinal) {
@ -1381,7 +1381,7 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(appID));
}
Uri request = new(SteamStoreURL, "/app/" + appID);
Uri request = new(SteamStoreURL, $"/app/{appID}");
// Extra entry for sessionID
Dictionary<string, string> data = new(2, StringComparer.Ordinal) { { "appid_to_clear_from_queue", appID.ToString(CultureInfo.InvariantCulture) } };
@ -1680,7 +1680,7 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(page));
}
Uri request = new(SteamCommunityURL, "/my/badges?l=english&p=" + page);
Uri request = new(SteamCommunityURL, $"/my/badges?l=english&p={page}");
HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);
@ -1746,7 +1746,7 @@ namespace ArchiSteamFarm.Steam.Integration {
}
}
Uri request = new(SteamCommunityURL, "/mobileconf/conf?a=" + Bot.SteamID + "&k=" + WebUtility.UrlEncode(confirmationHash) + "&l=english&m=android&p=" + WebUtility.UrlEncode(deviceID) + "&t=" + time + "&tag=conf");
Uri request = new(SteamCommunityURL, $"/mobileconf/conf?a={Bot.SteamID}&k={WebUtility.UrlEncode(confirmationHash)}&l=english&m=android&p={WebUtility.UrlEncode(deviceID)}&t={time}&tag=conf");
HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request).ConfigureAwait(false);
@ -1837,7 +1837,7 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(appID));
}
Uri request = new(SteamCommunityURL, "/my/gamecards/" + appID + "?l=english");
Uri request = new(SteamCommunityURL, $"/my/gamecards/{appID}?l=english");
HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);
@ -1888,7 +1888,7 @@ namespace ArchiSteamFarm.Steam.Integration {
throw new ArgumentOutOfRangeException(nameof(tradeID));
}
Uri request = new(SteamCommunityURL, "/tradeoffer/" + tradeID + "?l=english");
Uri request = new(SteamCommunityURL, $"/tradeoffer/{tradeID}?l=english");
using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request).ConfigureAwait(false);
@ -2035,7 +2035,7 @@ namespace ArchiSteamFarm.Steam.Integration {
}
}
Uri request = new(SteamCommunityURL, "/mobileconf/ajaxop?a=" + Bot.SteamID + "&cid=" + confirmationID + "&ck=" + confirmationKey + "&k=" + WebUtility.UrlEncode(confirmationHash) + "&l=english&m=android&op=" + (accept ? "allow" : "cancel") + "&p=" + WebUtility.UrlEncode(deviceID) + "&t=" + time + "&tag=conf");
Uri request = new(SteamCommunityURL, $"/mobileconf/ajaxop?a={Bot.SteamID}&cid={confirmationID}&ck={confirmationKey}&k={WebUtility.UrlEncode(confirmationHash)}&l=english&m=android&op={(accept ? "allow" : "cancel")}&p={WebUtility.UrlEncode(deviceID)}&t={time}&tag=conf");
ObjectResponse<BooleanResponse>? response = await UrlGetToJsonObjectWithSession<BooleanResponse>(request).ConfigureAwait(false);
@ -2187,24 +2187,24 @@ namespace ArchiSteamFarm.Steam.Integration {
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(steamID.ToString(CultureInfo.InvariantCulture)));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamCommunityURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamHelpURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamStoreURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamStoreURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamCommunityURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamHelpURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamStoreURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamStoreURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamCommunityURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamHelpURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamStoreURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamStoreURL.Host}"));
// Report proper time when doing timezone-based calculations, see setTimezoneCookies() from https://steamcommunity-a.akamaihd.net/public/shared/javascript/shared_global.js
string timeZoneOffset = DateTimeOffset.Now.Offset.TotalSeconds + WebUtility.UrlEncode(",") + "0";
string timeZoneOffset = $"{DateTimeOffset.Now.Offset.TotalSeconds}{WebUtility.UrlEncode(",")}0";
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", "." + SteamCommunityURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", "." + SteamHelpURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", "." + SteamStoreURL.Host));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamStoreURL.Host}"));
Bot.ArchiLogger.LogGenericInfo(Strings.Success);
@ -2323,7 +2323,7 @@ namespace ArchiSteamFarm.Steam.Integration {
return false;
}
Uri request = new(SteamCommunityURL, profileURL + "/ajaxunpackbooster");
Uri request = new(SteamCommunityURL, $"{profileURL}/ajaxunpackbooster");
// Extra entry for sessionID
Dictionary<string, string> data = new(3, StringComparer.Ordinal) {
@ -2605,7 +2605,7 @@ namespace ArchiSteamFarm.Steam.Integration {
Dictionary<string, string> data = new(4, StringComparer.Ordinal) {
{ "agreeToTerms", "agreed" },
#pragma warning disable CA1308 // False positive, we're intentionally converting this part to lowercase and it's not used for any security decisions based on the result of the normalization
{ "domain", "generated.by." + SharedInfo.AssemblyName.ToLowerInvariant() + ".localhost" },
{ "domain", $"generated.by.{SharedInfo.AssemblyName.ToLowerInvariant()}.localhost" },
#pragma warning restore CA1308 // False positive, we're intentionally converting this part to lowercase and it's not used for any security decisions based on the result of the normalization
{ "Submit", "Register" }
};

View file

@ -252,7 +252,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
[PublicAPI]
public static (bool Success, string Message) Restart() {
if (!Program.RestartAllowed) {
return (false, "!" + nameof(Program.RestartAllowed));
return (false, $"!{nameof(Program.RestartAllowed)}");
}
// Schedule the task after some time so user can receive response
@ -418,7 +418,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
if (SharedInfo.Version >= version) {
return (false, "V" + SharedInfo.Version + " ≥ V" + version, version);
return (false, $"V{SharedInfo.Version} ≥ V{version}", version);
}
Utilities.InBackground(ASF.RestartOrExit);

View file

@ -62,7 +62,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
throw new ArgumentNullException(nameof(botName));
}
return Environment.NewLine + "<" + botName + "> " + response;
return $"{Environment.NewLine}<{botName}> {response}";
}
[PublicAPI]
@ -71,7 +71,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
throw new ArgumentNullException(nameof(response));
}
return "<" + Bot.BotName + "> " + response;
return $"<{Bot.BotName}> {response}";
}
[PublicAPI]
@ -80,7 +80,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
throw new ArgumentNullException(nameof(response));
}
return "<" + SharedInfo.ASF + "> " + response;
return $"<{SharedInfo.ASF}> {response}";
}
[PublicAPI]
@ -638,18 +638,18 @@ namespace ArchiSteamFarm.Steam.Interaction {
callback = await Bot.SteamApps.RequestFreeLicense(gameID).ToLongRunningTask().ConfigureAwait(false);
} catch (Exception e) {
Bot.ArchiLogger.LogGenericWarningException(e);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, "app/" + gameID, EResult.Timeout)));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, $"app/{gameID}", EResult.Timeout)));
break;
}
response.AppendLine(FormatBotResponse((callback.GrantedApps.Count > 0) || (callback.GrantedPackages.Count > 0) ? string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicenseWithItems, "app/" + gameID, callback.Result, string.Join(", ", callback.GrantedApps.Select(appID => "app/" + appID).Union(callback.GrantedPackages.Select(subID => "sub/" + subID)))) : string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, "app/" + gameID, callback.Result)));
response.AppendLine(FormatBotResponse((callback.GrantedApps.Count > 0) || (callback.GrantedPackages.Count > 0) ? string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicenseWithItems, $"app/{gameID}", callback.Result, string.Join(", ", callback.GrantedApps.Select(appID => $"app/{appID}").Union(callback.GrantedPackages.Select(subID => $"sub/{subID}")))) : string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, $"app/{gameID}", callback.Result)));
break;
default:
(EResult result, EPurchaseResultDetail purchaseResult) = await Bot.ArchiWebHandler.AddFreeLicense(gameID).ConfigureAwait(false);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, "sub/" + gameID, result + "/" + purchaseResult)));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, $"sub/{gameID}", $"{result}/{purchaseResult}")));
break;
}
@ -1276,7 +1276,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
throw new ArgumentOutOfRangeException(nameof(steamID));
}
return Bot.HasAccess(steamID, BotConfig.EAccess.FamilySharing) ? FormatBotResponse(SharedInfo.ProjectURL + "/wiki/Commands") : null;
return Bot.HasAccess(steamID, BotConfig.EAccess.FamilySharing) ? FormatBotResponse($"{SharedInfo.ProjectURL}/wiki/Commands") : null;
}
private string? ResponseIdleBlacklist(ulong steamID) {
@ -2081,11 +2081,11 @@ namespace ArchiSteamFarm.Steam.Interaction {
if (packageIDs?.Count > 0) {
if ((gamesOwned != null) && gamesOwned.TryGetValue(appID, out string? cachedGameName)) {
result["app/" + appID] = cachedGameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, "app/" + appID, cachedGameName)));
result[$"app/{appID}"] = cachedGameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, $"app/{appID}", cachedGameName)));
} else {
result["app/" + appID] = appID.ToString(CultureInfo.InvariantCulture);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlready, "app/" + appID)));
result[$"app/{appID}"] = appID.ToString(CultureInfo.InvariantCulture);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlready, $"app/{appID}")));
}
} else {
if (gamesOwned == null) {
@ -2099,10 +2099,10 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
if (gamesOwned.TryGetValue(appID, out string? gameName)) {
result["app/" + appID] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, "app/" + appID, gameName)));
result[$"app/{appID}"] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, $"app/{appID}", gameName)));
} else {
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotNotOwnedYet, "app/" + appID)));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotNotOwnedYet, $"app/{appID}")));
}
}
@ -2135,8 +2135,8 @@ namespace ArchiSteamFarm.Steam.Interaction {
foreach ((uint appID, string gameName) in gamesOwned.Where(gameOwned => regex.IsMatch(gameOwned.Value))) {
foundWithRegex = true;
result["app/" + appID] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, "app/" + appID, gameName)));
result[$"app/{appID}"] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, $"app/{appID}", gameName)));
}
if (!foundWithRegex) {
@ -2147,10 +2147,10 @@ namespace ArchiSteamFarm.Steam.Interaction {
case "S" when uint.TryParse(game, out uint packageID) && (packageID > 0):
case "SUB" when uint.TryParse(game, out packageID) && (packageID > 0):
if (Bot.OwnedPackageIDs.ContainsKey(packageID)) {
result["sub/" + packageID] = packageID.ToString(CultureInfo.InvariantCulture);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlready, "sub/" + packageID)));
result[$"sub/{packageID}"] = packageID.ToString(CultureInfo.InvariantCulture);
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlready, $"sub/{packageID}")));
} else {
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotNotOwnedYet, "sub/" + packageID)));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotNotOwnedYet, $"sub/{packageID}")));
}
break;
@ -2170,8 +2170,8 @@ namespace ArchiSteamFarm.Steam.Interaction {
foreach ((uint appID, string gameName) in gamesOwned.Where(gameOwned => gameOwned.Value.Contains(game, StringComparison.OrdinalIgnoreCase))) {
foundWithName = true;
result["app/" + appID] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, "app/" + appID, gameName)));
result[$"app/{appID}"] = gameName;
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnedAlreadyWithName, $"app/{appID}", gameName)));
}
if (!foundWithName) {
@ -2228,7 +2228,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
ownedGamesStats[gameID] = ownedGameStats;
}
IEnumerable<string> extraResponses = ownedGamesStats.Select(kv => FormatStaticResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnsOverviewPerGame, kv.Value.Count, validResults.Count, kv.Key + (!string.IsNullOrEmpty(kv.Value.GameName) ? " | " + kv.Value.GameName : ""))));
IEnumerable<string> extraResponses = ownedGamesStats.Select(kv => FormatStaticResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnsOverviewPerGame, kv.Value.Count, validResults.Count, kv.Key + (!string.IsNullOrEmpty(kv.Value.GameName) ? $" | {kv.Value.GameName}" : ""))));
return string.Join(Environment.NewLine, validResults.Select(result => result.Response).Concat(extraResponses));
}
@ -2382,7 +2382,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
if (gamesToPlay.Count >= ArchiHandler.MaxGamesPlayedConcurrently) {
return FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(gamesToPlay) + " > " + ArchiHandler.MaxGamesPlayedConcurrently));
return FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(gamesToPlay)} > {ArchiHandler.MaxGamesPlayedConcurrently}"));
}
gamesToPlay.Add(gameID);
@ -2721,9 +2721,9 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
if (result.Items?.Count > 0) {
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, result.Result + "/" + result.PurchaseResultDetail, string.Join(", ", result.Items)), currentBot.BotName));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, $"{result.Result}/{result.PurchaseResultDetail}", string.Join(", ", result.Items)), currentBot.BotName));
} else if (!skipRequest) {
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, result.Result + "/" + result.PurchaseResultDetail), currentBot.BotName));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, $"{result.Result}/{result.PurchaseResultDetail}"), currentBot.BotName));
}
switch (result.PurchaseResultDetail) {
@ -2774,7 +2774,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
PurchaseResponseCallback? otherResult = await innerBot.Actions.RedeemKey(key!).ConfigureAwait(false);
if (otherResult == null) {
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, EResult.Timeout + "/" + EPurchaseResultDetail.Timeout), innerBot.BotName));
response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, $"{EResult.Timeout}/{EPurchaseResultDetail.Timeout}"), innerBot.BotName));
continue;
}
@ -2798,7 +2798,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
break;
}
response.AppendLine(FormatBotResponse(otherResult.Items?.Count > 0 ? string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, otherResult.Result + "/" + otherResult.PurchaseResultDetail, string.Join(", ", otherResult.Items)) : string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, otherResult.Result + "/" + otherResult.PurchaseResultDetail), innerBot.BotName));
response.AppendLine(FormatBotResponse(otherResult.Items?.Count > 0 ? string.Format(CultureInfo.CurrentCulture, Strings.BotRedeemWithItems, key, $"{otherResult.Result}/{otherResult.PurchaseResultDetail}", string.Join(", ", otherResult.Items)) : string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, $"{otherResult.Result}/{otherResult.PurchaseResultDetail}"), innerBot.BotName));
if (alreadyHandled) {
break;
@ -3061,7 +3061,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
if (Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Count > 1) {
return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdlingList, string.Join(", ", Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Select(game => game.AppID + " (" + game.GameName + ")")), Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot);
return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdlingList, string.Join(", ", Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Select(game => $"{game.AppID} ({game.GameName})")), Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot);
}
Game soloGame = Bot.CardsFarmer.CurrentGamesFarmingReadOnly.First();
@ -3410,7 +3410,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
(bool success, string? message, Version? version) = await Actions.Update().ConfigureAwait(false);
return FormatStaticResponse((success ? Strings.Success : Strings.WarningFailed) + (!string.IsNullOrEmpty(message) ? " " + message : version != null ? " " + version : ""));
return FormatStaticResponse((success ? Strings.Success : Strings.WarningFailed) + (!string.IsNullOrEmpty(message) ? $" {message}" : version != null ? $" {version}" : ""));
}
private string? ResponseVersion(ulong steamID) {

View file

@ -461,7 +461,7 @@ namespace ArchiSteamFarm.Steam.Storage {
}
if (GamesPlayedWhileIdle.Count > ArchiHandler.MaxGamesPlayedConcurrently) {
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), nameof(GamesPlayedWhileIdle.Count) + " " + GamesPlayedWhileIdle.Count + " > " + ArchiHandler.MaxGamesPlayedConcurrently));
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), $"{nameof(GamesPlayedWhileIdle.Count)} {GamesPlayedWhileIdle.Count} > {ArchiHandler.MaxGamesPlayedConcurrently}"));
}
foreach (Asset.EType lootableType in LootableTypes.Where(lootableType => !Enum.IsDefined(typeof(Asset.EType), lootableType))) {

View file

@ -56,7 +56,7 @@ namespace ArchiSteamFarm.Web {
throw new ArgumentNullException(nameof(version));
}
Uri request = new(SharedInfo.GithubReleaseURL + "/tags/" + version);
Uri request = new($"{SharedInfo.GithubReleaseURL}/tags/{version}");
return await GetReleaseFromURL(request).ConfigureAwait(false);
}
@ -70,7 +70,7 @@ namespace ArchiSteamFarm.Web {
throw new InvalidOperationException(nameof(ASF.WebBrowser));
}
Uri request = new(SharedInfo.ProjectURL + "/wiki/" + page + "/_history");
Uri request = new($"{SharedInfo.ProjectURL}/wiki/{page}/_history");
using HtmlDocumentResponse? response = await ASF.WebBrowser.UrlGetToHtmlDocument(request, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
@ -143,7 +143,7 @@ namespace ArchiSteamFarm.Web {
throw new InvalidOperationException(nameof(ASF.WebBrowser));
}
Uri request = new(SharedInfo.ProjectURL + "/wiki/" + page + (!string.IsNullOrEmpty(revision) ? "/" + revision : ""));
Uri request = new($"{SharedInfo.ProjectURL}/wiki/{page}{(!string.IsNullOrEmpty(revision) ? $"/{revision}" : "")}");
using HtmlDocumentResponse? response = await ASF.WebBrowser.UrlGetToHtmlDocument(request).ConfigureAwait(false);

View file

@ -113,7 +113,7 @@ namespace ArchiSteamFarm.Web {
// Most web services expect that UserAgent is set, so we declare it globally
// If you by any chance came here with a very "clever" idea of hiding your ass by changing default ASF user-agent then here is a very good advice from me: don't, for your own safety - you've been warned
result.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(SharedInfo.PublicIdentifier, SharedInfo.Version.ToString()));
result.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("(" + SharedInfo.BuildInfo.Variant + "; " + OS.Version.Replace("(", "", StringComparison.Ordinal).Replace(")", "", StringComparison.Ordinal) + "; +" + SharedInfo.ProjectURL + ")"));
result.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue($"({SharedInfo.BuildInfo.Variant}; {OS.Version.Replace("(", "", StringComparison.Ordinal).Replace(")", "", StringComparison.Ordinal)}; +{SharedInfo.ProjectURL})"));
return result;
}
@ -785,7 +785,7 @@ namespace ArchiSteamFarm.Web {
try {
requestMessage.Content = new FormUrlEncodedContent(nameValueCollection);
} catch (UriFormatException) {
requestMessage.Content = new StringContent(string.Join("&", nameValueCollection.Select(kv => WebUtility.UrlEncode(kv.Key) + "=" + WebUtility.UrlEncode(kv.Value))), null, "application/x-www-form-urlencoded");
requestMessage.Content = new StringContent(string.Join("&", nameValueCollection.Select(kv => $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}")), null, "application/x-www-form-urlencoded");
}
break;
@ -805,7 +805,7 @@ namespace ArchiSteamFarm.Web {
}
if (Debugging.IsUserDebugging) {
ArchiLogger.LogGenericDebug(httpMethod + " " + request);
ArchiLogger.LogGenericDebug($"{httpMethod} {request}");
}
try {
@ -823,7 +823,7 @@ namespace ArchiSteamFarm.Web {
}
if (Debugging.IsUserDebugging) {
ArchiLogger.LogGenericDebug(response.StatusCode + " <- " + httpMethod + " " + request);
ArchiLogger.LogGenericDebug($"{response.StatusCode} <- {httpMethod} {request}");
}
if (response.IsSuccessStatusCode) {
@ -883,7 +883,7 @@ namespace ArchiSteamFarm.Web {
}
if (!Debugging.IsUserDebugging) {
ArchiLogger.LogGenericDebug(response.StatusCode + " <- " + httpMethod + " " + request);
ArchiLogger.LogGenericDebug($"{response.StatusCode} <- {httpMethod} {request}");
}
if (response.StatusCode.IsClientErrorCode()) {