Switch to proper OrderedDictionary

This commit is contained in:
JustArchi
2018-02-26 08:53:14 +01:00
parent 56259fd197
commit 4a5665c92b
3 changed files with 60 additions and 38 deletions

View File

@@ -20,8 +20,10 @@
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
@@ -659,7 +661,7 @@ namespace ArchiSteamFarm {
}
try {
SortedDictionary<string, string> gamesToRedeemInBackground = new SortedDictionary<string, string>();
OrderedDictionary gamesToRedeemInBackground = new OrderedDictionary();
using (StreamReader reader = new StreamReader(filePath)) {
string line;
@@ -1159,35 +1161,43 @@ namespace ArchiSteamFarm {
}
}
internal async Task ValidateAndAddGamesToRedeemInBackground(SortedDictionary<string, string> gamesToRedeemInBackground) {
internal async Task ValidateAndAddGamesToRedeemInBackground(OrderedDictionary gamesToRedeemInBackground) {
if ((gamesToRedeemInBackground == null) || (gamesToRedeemInBackground.Count == 0)) {
ArchiLogger.LogNullError(nameof(gamesToRedeemInBackground));
return;
}
HashSet<string> invalidGames = new HashSet<string>();
HashSet<object> invalidKeys = new HashSet<object>();
foreach (KeyValuePair<string, string> game in gamesToRedeemInBackground) {
foreach (DictionaryEntry game in gamesToRedeemInBackground) {
bool invalid = false;
if (!IsValidCdKey(game.Key)) {
string key = game.Key as string;
if (string.IsNullOrEmpty(key)) {
invalid = true;
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, game.Key));
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, nameof(key)));
} else if (!IsValidCdKey(key)) {
invalid = true;
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, key));
}
if (string.IsNullOrEmpty(game.Value)) {
string name = game.Value as string;
if (string.IsNullOrEmpty(name)) {
invalid = true;
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, game.Value));
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, nameof(name)));
} else if (string.IsNullOrEmpty(name)) {
invalid = true;
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsInvalid, name));
}
if (invalid) {
invalidGames.Add(game.Key);
invalidKeys.Add(game.Key);
}
}
if (invalidGames.Count > 0) {
foreach (string invalidGame in invalidGames) {
gamesToRedeemInBackground.Remove(invalidGame);
if (invalidKeys.Count > 0) {
foreach (string invalidKey in invalidKeys) {
gamesToRedeemInBackground.Remove(invalidKey);
}
if (gamesToRedeemInBackground.Count == 0) {
@@ -2323,9 +2333,9 @@ namespace ArchiSteamFarm {
}
while (IsConnectedAndLoggedOn && BotDatabase.HasGamesToRedeemInBackground) {
KeyValuePair<string, string> game = BotDatabase.GetGameToRedeemInBackground();
if (string.IsNullOrEmpty(game.Key) || string.IsNullOrEmpty(game.Value)) {
ArchiLogger.LogNullError(nameof(game.Key) + " || " + nameof(game.Value));
(string Key, string Name) game = BotDatabase.GetGameToRedeemInBackground();
if (string.IsNullOrEmpty(game.Key) || string.IsNullOrEmpty(game.Name)) {
ArchiLogger.LogNullError(nameof(game.Key) + " || " + nameof(game.Name));
break;
}
@@ -2379,10 +2389,10 @@ namespace ArchiSteamFarm {
if (shouldKeep) {
try {
await File.AppendAllTextAsync(KeysToRedeemAlreadyOwnedFilePath, game.Value + "\t" + game.Key + " (" + result.PurchaseResultDetail + ")" + Environment.NewLine).ConfigureAwait(false);
await File.AppendAllTextAsync(KeysToRedeemAlreadyOwnedFilePath, game.Name + "\t" + game.Key + " [" + result.PurchaseResultDetail + "]" + Environment.NewLine).ConfigureAwait(false);
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
await BotDatabase.AddGameToRedeemInBackground(game.Key, game.Value).ConfigureAwait(false); // Failsafe
await BotDatabase.AddGameToRedeemInBackground(game.Key, game.Name).ConfigureAwait(false); // Failsafe
break;
}
}

View File

@@ -20,9 +20,10 @@
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
@@ -43,7 +44,7 @@ namespace ArchiSteamFarm {
private readonly SemaphoreSlim FileSemaphore = new SemaphoreSlim(1, 1);
[JsonProperty(Required = Required.DisallowNull)]
private readonly SortedDictionary<string, string> GamesToRedeemInBackground = new SortedDictionary<string, string>();
private readonly OrderedDictionary GamesToRedeemInBackground = new OrderedDictionary();
[JsonProperty(Required = Required.DisallowNull)]
private readonly ConcurrentHashSet<uint> IdlingBlacklistedAppIDs = new ConcurrentHashSet<uint>();
@@ -86,17 +87,23 @@ namespace ArchiSteamFarm {
}
}
internal async Task AddGamesToRedeemInBackground(IReadOnlyDictionary<string, string> games) {
internal async Task AddGamesToRedeemInBackground(OrderedDictionary games) {
if ((games == null) || (games.Count == 0)) {
ASF.ArchiLogger.LogNullError(nameof(games));
return;
}
bool save;
bool save = false;
lock (GamesToRedeemInBackground) {
// We use Count() and not Any() because we must ensure full loop pass
save = games.Count(game => GamesToRedeemInBackground.TryAdd(game.Key, game.Value)) > 0;
foreach (DictionaryEntry game in games) {
if (GamesToRedeemInBackground.Contains(game.Key)) {
continue;
}
GamesToRedeemInBackground.Add(game.Key, game.Value);
save = true;
}
}
if (save) {
@@ -110,15 +117,15 @@ namespace ArchiSteamFarm {
return;
}
bool save;
lock (GamesToRedeemInBackground) {
save = GamesToRedeemInBackground.TryAdd(key, game);
if (!GamesToRedeemInBackground.Contains(key)) {
return;
}
GamesToRedeemInBackground.Remove(key);
}
if (save) {
await Save().ConfigureAwait(false);
}
await Save().ConfigureAwait(false);
}
internal async Task AddIdlingBlacklistedAppIDs(IReadOnlyCollection<uint> appIDs) {
@@ -156,10 +163,14 @@ namespace ArchiSteamFarm {
internal IReadOnlyCollection<ulong> GetBlacklistedFromTradesSteamIDs() => BlacklistedFromTradesSteamIDs;
internal KeyValuePair<string, string> GetGameToRedeemInBackground() {
internal (string Key, string Name) GetGameToRedeemInBackground() {
lock (GamesToRedeemInBackground) {
return GamesToRedeemInBackground.FirstOrDefault();
foreach (DictionaryEntry game in GamesToRedeemInBackground) {
return (game.Key as string, game.Value as string);
}
}
return (null, null);
}
internal IReadOnlyCollection<uint> GetIdlingBlacklistedAppIDs() => IdlingBlacklistedAppIDs;
@@ -258,15 +269,15 @@ namespace ArchiSteamFarm {
return;
}
bool save;
lock (GamesToRedeemInBackground) {
save = GamesToRedeemInBackground.Remove(key, out _);
if (!GamesToRedeemInBackground.Contains(key)) {
return;
}
GamesToRedeemInBackground.Remove(key);
}
if (save) {
await Save().ConfigureAwait(false);
}
await Save().ConfigureAwait(false);
}
internal async Task RemoveIdlingBlacklistedAppIDs(IReadOnlyCollection<uint> appIDs) {

View File

@@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
@@ -1046,7 +1047,7 @@ namespace ArchiSteamFarm {
private sealed class GamesToRedeemInBackgroundRequest {
#pragma warning disable 649
[JsonProperty(Required = Required.Always)]
internal readonly SortedDictionary<string, string> GamesToRedeemInBackground;
internal readonly OrderedDictionary GamesToRedeemInBackground;
#pragma warning restore 649
// Deserialized from JSON