* Start working on nullable checks

help me

* Update GlobalConfig.cs

* Finish initial fixup round

* nullability code review
This commit is contained in:
Łukasz Domeradzki
2020-08-22 21:41:01 +02:00
committed by GitHub
parent e5f64ec9dd
commit 9fc1ea65a5
91 changed files with 1996 additions and 2808 deletions

View File

@@ -27,13 +27,11 @@ using System.Linq;
using System.Threading.Tasks;
using ArchiSteamFarm.Collections;
using ArchiSteamFarm.Helpers;
using JetBrains.Annotations;
using Newtonsoft.Json;
using SteamKit2;
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal sealed class GlobalCache : SerializableFile {
[NotNull]
private static string SharedFilePath => Path.Combine(ArchiSteamFarm.SharedInfo.ConfigDirectory, nameof(SteamTokenDumper) + ".cache");
[JsonProperty(Required = Required.DisallowNull)]
@@ -64,22 +62,16 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal ulong GetAppToken(uint appID) => AppTokens[appID];
[NotNull]
internal Dictionary<uint, ulong> GetAppTokensForSubmission() => AppTokens.Where(appToken => !SubmittedAppIDs.Contains(appToken.Key)).ToDictionary(appToken => appToken.Key, appToken => appToken.Value);
[NotNull]
internal Dictionary<uint, string> GetDepotKeysForSubmission() => DepotKeys.Where(depotKey => !SubmittedDepotIDs.Contains(depotKey.Key)).ToDictionary(depotKey => depotKey.Key, depotKey => depotKey.Value);
[NotNull]
internal Dictionary<uint, ulong> GetPackageTokensForSubmission() => PackageTokens.Where(packageToken => !SubmittedPackageIDs.Contains(packageToken.Key)).ToDictionary(packageToken => packageToken.Key, packageToken => packageToken.Value);
[ItemNotNull]
internal static async Task<GlobalCache> Load() {
if (!File.Exists(SharedFilePath)) {
return new GlobalCache();
}
GlobalCache globalCache = null;
GlobalCache? globalCache = null;
try {
string json = await RuntimeCompatibility.File.ReadAllTextAsync(SharedFilePath).ConfigureAwait(false);
@@ -100,7 +92,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
return globalCache;
}
internal async Task OnPICSChanges(uint currentChangeNumber, [NotNull] IReadOnlyCollection<KeyValuePair<uint, SteamApps.PICSChangesCallback.PICSChangeData>> appChanges) {
internal async Task OnPICSChanges(uint currentChangeNumber, IReadOnlyCollection<KeyValuePair<uint, SteamApps.PICSChangesCallback.PICSChangeData>> appChanges) {
if ((currentChangeNumber == 0) || (appChanges == null)) {
throw new ArgumentNullException(nameof(appChanges));
}
@@ -127,7 +119,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal async Task OnPICSChangesRestart(uint currentChangeNumber) {
if (currentChangeNumber == 0) {
throw new ArgumentNullException();
throw new ArgumentNullException(nameof(currentChangeNumber));
}
if (currentChangeNumber <= LastChangeNumber) {
@@ -146,7 +138,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal bool ShouldRefreshAppInfo(uint appID) => !AppChangeNumbers.ContainsKey(appID);
internal bool ShouldRefreshDepotKey(uint depotID) => !DepotKeys.ContainsKey(depotID);
internal async Task UpdateAppChangeNumbers([NotNull] IReadOnlyCollection<KeyValuePair<uint, uint>> appChangeNumbers) {
internal async Task UpdateAppChangeNumbers(IReadOnlyCollection<KeyValuePair<uint, uint>> appChangeNumbers) {
if (appChangeNumbers == null) {
throw new ArgumentNullException(nameof(appChangeNumbers));
}
@@ -167,7 +159,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
}
internal async Task UpdateAppTokens([NotNull] IReadOnlyCollection<KeyValuePair<uint, ulong>> appTokens, [NotNull] IReadOnlyCollection<uint> publicAppIDs) {
internal async Task UpdateAppTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> appTokens, IReadOnlyCollection<uint> publicAppIDs) {
if ((appTokens == null) || (publicAppIDs == null)) {
throw new ArgumentNullException(nameof(appTokens) + " || " + nameof(publicAppIDs));
}
@@ -207,7 +199,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
}
internal async Task UpdateDepotKeys([NotNull] ICollection<SteamApps.DepotKeyCallback> depotKeyResults) {
internal async Task UpdateDepotKeys(ICollection<SteamApps.DepotKeyCallback> depotKeyResults) {
if (depotKeyResults == null) {
throw new ArgumentNullException(nameof(depotKeyResults));
}
@@ -221,7 +213,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
string depotKey = BitConverter.ToString(depotKeyResult.DepotKey).Replace("-", "");
if (DepotKeys.TryGetValue(depotKeyResult.DepotID, out string previousDepotKey) && (previousDepotKey == depotKey)) {
if (DepotKeys.TryGetValue(depotKeyResult.DepotID, out string? previousDepotKey) && (previousDepotKey == depotKey)) {
continue;
}
@@ -240,7 +232,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
}
internal async Task UpdatePackageTokens([NotNull] IReadOnlyCollection<KeyValuePair<uint, ulong>> packageTokens) {
internal async Task UpdatePackageTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> packageTokens) {
if (packageTokens == null) {
throw new ArgumentNullException(nameof(packageTokens));
}
@@ -267,7 +259,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
}
internal async Task UpdateSubmittedData([NotNull] IReadOnlyCollection<uint> appIDs, [NotNull] IReadOnlyCollection<uint> packageIDs, [NotNull] IReadOnlyCollection<uint> depotIDs) {
internal async Task UpdateSubmittedData(IReadOnlyCollection<uint> appIDs, IReadOnlyCollection<uint> packageIDs, IReadOnlyCollection<uint> depotIDs) {
if ((appIDs == null) || (packageIDs == null) || (depotIDs == null)) {
throw new ArgumentNullException(nameof(appIDs) + " || " + nameof(packageIDs) + " || " + nameof(depotIDs));
}

View File

@@ -22,7 +22,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using JetBrains.Annotations;
using Newtonsoft.Json;
using SteamKit2;
@@ -40,7 +39,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
#pragma warning disable IDE0052
[JsonProperty(PropertyName = "guid", Required = Required.Always)]
private readonly string Guid = ASF.GlobalDatabase.Guid.ToString("N");
private readonly string Guid = ASF.GlobalDatabase?.Guid.ToString("N") ?? throw new ArgumentNullException(nameof(ASF.GlobalDatabase.Guid));
#pragma warning restore IDE0052
private readonly ulong SteamID;
@@ -62,11 +61,10 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
#pragma warning disable IDE0051
[JsonProperty(PropertyName = "steamid", Required = Required.Always)]
[NotNull]
private string SteamIDText => new SteamID(SteamID).Render();
#pragma warning restore IDE0051
internal RequestData(ulong steamID, [NotNull] IEnumerable<KeyValuePair<uint, ulong>> apps, [NotNull] IEnumerable<KeyValuePair<uint, ulong>> accessTokens, [NotNull] IEnumerable<KeyValuePair<uint, string>> depots) {
internal RequestData(ulong steamID, IEnumerable<KeyValuePair<uint, ulong>> apps, IEnumerable<KeyValuePair<uint, ulong>> accessTokens, IEnumerable<KeyValuePair<uint, string>> depots) {
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount || (apps == null) || (accessTokens == null) || (depots == null)) {
throw new ArgumentNullException(nameof(steamID) + " || " + nameof(apps) + " || " + nameof(accessTokens) + " || " + nameof(depots));
}

View File

@@ -27,7 +27,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
internal sealed class ResponseData {
#pragma warning disable 649
[JsonProperty(PropertyName = "data", Required = Required.Always)]
internal readonly InternalData Data;
internal readonly InternalData? Data;
#pragma warning restore 649
#pragma warning disable 649

View File

@@ -29,21 +29,19 @@ using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Plugins;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SteamKit2;
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
[Export(typeof(IPlugin))]
[UsedImplicitly]
internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotSteamClient, ISteamPICSChanges {
private static readonly ConcurrentDictionary<Bot, IDisposable> BotSubscriptions = new ConcurrentDictionary<Bot, IDisposable>();
private static readonly ConcurrentDictionary<Bot, (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer)> BotSynchronizations = new ConcurrentDictionary<Bot, (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer)>();
private static readonly SemaphoreSlim SubmissionSemaphore = new SemaphoreSlim(1, 1);
private static readonly Timer SubmissionTimer = new Timer(async e => await SubmitData().ConfigureAwait(false));
private static GlobalCache GlobalCache;
private static GlobalCache? GlobalCache;
[JsonProperty]
private static bool IsEnabled;
@@ -56,7 +54,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
public Task<uint> GetPreferredChangeNumberToStartFrom() => Task.FromResult(IsEnabled ? GlobalCache?.LastChangeNumber ?? 0 : 0);
public void OnASFInit(IReadOnlyDictionary<string, JToken> additionalConfigProperties = null) {
public void OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
if (!SharedInfo.HasValidToken) {
ASF.ArchiLogger.LogGenericError($"{Name} has been disabled due to missing build token.");
@@ -103,7 +101,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
throw new ArgumentNullException(nameof(bot));
}
if (BotSubscriptions.TryRemove(bot, out IDisposable subscription)) {
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
subscription.Dispose();
}
@@ -138,7 +136,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
throw new ArgumentNullException(nameof(bot) + " || " + nameof(callbackManager));
}
if (BotSubscriptions.TryRemove(bot, out IDisposable subscription)) {
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
subscription.Dispose();
}
@@ -153,7 +151,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
}
public IReadOnlyCollection<ClientMsgHandler> OnBotSteamHandlersInit(Bot bot) => null;
public IReadOnlyCollection<ClientMsgHandler>? OnBotSteamHandlersInit(Bot bot) => null;
public override void OnLoaded() { }
@@ -189,7 +187,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
await GlobalCache.OnPICSChangesRestart(currentChangeNumber).ConfigureAwait(false);
}
private static async void OnLicenseList([NotNull] Bot bot, [NotNull] SteamApps.LicenseListCallback callback) {
private static async void OnLicenseList(Bot bot, SteamApps.LicenseListCallback callback) {
if ((bot == null) || (callback == null)) {
throw new ArgumentNullException(nameof(callback));
}
@@ -208,7 +206,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
await Refresh(bot, packageTokens.Keys).ConfigureAwait(false);
}
private static async Task Refresh([NotNull] Bot bot, IReadOnlyCollection<uint> packageIDs = null) {
private static async Task Refresh(Bot bot, IReadOnlyCollection<uint>? packageIDs = null) {
if (bot == null) {
throw new ArgumentNullException(nameof(bot));
}
@@ -217,8 +215,8 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
return;
}
if (GlobalCache == null) {
throw new ArgumentNullException(nameof(GlobalCache));
if ((GlobalCache == null) || (ASF.GlobalDatabase == null)) {
throw new ArgumentNullException(nameof(GlobalCache) + " || " + nameof(ASF.GlobalDatabase));
}
if (!BotSynchronizations.TryGetValue(bot, out (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer) synchronization)) {
@@ -239,7 +237,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
HashSet<uint> appIDsToRefresh = new HashSet<uint>();
foreach (uint packageID in packageIDs) {
if (!ASF.GlobalDatabase.PackagesDataReadOnly.TryGetValue(packageID, out (uint ChangeNumber, HashSet<uint> AppIDs) packageData) || (packageData.AppIDs == null)) {
if (!ASF.GlobalDatabase.PackagesDataReadOnly.TryGetValue(packageID, out (uint ChangeNumber, HashSet<uint>? AppIDs) packageData) || (packageData.AppIDs == null)) {
// ASF might not have the package info for us at the moment, we'll retry later
continue;
}
@@ -388,14 +386,18 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
}
private static async Task SubmitData() {
if (Bot.Bots == null) {
throw new ArgumentNullException(nameof(Bot.Bots));
}
const string request = SharedInfo.ServerURL + "/submit";
if (!IsEnabled) {
return;
}
if (GlobalCache == null) {
throw new ArgumentNullException(nameof(GlobalCache));
if ((ASF.GlobalConfig == null) || (ASF.WebBrowser == null) || (GlobalCache == null)) {
throw new ArgumentNullException(nameof(ASF.GlobalConfig) + " || " + nameof(ASF.WebBrowser) + " || " + nameof(GlobalCache));
}
if (!await SubmissionSemaphore.WaitAsync(0).ConfigureAwait(false)) {
@@ -415,7 +417,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
return;
}
ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.BotsReadOnly.Values.Where(bot => bot.SteamID > 0).OrderByDescending(bot => bot.OwnedPackageIDsReadOnly.Count).FirstOrDefault()?.SteamID ?? 0;
ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(bot => bot.SteamID > 0).OrderByDescending(bot => bot.OwnedPackageIDsReadOnly.Count).FirstOrDefault()?.SteamID ?? 0;
if (contributorSteamID == 0) {
ASF.ArchiLogger.LogGenericError($"Skipped {nameof(SubmitData)} trigger because there is no valid steamID we could classify as a contributor. Consider setting up {nameof(ASF.GlobalConfig.SteamOwnerID)} property.");
@@ -427,9 +429,9 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
ASF.ArchiLogger.LogGenericInfo($"Submitting registered apps/subs/depots: {appTokens.Count}/{packageTokens.Count}/{depotKeys.Count}...");
WebBrowser.ObjectResponse<ResponseData> response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
WebBrowser.ObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
if ((response?.Content == null) || response.StatusCode.IsClientErrorCode()) {
if ((response?.Content?.Data == null) || response.StatusCode.IsClientErrorCode()) {
ASF.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
#if NETFRAMEWORK