diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj
index 082c0bdb4..608bf5866 100644
--- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj
+++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj
@@ -27,6 +27,7 @@
+
diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatAPI.cs b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatAPI.cs
index a352c9d16..f38109b16 100644
--- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatAPI.cs
+++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatAPI.cs
@@ -22,6 +22,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
@@ -31,7 +32,8 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
internal static class CatAPI {
private const string URL = "https://aws.random.cat";
- internal static async Task GetRandomCatURL(WebBrowser webBrowser) {
+ [ItemCanBeNull]
+ internal static async Task GetRandomCatURL([NotNull] WebBrowser webBrowser) {
const string request = URL + "/meow";
WebBrowser.ObjectResponse response = await webBrowser.UrlGetToJsonObject(request).ConfigureAwait(false);
diff --git a/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj b/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
index 5611453bf..083dc5825 100644
--- a/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
+++ b/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
@@ -28,6 +28,7 @@
+
diff --git a/ArchiSteamFarm.Tests/Trading.cs b/ArchiSteamFarm.Tests/Trading.cs
index f28b9c831..89a1d224f 100644
--- a/ArchiSteamFarm.Tests/Trading.cs
+++ b/ArchiSteamFarm.Tests/Trading.cs
@@ -23,6 +23,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using ArchiSteamFarm.Json;
+using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ArchiSteamFarm.Tests {
@@ -318,6 +319,7 @@ namespace ArchiSteamFarm.Tests {
return (bool) method.Invoke(null, new object[] { inventory, itemsToGive, itemsToReceive });
}
+ [NotNull]
private static Steam.Asset CreateItem(ulong classID, uint amount = 1, uint realAppID = Steam.Asset.SteamAppID, Steam.Asset.EType type = Steam.Asset.EType.TradingCard) => new Steam.Asset(Steam.Asset.SteamAppID, Steam.Asset.SteamCommunityContextID, classID, amount, realAppID, type);
}
}
diff --git a/ArchiSteamFarm/ASF.cs b/ArchiSteamFarm/ASF.cs
index 2fa3e37fa..785cb2284 100644
--- a/ArchiSteamFarm/ASF.cs
+++ b/ArchiSteamFarm/ASF.cs
@@ -95,6 +95,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
internal static async Task Update(bool updateOverride = false) {
if (!SharedInfo.BuildInfo.CanUpdate || (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.None)) {
return null;
@@ -243,13 +244,6 @@ namespace ArchiSteamFarm {
}
StringComparer botsComparer = await Core.GetBotsComparer().ConfigureAwait(false);
-
- if (botsComparer == null) {
- ArchiLogger.LogNullError(nameof(botsComparer));
-
- return;
- }
-
Bot.Init(botsComparer);
// Ensure that we ask for a list of servers if we don't have any saved servers available
diff --git a/ArchiSteamFarm/Access.cs b/ArchiSteamFarm/Access.cs
index e245f380e..fe799d8df 100644
--- a/ArchiSteamFarm/Access.cs
+++ b/ArchiSteamFarm/Access.cs
@@ -29,7 +29,7 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
- internal Access(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
+ internal Access([NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
[PublicAPI]
public bool IsFamilySharing(ulong steamID) {
diff --git a/ArchiSteamFarm/Actions.cs b/ArchiSteamFarm/Actions.cs
index 2280531d2..9ce33607a 100644
--- a/ArchiSteamFarm/Actions.cs
+++ b/ArchiSteamFarm/Actions.cs
@@ -46,7 +46,7 @@ namespace ArchiSteamFarm {
private bool ProcessingGiftsScheduled;
private bool TradingScheduled;
- internal Actions(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
+ internal Actions([NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
public void Dispose() {
// Those are objects that are always being created if constructor doesn't throw exception
@@ -363,6 +363,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemNotNull]
internal async Task GetTradingLock() {
await TradingSemaphore.WaitAsync().ConfigureAwait(false);
diff --git a/ArchiSteamFarm/ArchiHandler.cs b/ArchiSteamFarm/ArchiHandler.cs
index aeb1f5e99..8497cdb34 100644
--- a/ArchiSteamFarm/ArchiHandler.cs
+++ b/ArchiSteamFarm/ArchiHandler.cs
@@ -47,7 +47,7 @@ namespace ArchiSteamFarm {
internal DateTime LastPacketReceived { get; private set; }
- internal ArchiHandler(ArchiLogger archiLogger, SteamUnifiedMessages steamUnifiedMessages) {
+ internal ArchiHandler([NotNull] ArchiLogger archiLogger, [NotNull] SteamUnifiedMessages steamUnifiedMessages) {
if ((archiLogger == null) || (steamUnifiedMessages == null)) {
throw new ArgumentNullException(nameof(archiLogger) + " || " + nameof(steamUnifiedMessages));
}
@@ -674,7 +674,7 @@ namespace ArchiSteamFarm {
public EPurchaseResultDetail PurchaseResultDetail { get; internal set; }
public EResult Result { get; internal set; }
- internal PurchaseResponseCallback(JobID jobID, CMsgClientPurchaseResponse msg) {
+ internal PurchaseResponseCallback([NotNull] JobID jobID, [NotNull] CMsgClientPurchaseResponse msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -740,7 +740,7 @@ namespace ArchiSteamFarm {
internal sealed class PlayingSessionStateCallback : CallbackMsg {
internal readonly bool PlayingBlocked;
- internal PlayingSessionStateCallback(JobID jobID, CMsgClientPlayingSessionState msg) {
+ internal PlayingSessionStateCallback([NotNull] JobID jobID, [NotNull] CMsgClientPlayingSessionState msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -753,7 +753,7 @@ namespace ArchiSteamFarm {
internal sealed class RedeemGuestPassResponseCallback : CallbackMsg {
internal readonly EResult Result;
- internal RedeemGuestPassResponseCallback(JobID jobID, CMsgClientRedeemGuestPassResponse msg) {
+ internal RedeemGuestPassResponseCallback([NotNull] JobID jobID, [NotNull] CMsgClientRedeemGuestPassResponse msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -766,7 +766,7 @@ namespace ArchiSteamFarm {
internal sealed class SharedLibraryLockStatusCallback : CallbackMsg {
internal readonly ulong LibraryLockedBySteamID;
- internal SharedLibraryLockStatusCallback(JobID jobID, CMsgClientSharedLibraryLockStatus msg) {
+ internal SharedLibraryLockStatusCallback([NotNull] JobID jobID, [NotNull] CMsgClientSharedLibraryLockStatus msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -784,7 +784,7 @@ namespace ArchiSteamFarm {
internal sealed class UserNotificationsCallback : CallbackMsg {
internal readonly Dictionary Notifications;
- internal UserNotificationsCallback(JobID jobID, CMsgClientUserNotifications msg) {
+ internal UserNotificationsCallback([NotNull] JobID jobID, [NotNull] CMsgClientUserNotifications msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -824,7 +824,7 @@ namespace ArchiSteamFarm {
}
}
- internal UserNotificationsCallback(JobID jobID, CMsgClientItemAnnouncements msg) {
+ internal UserNotificationsCallback([NotNull] JobID jobID, [NotNull] CMsgClientItemAnnouncements msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
@@ -853,7 +853,7 @@ namespace ArchiSteamFarm {
internal sealed class VanityURLChangedCallback : CallbackMsg {
internal readonly string VanityURL;
- internal VanityURLChangedCallback(JobID jobID, CMsgClientVanityURLChangedNotification msg) {
+ internal VanityURLChangedCallback([NotNull] JobID jobID, [NotNull] CMsgClientVanityURLChangedNotification msg) {
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs
index b67d1e442..e8f35d2a5 100644
--- a/ArchiSteamFarm/ArchiWebHandler.cs
+++ b/ArchiSteamFarm/ArchiWebHandler.cs
@@ -83,7 +83,7 @@ namespace ArchiSteamFarm {
private ulong SteamID;
private string VanityURL;
- internal ArchiWebHandler(Bot bot) {
+ internal ArchiWebHandler([NotNull] Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
CachedApiKey = new ArchiCacheable(ResolveApiKey, TimeSpan.FromHours(1));
@@ -98,6 +98,7 @@ namespace ArchiSteamFarm {
WebBrowser.Dispose();
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task GetAbsoluteProfileURL(bool waitForInitialization = true) {
if (waitForInitialization && (SteamID == 0)) {
@@ -1010,8 +1011,10 @@ namespace ArchiSteamFarm {
return true;
}
+ [NotNull]
internal HttpClient GenerateDisposableHttpClient() => WebBrowser.GenerateDisposableHttpClient();
+ [ItemCanBeNull]
internal async Task> GenerateNewDiscoveryQueue() {
const string request = "/explore/generatenewdiscoveryqueue";
@@ -1023,6 +1026,7 @@ namespace ArchiSteamFarm {
return output?.Queue;
}
+ [ItemCanBeNull]
internal async Task> GetActiveTradeOffers() {
(bool success, string steamApiKey) = await CachedApiKey.GetValue().ConfigureAwait(false);
@@ -1159,6 +1163,7 @@ namespace ArchiSteamFarm {
return result;
}
+ [ItemCanBeNull]
internal async Task> GetAppList() {
KeyValue response = null;
@@ -1224,6 +1229,7 @@ namespace ArchiSteamFarm {
return await UrlGetToHtmlDocumentWithSession(SteamCommunityURL, request, false).ConfigureAwait(false);
}
+ [ItemCanBeNull]
internal async Task GetConfirmationDetails(string deviceID, string confirmationHash, uint time, MobileAuthenticator.Confirmation confirmation) {
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0) || (confirmation == null)) {
Bot.ArchiLogger.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time) + " || " + nameof(confirmation));
@@ -1280,6 +1286,7 @@ namespace ArchiSteamFarm {
return await UrlGetToHtmlDocumentWithSession(SteamCommunityURL, request).ConfigureAwait(false);
}
+ [ItemCanBeNull]
internal async Task> GetDigitalGiftCards() {
const string request = "/gifts";
HtmlDocument response = await UrlGetToHtmlDocumentWithSession(SteamStoreURL, request).ConfigureAwait(false);
@@ -1323,6 +1330,7 @@ namespace ArchiSteamFarm {
return await UrlGetToHtmlDocumentWithSession(SteamStoreURL, request).ConfigureAwait(false);
}
+ [ItemCanBeNull]
internal async Task> GetFamilySharingSteamIDs() {
const string request = "/account/managedevices?l=english";
HtmlDocument htmlDocument = await UrlGetToHtmlDocumentWithSession(SteamStoreURL, request).ConfigureAwait(false);
@@ -1367,6 +1375,7 @@ namespace ArchiSteamFarm {
return await UrlGetToHtmlDocumentWithSession(SteamCommunityURL, request, false).ConfigureAwait(false);
}
+ [ItemCanBeNull]
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
internal async Task> GetInventory(ulong steamID = 0, uint appID = Steam.Asset.SteamAppID, uint contextID = Steam.Asset.SteamCommunityContextID, bool? tradable = null, IReadOnlyCollection wantedTypes = null, IReadOnlyCollection wantedRealAppIDs = null, IReadOnlyCollection<(uint AppID, Steam.Asset.EType Type)> wantedSets = null, IReadOnlyCollection<(uint AppID, Steam.Asset.EType Type)> skippedSets = null) {
if ((appID == 0) || (contextID == 0)) {
@@ -1495,6 +1504,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
internal async Task> GetMyOwnedGames() {
const string request = "/my/games?l=english&xml=1";
@@ -1537,6 +1547,7 @@ namespace ArchiSteamFarm {
return result;
}
+ [ItemCanBeNull]
internal async Task> GetOwnedGames(ulong steamID) {
if (steamID == 0) {
Bot.ArchiLogger.LogNullError(nameof(steamID));
diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs
index 71af9dfdf..6a9e2007b 100755
--- a/ArchiSteamFarm/Bot.cs
+++ b/ArchiSteamFarm/Bot.cs
@@ -114,16 +114,32 @@ namespace ArchiSteamFarm {
private readonly SteamUser SteamUser;
private readonly Trading Trading;
+ [NotNull]
private string BotPath => Path.Combine(SharedInfo.ConfigDirectory, BotName);
+
+ [NotNull]
private string ConfigFilePath => BotPath + SharedInfo.ConfigExtension;
+
+ [NotNull]
private string DatabaseFilePath => BotPath + SharedInfo.DatabaseExtension;
+
+ [NotNull]
private string KeysToRedeemFilePath => BotPath + SharedInfo.KeysExtension;
+
+ [NotNull]
private string KeysToRedeemUnusedFilePath => KeysToRedeemFilePath + SharedInfo.KeysUnusedExtension;
+
+ [NotNull]
private string KeysToRedeemUsedFilePath => KeysToRedeemFilePath + SharedInfo.KeysUsedExtension;
+
+ [NotNull]
private string MobileAuthenticatorFilePath => BotPath + SharedInfo.MobileAuthenticatorExtension;
+
+ [NotNull]
private string SentryFilePath => BotPath + SharedInfo.SentryHashExtension;
[JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(SteamID))]
+ [NotNull]
private string SSteamID => SteamID.ToString();
[JsonProperty]
@@ -170,7 +186,7 @@ namespace ArchiSteamFarm {
private string TwoFactorCode;
private byte TwoFactorCodeFailures;
- private Bot(string botName, BotConfig botConfig, BotDatabase botDatabase) {
+ private Bot([NotNull] string botName, [NotNull] BotConfig botConfig, [NotNull] BotDatabase botDatabase) {
if (string.IsNullOrEmpty(botName) || (botConfig == null) || (botDatabase == null)) {
throw new ArgumentNullException(nameof(botName) + " || " + nameof(botConfig) + " || " + nameof(botDatabase));
}
@@ -588,8 +604,10 @@ namespace ArchiSteamFarm {
return result;
}
+ [ItemCanBeNull]
internal async Task> GetMarketableAppIDs() => await ArchiWebHandler.GetAppList().ConfigureAwait(false);
+ [ItemCanBeNull]
internal async Task AppIDs)>> GetPackagesData(IReadOnlyCollection packageIDs) {
if ((packageIDs == null) || (packageIDs.Count == 0)) {
ArchiLogger.LogNullError(nameof(packageIDs));
@@ -1293,6 +1311,7 @@ namespace ArchiSteamFarm {
return message.Replace("\\", "\\\\").Replace("[", "\\[");
}
+ [ItemCanBeNull]
private async Task> GetKeysFromFile(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ArchiLogger.LogNullError(nameof(filePath));
diff --git a/ArchiSteamFarm/BotConfig.cs b/ArchiSteamFarm/BotConfig.cs
index 9a2626a2c..6dab78aef 100644
--- a/ArchiSteamFarm/BotConfig.cs
+++ b/ArchiSteamFarm/BotConfig.cs
@@ -229,6 +229,7 @@ namespace ArchiSteamFarm {
private bool ShouldSerializeSensitiveDetails = true;
[JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(SteamMasterClanID), Required = Required.DisallowNull)]
+ [NotNull]
private string SSteamMasterClanID {
get => SteamMasterClanID.ToString();
@@ -297,6 +298,7 @@ namespace ArchiSteamFarm {
return TradingPreferences <= ETradingPreferences.All ? (true, null) : (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(TradingPreferences), TradingPreferences));
}
+ [ItemCanBeNull]
internal static async Task Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ASF.ArchiLogger.LogNullError(nameof(filePath));
diff --git a/ArchiSteamFarm/BotDatabase.cs b/ArchiSteamFarm/BotDatabase.cs
index 80a4b8359..4a4153e53 100644
--- a/ArchiSteamFarm/BotDatabase.cs
+++ b/ArchiSteamFarm/BotDatabase.cs
@@ -27,6 +27,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Collections;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm {
@@ -63,7 +64,7 @@ namespace ArchiSteamFarm {
private bool ReadOnly;
// This constructor is used when creating new database
- private BotDatabase(string filePath) {
+ private BotDatabase([NotNull] string filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException(nameof(filePath));
}
@@ -137,6 +138,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
internal static async Task CreateOrLoad(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ASF.ArchiLogger.LogNullError(nameof(filePath));
diff --git a/ArchiSteamFarm/CardsFarmer.cs b/ArchiSteamFarm/CardsFarmer.cs
index 64f7fe3cf..4aed6fce9 100755
--- a/ArchiSteamFarm/CardsFarmer.cs
+++ b/ArchiSteamFarm/CardsFarmer.cs
@@ -32,6 +32,7 @@ using System.Threading.Tasks;
using ArchiSteamFarm.Collections;
using ArchiSteamFarm.Localization;
using HtmlAgilityPack;
+using JetBrains.Annotations;
using Newtonsoft.Json;
using SteamKit2;
@@ -80,7 +81,7 @@ namespace ArchiSteamFarm {
private bool PermanentlyPaused;
private bool ShouldResumeFarming = true;
- internal CardsFarmer(Bot bot) {
+ internal CardsFarmer([NotNull] Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
if (Program.GlobalConfig.IdleFarmingPeriod > 0) {
@@ -1004,6 +1005,12 @@ namespace ArchiSteamFarm {
}
private async Task IsPlayableGame(Game game) {
+ if (game == null) {
+ Bot.ArchiLogger.LogNullError(nameof(game));
+
+ return false;
+ }
+
(uint playableAppID, DateTime ignoredUntil) = await Bot.GetAppDataForIdling(game.AppID, game.HoursPlayed).ConfigureAwait(false);
if (playableAppID == 0) {
@@ -1182,7 +1189,7 @@ namespace ArchiSteamFarm {
internal uint PlayableAppID { get; set; }
- internal Game(uint appID, string gameName, float hoursPlayed, ushort cardsRemaining, byte badgeLevel) {
+ internal Game(uint appID, [NotNull] string gameName, float hoursPlayed, ushort cardsRemaining, byte badgeLevel) {
if ((appID == 0) || string.IsNullOrEmpty(gameName) || (hoursPlayed < 0) || (cardsRemaining == 0)) {
throw new ArgumentOutOfRangeException(nameof(appID) + " || " + nameof(gameName) + " || " + nameof(hoursPlayed) + " || " + nameof(cardsRemaining));
}
diff --git a/ArchiSteamFarm/Collections/ConcurrentHashSet.cs b/ArchiSteamFarm/Collections/ConcurrentHashSet.cs
index 0c7f128f1..692f7cc69 100644
--- a/ArchiSteamFarm/Collections/ConcurrentHashSet.cs
+++ b/ArchiSteamFarm/Collections/ConcurrentHashSet.cs
@@ -22,6 +22,7 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using JetBrains.Annotations;
@@ -34,7 +35,10 @@ namespace ArchiSteamFarm.Collections {
public bool Add(T item) => BackingCollection.TryAdd(item, true);
public void Clear() => BackingCollection.Clear();
+
+ [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
public bool Contains(T item) => BackingCollection.ContainsKey(item);
+
public void CopyTo(T[] array, int arrayIndex) => BackingCollection.Keys.CopyTo(array, arrayIndex);
public void ExceptWith(IEnumerable other) {
@@ -83,6 +87,7 @@ namespace ArchiSteamFarm.Collections {
return otherSet.Any(Contains);
}
+ [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
public bool Remove(T item) => BackingCollection.TryRemove(item, out _);
public bool SetEquals(IEnumerable other) {
@@ -111,19 +116,21 @@ namespace ArchiSteamFarm.Collections {
}
}
+ [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
void ICollection.Add(T item) => Add(item);
+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
// We use Count() and not Any() because we must ensure full loop pass
[PublicAPI]
- public bool AddRange(IEnumerable items) => items.Count(Add) > 0;
+ public bool AddRange([NotNull] IEnumerable items) => items.Count(Add) > 0;
// We use Count() and not Any() because we must ensure full loop pass
[PublicAPI]
- public bool RemoveRange(IEnumerable items) => items.Count(Remove) > 0;
+ public bool RemoveRange([NotNull] IEnumerable items) => items.Count(Remove) > 0;
[PublicAPI]
- public bool ReplaceIfNeededWith(IReadOnlyCollection other) {
+ public bool ReplaceIfNeededWith([NotNull] IReadOnlyCollection other) {
if (SetEquals(other)) {
return false;
}
@@ -134,7 +141,7 @@ namespace ArchiSteamFarm.Collections {
}
[PublicAPI]
- public void ReplaceWith(IEnumerable other) {
+ public void ReplaceWith([NotNull] IEnumerable other) {
BackingCollection.Clear();
foreach (T item in other) {
diff --git a/ArchiSteamFarm/Collections/ConcurrentSortedHashSet.cs b/ArchiSteamFarm/Collections/ConcurrentSortedHashSet.cs
index 0c907bcb6..369486071 100644
--- a/ArchiSteamFarm/Collections/ConcurrentSortedHashSet.cs
+++ b/ArchiSteamFarm/Collections/ConcurrentSortedHashSet.cs
@@ -22,7 +22,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Threading;
+using JetBrains.Annotations;
namespace ArchiSteamFarm.Collections {
internal sealed class ConcurrentSortedHashSet : IDisposable, IReadOnlyCollection, ISet {
@@ -197,10 +199,12 @@ namespace ArchiSteamFarm.Collections {
}
}
+ [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
void ICollection.Add(T item) => Add(item);
+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- internal void ReplaceWith(IEnumerable other) {
+ internal void ReplaceWith([NotNull] IEnumerable other) {
CollectionSemaphore.Wait();
try {
@@ -222,7 +226,7 @@ namespace ArchiSteamFarm.Collections {
object IEnumerator.Current => Current;
- internal ConcurrentEnumerator(IReadOnlyCollection collection, SemaphoreSlim semaphore) {
+ internal ConcurrentEnumerator([NotNull] IReadOnlyCollection collection, [NotNull] SemaphoreSlim semaphore) {
if ((collection == null) || (semaphore == null)) {
throw new ArgumentNullException(nameof(collection) + " || " + nameof(semaphore));
}
diff --git a/ArchiSteamFarm/Commands.cs b/ArchiSteamFarm/Commands.cs
index 4e39e2634..95f41790b 100644
--- a/ArchiSteamFarm/Commands.cs
+++ b/ArchiSteamFarm/Commands.cs
@@ -36,7 +36,7 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
private readonly Dictionary CachedGamesOwned = new Dictionary();
- internal Commands(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
+ internal Commands([NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
[PublicAPI]
public static string FormatBotResponse(string response, string botName) {
@@ -398,6 +398,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(!string.IsNullOrEmpty(token) ? string.Format(Strings.BotAuthenticatorToken, token) : Strings.WarningFailed);
}
+ [ItemCanBeNull]
private static async Task Response2FA(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -442,6 +443,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(result ? Strings.Success : Strings.WarningFailed);
}
+ [ItemCanBeNull]
private static async Task Response2FAConfirm(ulong steamID, string botNames, bool confirm) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -543,6 +545,7 @@ namespace ArchiSteamFarm {
return await ResponseAddLicense(steamID, gamesToRedeem).ConfigureAwait(false);
}
+ [ItemCanBeNull]
private static async Task ResponseAddLicense(ulong steamID, string botNames, string targetGameIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetGameIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetGameIDs));
@@ -591,6 +594,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseAdvancedLoot(ulong steamID, string botNames, string appID, string contextID) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(appID) || string.IsNullOrEmpty(contextID)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(appID) + " || " + nameof(contextID));
@@ -673,6 +677,7 @@ namespace ArchiSteamFarm {
return await ResponseRedeem(steamID, keys, redeemFlags).ConfigureAwait(false);
}
+ [ItemCanBeNull]
private static async Task ResponseAdvancedRedeem(ulong steamID, string botNames, string options, string keys) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(options) || string.IsNullOrEmpty(keys)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(options) + " || " + nameof(keys));
@@ -787,6 +792,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(blacklist.Count > 0 ? string.Join(", ", blacklist) : string.Format(Strings.ErrorIsEmpty, nameof(blacklist)));
}
+ [ItemCanBeNull]
private static async Task ResponseBlacklist(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -839,6 +845,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseBlacklistAdd(ulong steamID, string botNames, string targetSteamIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetSteamIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetSteamIDs));
@@ -891,6 +898,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseBlacklistRemove(ulong steamID, string botNames, string targetSteamIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetSteamIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetSteamIDs));
@@ -951,6 +959,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseFarm(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -997,6 +1006,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(idleBlacklist.Count > 0 ? string.Join(", ", idleBlacklist) : string.Format(Strings.ErrorIsEmpty, nameof(idleBlacklist)));
}
+ [ItemCanBeNull]
private static async Task ResponseIdleBlacklist(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1049,6 +1059,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseIdleBlacklistAdd(ulong steamID, string botNames, string targetAppIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetAppIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetAppIDs));
@@ -1101,6 +1112,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseIdleBlacklistRemove(ulong steamID, string botNames, string targetAppIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetAppIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetAppIDs));
@@ -1137,6 +1149,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(idleQueue.Count > 0 ? string.Join(", ", idleQueue) : string.Format(Strings.ErrorIsEmpty, nameof(idleQueue)));
}
+ [ItemCanBeNull]
private static async Task ResponseIdleQueue(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1189,6 +1202,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseIdleQueueAdd(ulong steamID, string botNames, string targetAppIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetAppIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetAppIDs));
@@ -1241,6 +1255,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseIdleQueueRemove(ulong steamID, string botNames, string targetAppIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetAppIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetAppIDs));
@@ -1285,6 +1300,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseInput(ulong steamID, string botNames, string propertyName, string inputValue) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(propertyName) || string.IsNullOrEmpty(inputValue)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(propertyName) + " || " + nameof(inputValue));
@@ -1325,6 +1341,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(level.HasValue ? string.Format(Strings.BotLevel, level.Value) : Strings.WarningFailed);
}
+ [ItemCanBeNull]
private static async Task ResponseLevel(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1369,6 +1386,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseLoot(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1429,6 +1447,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseLootByRealAppIDs(ulong steamID, string botNames, string realAppIDsText) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(realAppIDsText)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(realAppIDsText));
@@ -1469,6 +1488,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseNickname(ulong steamID, string botNames, string nickname) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(nickname)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(nickname));
@@ -1576,6 +1596,7 @@ namespace ArchiSteamFarm {
return (response.Length > 0 ? response.ToString() : FormatBotResponse(string.Format(Strings.BotNotOwnedYet, query)), ownedGameIDs);
}
+ [ItemCanBeNull]
private static async Task ResponseOwns(ulong steamID, string botNames, string query) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(query)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(query));
@@ -1631,6 +1652,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(string.Join(", ", encryptedPasswords.Where(kv => !string.IsNullOrEmpty(kv.Value)).Select(kv => string.Format(Strings.BotEncryptedPassword, kv.Key, kv.Value))));
}
+ [ItemCanBeNull]
private static async Task ResponsePassword(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1677,6 +1699,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponsePause(ulong steamID, string botNames, bool permanent, string resumeInSecondsText = null) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -1762,6 +1785,7 @@ namespace ArchiSteamFarm {
return await ResponsePlay(steamID, gamesToPlay, gameName.ToString()).ConfigureAwait(false);
}
+ [ItemCanBeNull]
private static async Task ResponsePlay(ulong steamID, string botNames, string targetGameIDs) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(targetGameIDs)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(targetGameIDs));
@@ -1912,6 +1936,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(await Bot.ArchiWebHandler.ChangePrivacySettings(userPrivacy).ConfigureAwait(false) ? Strings.Success : Strings.WarningFailed);
}
+ [ItemCanBeNull]
private static async Task ResponsePrivacy(ulong steamID, string botNames, string privacySettingsText) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(privacySettingsText)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(privacySettingsText));
@@ -2140,6 +2165,7 @@ namespace ArchiSteamFarm {
return response.Length > 0 ? response.ToString() : null;
}
+ [ItemCanBeNull]
private static async Task ResponseRedeem(ulong steamID, string botNames, string keys, ERedeemFlags redeemFlags = ERedeemFlags.None) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(keys)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(keys));
@@ -2192,6 +2218,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseResume(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -2228,6 +2255,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseStart(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -2308,6 +2336,7 @@ namespace ArchiSteamFarm {
return (FormatBotResponse(string.Format(Strings.BotStatusIdling, soloGame.AppID, soloGame.GameName, soloGame.CardsRemaining, Bot.CardsFarmer.GamesToFarm.Count, Bot.CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot);
}
+ [ItemCanBeNull]
private static async Task ResponseStatus(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -2352,6 +2381,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseStop(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -2408,6 +2438,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output));
}
+ [ItemCanBeNull]
private static async Task ResponseTransfer(ulong steamID, string botNames, string botNameTo) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(botNameTo)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(botNameTo));
@@ -2574,6 +2605,7 @@ namespace ArchiSteamFarm {
return FormatBotResponse(Strings.Done);
}
+ [ItemCanBeNull]
private static async Task ResponseUnpackBoosters(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
@@ -2634,6 +2666,7 @@ namespace ArchiSteamFarm {
return !Bot.IsConnectedAndLoggedOn ? FormatBotResponse(Strings.BotNotConnected) : FormatBotResponse(Bot.WalletCurrency != ECurrencyCode.Invalid ? string.Format(Strings.BotWalletBalance, Bot.WalletBalance / 100.0, Bot.WalletCurrency.ToString()) : Strings.BotHasNoWallet);
}
+ [ItemCanBeNull]
private static async Task ResponseWalletBalance(ulong steamID, string botNames) {
if ((steamID == 0) || string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames));
diff --git a/ArchiSteamFarm/GitHub.cs b/ArchiSteamFarm/GitHub.cs
index de5273e2e..cd75fe2f6 100644
--- a/ArchiSteamFarm/GitHub.cs
+++ b/ArchiSteamFarm/GitHub.cs
@@ -25,6 +25,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Markdig;
using Markdig.Renderers;
using Markdig.Syntax;
@@ -33,6 +34,7 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm {
internal static class GitHub {
+ [ItemCanBeNull]
internal static async Task GetLatestRelease(bool stable = true) {
string releaseURL = SharedInfo.GithubReleaseURL + (stable ? "/latest" : "?per_page=1");
@@ -45,6 +47,7 @@ namespace ArchiSteamFarm {
return response?.FirstOrDefault();
}
+ [ItemCanBeNull]
internal static async Task GetRelease(string version) {
if (string.IsNullOrEmpty(version)) {
ASF.ArchiLogger.LogNullError(nameof(version));
@@ -55,6 +58,7 @@ namespace ArchiSteamFarm {
return await GetReleaseFromURL(SharedInfo.GithubReleaseURL + "/tags/" + version).ConfigureAwait(false);
}
+ [ItemCanBeNull]
internal static async Task> GetReleases(byte count) {
if (count == 0) {
ASF.ArchiLogger.LogNullError(nameof(count));
@@ -86,6 +90,7 @@ namespace ArchiSteamFarm {
return result;
}
+ [ItemCanBeNull]
private static async Task GetReleaseFromURL(string releaseURL) {
if (string.IsNullOrEmpty(nameof(releaseURL))) {
ASF.ArchiLogger.LogNullError(nameof(releaseURL));
@@ -98,6 +103,7 @@ namespace ArchiSteamFarm {
return objectResponse?.Content;
}
+ [ItemCanBeNull]
private static async Task> GetReleasesFromURL(string releaseURL) {
if (string.IsNullOrEmpty(nameof(releaseURL))) {
ASF.ArchiLogger.LogNullError(nameof(releaseURL));
diff --git a/ArchiSteamFarm/GlobalConfig.cs b/ArchiSteamFarm/GlobalConfig.cs
index 070a63abf..e7ffbb147 100644
--- a/ArchiSteamFarm/GlobalConfig.cs
+++ b/ArchiSteamFarm/GlobalConfig.cs
@@ -219,6 +219,7 @@ namespace ArchiSteamFarm {
private bool ShouldSerializeSensitiveDetails = true;
[JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(SteamOwnerID), Required = Required.DisallowNull)]
+ [NotNull]
private string SSteamOwnerID {
get => SteamOwnerID.ToString();
@@ -261,12 +262,14 @@ namespace ArchiSteamFarm {
return Enum.IsDefined(typeof(EUpdateChannel), UpdateChannel) ? (true, null) : (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(UpdateChannel), UpdateChannel));
}
+ [NotNull]
internal static GlobalConfig Create() =>
new GlobalConfig {
ShouldSerializeEverything = false,
ShouldSerializeSensitiveDetails = false
};
+ [ItemCanBeNull]
internal static async Task Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ASF.ArchiLogger.LogNullError(nameof(filePath));
diff --git a/ArchiSteamFarm/GlobalDatabase.cs b/ArchiSteamFarm/GlobalDatabase.cs
index da2319217..1d2eadd76 100644
--- a/ArchiSteamFarm/GlobalDatabase.cs
+++ b/ArchiSteamFarm/GlobalDatabase.cs
@@ -27,6 +27,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.SteamKit2;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm {
@@ -49,7 +50,7 @@ namespace ArchiSteamFarm {
private string FilePath;
// This constructor is used when creating new database
- private GlobalDatabase(string filePath) : this() {
+ private GlobalDatabase([NotNull] string filePath) : this() {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException(nameof(filePath));
}
@@ -69,6 +70,7 @@ namespace ArchiSteamFarm {
PackagesRefreshSemaphore.Dispose();
}
+ [ItemCanBeNull]
internal static async Task CreateOrLoad(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ASF.ArchiLogger.LogNullError(nameof(filePath));
diff --git a/ArchiSteamFarm/Helpers/ArchiCacheable.cs b/ArchiSteamFarm/Helpers/ArchiCacheable.cs
index 38beda34b..71d7850cf 100644
--- a/ArchiSteamFarm/Helpers/ArchiCacheable.cs
+++ b/ArchiSteamFarm/Helpers/ArchiCacheable.cs
@@ -41,7 +41,7 @@ namespace ArchiSteamFarm.Helpers {
private T InitializedValue;
private Timer MaintenanceTimer;
- internal ArchiCacheable(Func> resolveFunction, TimeSpan? cacheLifetime = null) {
+ internal ArchiCacheable([NotNull] Func> resolveFunction, TimeSpan? cacheLifetime = null) {
ResolveFunction = resolveFunction ?? throw new ArgumentNullException(nameof(resolveFunction));
CacheLifetime = cacheLifetime ?? Timeout.InfiniteTimeSpan;
}
diff --git a/ArchiSteamFarm/Helpers/SemaphoreLock.cs b/ArchiSteamFarm/Helpers/SemaphoreLock.cs
index aaa684c30..6821dbed6 100644
--- a/ArchiSteamFarm/Helpers/SemaphoreLock.cs
+++ b/ArchiSteamFarm/Helpers/SemaphoreLock.cs
@@ -21,12 +21,13 @@
using System;
using System.Threading;
+using JetBrains.Annotations;
namespace ArchiSteamFarm.Helpers {
internal sealed class SemaphoreLock : IDisposable {
private readonly SemaphoreSlim Semaphore;
- internal SemaphoreLock(SemaphoreSlim semaphore) => Semaphore = semaphore ?? throw new ArgumentNullException(nameof(semaphore));
+ internal SemaphoreLock([NotNull] SemaphoreSlim semaphore) => Semaphore = semaphore ?? throw new ArgumentNullException(nameof(semaphore));
public void Dispose() => Semaphore.Release();
}
diff --git a/ArchiSteamFarm/IPC/Middleware/ApiAuthenticationMiddleware.cs b/ArchiSteamFarm/IPC/Middleware/ApiAuthenticationMiddleware.cs
index 171984ff2..ff5f4a508 100644
--- a/ArchiSteamFarm/IPC/Middleware/ApiAuthenticationMiddleware.cs
+++ b/ArchiSteamFarm/IPC/Middleware/ApiAuthenticationMiddleware.cs
@@ -52,7 +52,7 @@ namespace ArchiSteamFarm.IPC.Middleware {
private readonly RequestDelegate Next;
- public ApiAuthenticationMiddleware(RequestDelegate next) => Next = next ?? throw new ArgumentNullException(nameof(next));
+ public ApiAuthenticationMiddleware([NotNull] RequestDelegate next) => Next = next ?? throw new ArgumentNullException(nameof(next));
[PublicAPI]
public async Task InvokeAsync(HttpContext context) {
diff --git a/ArchiSteamFarm/IPC/Responses/ASFResponse.cs b/ArchiSteamFarm/IPC/Responses/ASFResponse.cs
index 499d8c940..70060d1d8 100644
--- a/ArchiSteamFarm/IPC/Responses/ASFResponse.cs
+++ b/ArchiSteamFarm/IPC/Responses/ASFResponse.cs
@@ -21,6 +21,7 @@
using System;
using System.ComponentModel.DataAnnotations;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.IPC.Responses {
@@ -60,7 +61,7 @@ namespace ArchiSteamFarm.IPC.Responses {
[Required]
public readonly Version Version;
- internal ASFResponse(string buildVariant, GlobalConfig globalConfig, uint memoryUsage, DateTime processStartTime, Version version) {
+ internal ASFResponse([NotNull] string buildVariant, [NotNull] GlobalConfig globalConfig, uint memoryUsage, DateTime processStartTime, [NotNull] Version version) {
if (string.IsNullOrEmpty(buildVariant) || (globalConfig == null) || (memoryUsage == 0) || (processStartTime == DateTime.MinValue) || (version == null)) {
throw new ArgumentNullException(nameof(buildVariant) + " || " + nameof(globalConfig) + " || " + nameof(memoryUsage) + " || " + nameof(processStartTime) + " || " + nameof(version));
}
diff --git a/ArchiSteamFarm/IPC/Responses/GitHubReleaseResponse.cs b/ArchiSteamFarm/IPC/Responses/GitHubReleaseResponse.cs
index b9007995f..f33d1dcea 100644
--- a/ArchiSteamFarm/IPC/Responses/GitHubReleaseResponse.cs
+++ b/ArchiSteamFarm/IPC/Responses/GitHubReleaseResponse.cs
@@ -21,6 +21,7 @@
using System;
using System.ComponentModel.DataAnnotations;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.IPC.Responses {
@@ -53,7 +54,7 @@ namespace ArchiSteamFarm.IPC.Responses {
[Required]
public readonly string Version;
- internal GitHubReleaseResponse(GitHub.ReleaseResponse releaseResponse) {
+ internal GitHubReleaseResponse([NotNull] GitHub.ReleaseResponse releaseResponse) {
if (releaseResponse == null) {
throw new ArgumentNullException(nameof(releaseResponse));
}
diff --git a/ArchiSteamFarm/IPC/Responses/TypeResponse.cs b/ArchiSteamFarm/IPC/Responses/TypeResponse.cs
index 0e3f7c0d4..e494ae642 100644
--- a/ArchiSteamFarm/IPC/Responses/TypeResponse.cs
+++ b/ArchiSteamFarm/IPC/Responses/TypeResponse.cs
@@ -22,6 +22,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.IPC.Responses {
@@ -45,7 +46,7 @@ namespace ArchiSteamFarm.IPC.Responses {
[Required]
public readonly TypeProperties Properties;
- internal TypeResponse(Dictionary body, TypeProperties properties) {
+ internal TypeResponse([NotNull] Dictionary body, [NotNull] TypeProperties properties) {
if ((body == null) || (properties == null)) {
throw new ArgumentNullException(nameof(body) + " || " + nameof(properties));
}
diff --git a/ArchiSteamFarm/IPC/Startup.cs b/ArchiSteamFarm/IPC/Startup.cs
index 8341f3288..ca1df05fa 100644
--- a/ArchiSteamFarm/IPC/Startup.cs
+++ b/ArchiSteamFarm/IPC/Startup.cs
@@ -22,6 +22,7 @@
using System;
using System.IO;
using ArchiSteamFarm.IPC.Middleware;
+using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@@ -36,7 +37,7 @@ namespace ArchiSteamFarm.IPC {
internal sealed class Startup {
private readonly IConfiguration Configuration;
- public Startup(IConfiguration configuration) => Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
+ public Startup([NotNull] IConfiguration configuration) => Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if ((app == null) || (env == null)) {
diff --git a/ArchiSteamFarm/Json/Steam.cs b/ArchiSteamFarm/Json/Steam.cs
index 448959f63..bb8c17aac 100644
--- a/ArchiSteamFarm/Json/Steam.cs
+++ b/ArchiSteamFarm/Json/Steam.cs
@@ -64,6 +64,7 @@ namespace ArchiSteamFarm.Json {
public EType Type { get; internal set; }
[JsonProperty(PropertyName = "amount", Required = Required.Always)]
+ [NotNull]
private string AmountText {
get => Amount.ToString();
@@ -85,6 +86,7 @@ namespace ArchiSteamFarm.Json {
}
[JsonProperty(PropertyName = "assetid", Required = Required.DisallowNull)]
+ [NotNull]
private string AssetIDText {
get => AssetID.ToString();
@@ -106,6 +108,7 @@ namespace ArchiSteamFarm.Json {
}
[JsonProperty(PropertyName = "classid", Required = Required.DisallowNull)]
+ [NotNull]
private string ClassIDText {
get => ClassID.ToString();
@@ -125,6 +128,7 @@ namespace ArchiSteamFarm.Json {
}
[JsonProperty(PropertyName = "contextid", Required = Required.DisallowNull)]
+ [NotNull]
private string ContextIDText {
get => ContextID.ToString();
@@ -146,6 +150,7 @@ namespace ArchiSteamFarm.Json {
}
[JsonProperty(PropertyName = "id", Required = Required.DisallowNull)]
+ [NotNull]
private string IDText {
get => AssetIDText;
set => AssetIDText = value;
@@ -555,7 +560,7 @@ namespace ArchiSteamFarm.Json {
internal readonly PrivacySettings Settings;
// Constructed from privacy change request
- internal UserPrivacy(PrivacySettings settings, ECommentPermission commentPermission) {
+ internal UserPrivacy([NotNull] PrivacySettings settings, ECommentPermission commentPermission) {
Settings = settings ?? throw new ArgumentNullException(nameof(settings));
CommentPermission = commentPermission;
}
diff --git a/ArchiSteamFarm/MobileAuthenticator.cs b/ArchiSteamFarm/MobileAuthenticator.cs
index 6665d481a..188ddd564 100644
--- a/ArchiSteamFarm/MobileAuthenticator.cs
+++ b/ArchiSteamFarm/MobileAuthenticator.cs
@@ -29,6 +29,7 @@ using System.Threading.Tasks;
using ArchiSteamFarm.Json;
using ArchiSteamFarm.Localization;
using HtmlAgilityPack;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm {
@@ -92,6 +93,7 @@ namespace ArchiSteamFarm {
return GenerateTokenForTime(time);
}
+ [ItemCanBeNull]
internal async Task GetConfirmationDetails(Confirmation confirmation) {
if (confirmation == null) {
Bot.ArchiLogger.LogNullError(nameof(confirmation));
@@ -126,6 +128,7 @@ namespace ArchiSteamFarm {
return response?.Success == true ? response : null;
}
+ [ItemCanBeNull]
internal async Task> GetConfirmations(Steam.ConfirmationDetails.EType acceptedType = Steam.ConfirmationDetails.EType.Unknown) {
if (!HasValidDeviceID) {
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
@@ -275,7 +278,7 @@ namespace ArchiSteamFarm {
return true;
}
- internal void Init(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
+ internal void Init([NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
internal static bool IsValidDeviceID(string deviceID) {
if (string.IsNullOrEmpty(deviceID)) {
diff --git a/ArchiSteamFarm/NLog/ArchiLogger.cs b/ArchiSteamFarm/NLog/ArchiLogger.cs
index 6d9f1a891..f353e6edf 100644
--- a/ArchiSteamFarm/NLog/ArchiLogger.cs
+++ b/ArchiSteamFarm/NLog/ArchiLogger.cs
@@ -31,7 +31,7 @@ namespace ArchiSteamFarm.NLog {
public sealed class ArchiLogger {
private readonly Logger Logger;
- public ArchiLogger(string name) {
+ public ArchiLogger([NotNull] string name) {
if (string.IsNullOrEmpty(name)) {
throw new ArgumentNullException(nameof(name));
}
diff --git a/ArchiSteamFarm/NLog/HistoryTarget.cs b/ArchiSteamFarm/NLog/HistoryTarget.cs
index 97f4c7e51..d4ddcf01a 100644
--- a/ArchiSteamFarm/NLog/HistoryTarget.cs
+++ b/ArchiSteamFarm/NLog/HistoryTarget.cs
@@ -80,7 +80,7 @@ namespace ArchiSteamFarm.NLog {
internal sealed class NewHistoryEntryArgs : EventArgs {
internal readonly string Message;
- internal NewHistoryEntryArgs(string message) => Message = message ?? throw new ArgumentNullException(nameof(message));
+ internal NewHistoryEntryArgs([NotNull] string message) => Message = message ?? throw new ArgumentNullException(nameof(message));
}
}
}
diff --git a/ArchiSteamFarm/OS.cs b/ArchiSteamFarm/OS.cs
index 46af0fa1a..f2f1f52d2 100644
--- a/ArchiSteamFarm/OS.cs
+++ b/ArchiSteamFarm/OS.cs
@@ -24,10 +24,13 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using ArchiSteamFarm.Localization;
+using JetBrains.Annotations;
namespace ArchiSteamFarm {
internal static class OS {
internal static bool IsUnix => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+
+ [NotNull]
internal static string Variant => RuntimeInformation.OSDescription.Trim();
internal static void Init(bool systemRequired, GlobalConfig.EOptimizationMode optimizationMode) {
diff --git a/ArchiSteamFarm/Plugins/Core.cs b/ArchiSteamFarm/Plugins/Core.cs
index 32ea9a36c..c8e6dfe22 100644
--- a/ArchiSteamFarm/Plugins/Core.cs
+++ b/ArchiSteamFarm/Plugins/Core.cs
@@ -31,6 +31,7 @@ using System.Reflection;
using System.Threading.Tasks;
using ArchiSteamFarm.Json;
using ArchiSteamFarm.Localization;
+using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
using SteamKit2;
@@ -63,6 +64,7 @@ namespace ArchiSteamFarm.Plugins {
return true;
}
+ [ItemNotNull]
internal static async Task GetBotsComparer() {
if ((ActivePlugins == null) || (ActivePlugins.Count == 0)) {
return StringComparer.Ordinal;
@@ -178,6 +180,7 @@ namespace ArchiSteamFarm.Plugins {
}
}
+ [ItemCanBeNull]
internal static async Task OnBotCommand(Bot bot, ulong steamID, string message, string[] args) {
if ((bot == null) || (steamID == 0) || string.IsNullOrEmpty(message) || (args == null) || (args.Length == 0)) {
ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(args));
@@ -292,6 +295,7 @@ namespace ArchiSteamFarm.Plugins {
}
}
+ [ItemCanBeNull]
internal static async Task OnBotMessage(Bot bot, ulong steamID, string message) {
if ((bot == null) || (steamID == 0) || string.IsNullOrEmpty(message)) {
ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(message));
diff --git a/ArchiSteamFarm/Plugins/IBotCommand.cs b/ArchiSteamFarm/Plugins/IBotCommand.cs
index 5beb4b9ab..0d9cb5781 100644
--- a/ArchiSteamFarm/Plugins/IBotCommand.cs
+++ b/ArchiSteamFarm/Plugins/IBotCommand.cs
@@ -33,7 +33,8 @@ namespace ArchiSteamFarm.Plugins {
/// Command message in its raw format, stripped of .
/// Pre-parsed message using standard ASF delimiters.
/// Response to the command, or null/empty (as the task value) if the command isn't handled by this plugin.
+ [ItemCanBeNull]
[NotNull]
- Task OnBotCommand([NotNull] Bot bot, ulong steamID, [NotNull] string message, [NotNull] string[] args);
+ Task OnBotCommand([NotNull] Bot bot, ulong steamID, [NotNull] string message, [ItemNotNull] [NotNull] string[] args);
}
}
diff --git a/ArchiSteamFarm/Plugins/IBotMessage.cs b/ArchiSteamFarm/Plugins/IBotMessage.cs
index 568b6a5ac..562bd7754 100644
--- a/ArchiSteamFarm/Plugins/IBotMessage.cs
+++ b/ArchiSteamFarm/Plugins/IBotMessage.cs
@@ -32,6 +32,7 @@ namespace ArchiSteamFarm.Plugins {
/// 64-bit long unsigned integer of steamID executing the command.
/// Message in its raw format.
/// Response to the message, or null/empty (as the task value) for silence.
+ [ItemCanBeNull]
[NotNull]
Task OnBotMessage([NotNull] Bot bot, ulong steamID, [NotNull] string message);
}
diff --git a/ArchiSteamFarm/RuntimeCompatibility.cs b/ArchiSteamFarm/RuntimeCompatibility.cs
index 91fe4a78e..753d0802f 100644
--- a/ArchiSteamFarm/RuntimeCompatibility.cs
+++ b/ArchiSteamFarm/RuntimeCompatibility.cs
@@ -22,9 +22,9 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
+using JetBrains.Annotations;
#if NETFRAMEWORK
-using JetBrains.Annotations;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading;
@@ -54,28 +54,30 @@ namespace ArchiSteamFarm {
#pragma warning disable 1998
internal static class File {
- internal static async Task AppendAllTextAsync(string path, string contents) =>
+ internal static async Task AppendAllTextAsync([NotNull] string path, string contents) =>
#if NETFRAMEWORK
System.IO.File.AppendAllText(path, contents);
#else
await System.IO.File.AppendAllTextAsync(path, contents).ConfigureAwait(false);
#endif
- internal static async Task ReadAllBytesAsync(string path) =>
+ [ItemNotNull]
+ internal static async Task ReadAllBytesAsync([NotNull] string path) =>
#if NETFRAMEWORK
System.IO.File.ReadAllBytes(path);
#else
await System.IO.File.ReadAllBytesAsync(path).ConfigureAwait(false);
#endif
- internal static async Task ReadAllTextAsync(string path) =>
+ [ItemNotNull]
+ internal static async Task ReadAllTextAsync([NotNull] string path) =>
#if NETFRAMEWORK
System.IO.File.ReadAllText(path);
#else
await System.IO.File.ReadAllTextAsync(path).ConfigureAwait(false);
#endif
- internal static async Task WriteAllTextAsync(string path, string contents) =>
+ internal static async Task WriteAllTextAsync([NotNull] string path, string contents) =>
#if NETFRAMEWORK
System.IO.File.WriteAllText(path, contents);
#else
@@ -94,7 +96,8 @@ namespace ArchiSteamFarm {
}
internal static class Path {
- internal static string GetRelativePath(string relativeTo, string path) {
+ [NotNull]
+ internal static string GetRelativePath([NotNull] string relativeTo, [NotNull] string path) {
#if NETFRAMEWORK
if (!path.StartsWith(relativeTo, StringComparison.Ordinal)) {
throw new NotImplementedException();
@@ -112,9 +115,11 @@ namespace ArchiSteamFarm {
}
#if NETFRAMEWORK
- internal static async Task ReceiveAsync(this WebSocket webSocket, byte[] buffer, CancellationToken cancellationToken) => await webSocket.ReceiveAsync(new ArraySegment(buffer), cancellationToken).ConfigureAwait(false);
- internal static async Task SendAsync(this WebSocket webSocket, byte[] buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => await webSocket.SendAsync(new ArraySegment(buffer), messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
- internal static string[] Split(this string text, char separator, StringSplitOptions options = StringSplitOptions.None) => text.Split(new[] { separator }, options);
+ internal static async Task ReceiveAsync([NotNull] this WebSocket webSocket, [NotNull] byte[] buffer, CancellationToken cancellationToken) => await webSocket.ReceiveAsync(new ArraySegment(buffer), cancellationToken).ConfigureAwait(false);
+ internal static async Task SendAsync([NotNull] this WebSocket webSocket, [NotNull] byte[] buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => await webSocket.SendAsync(new ArraySegment(buffer), messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
+
+ [NotNull]
+ internal static string[] Split([NotNull] this string text, char separator, StringSplitOptions options = StringSplitOptions.None) => text.Split(new[] { separator }, options);
[PublicAPI]
internal static void TrimExcess(this Dictionary _) { } // no-op
diff --git a/ArchiSteamFarm/SharedInfo.cs b/ArchiSteamFarm/SharedInfo.cs
index facd8a484..69566e397 100644
--- a/ArchiSteamFarm/SharedInfo.cs
+++ b/ArchiSteamFarm/SharedInfo.cs
@@ -23,6 +23,7 @@ using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
+using JetBrains.Annotations;
namespace ArchiSteamFarm {
internal static class SharedInfo {
@@ -56,7 +57,10 @@ namespace ArchiSteamFarm {
internal static string HomeDirectory => Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
internal static Guid ModuleVersion => Assembly.GetEntryAssembly().ManifestModule.ModuleVersionId;
+
+ [NotNull]
internal static string PublicIdentifier => AssemblyName + (BuildInfo.IsCustomBuild ? "-custom" : "");
+
internal static Version Version => Assembly.GetEntryAssembly().GetName().Version;
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
diff --git a/ArchiSteamFarm/Statistics.cs b/ArchiSteamFarm/Statistics.cs
index 2d895f291..dbe203dfb 100644
--- a/ArchiSteamFarm/Statistics.cs
+++ b/ArchiSteamFarm/Statistics.cs
@@ -28,6 +28,7 @@ using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Json;
using ArchiSteamFarm.Localization;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm {
@@ -58,7 +59,7 @@ namespace ArchiSteamFarm {
private DateTime LastPersonaStateRequest;
private bool ShouldSendHeartBeats;
- internal Statistics(Bot bot) {
+ internal Statistics([NotNull] Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
MatchActivelyTimer = new Timer(
@@ -182,6 +183,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
private async Task> GetListedUsers() {
const string request = URL + "/Api/Bots";
diff --git a/ArchiSteamFarm/SteamKit2/InMemoryServerListProvider.cs b/ArchiSteamFarm/SteamKit2/InMemoryServerListProvider.cs
index 40a9d5c0c..5bf697f1b 100644
--- a/ArchiSteamFarm/SteamKit2/InMemoryServerListProvider.cs
+++ b/ArchiSteamFarm/SteamKit2/InMemoryServerListProvider.cs
@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ArchiSteamFarm.Collections;
+using JetBrains.Annotations;
using Newtonsoft.Json;
using SteamKit2.Discovery;
@@ -32,8 +33,10 @@ namespace ArchiSteamFarm.SteamKit2 {
[JsonProperty(Required = Required.DisallowNull)]
private readonly ConcurrentHashSet ServerRecords = new ConcurrentHashSet();
+ [NotNull]
public Task> FetchServerListAsync() => Task.FromResult(ServerRecords.Select(server => ServerRecord.CreateServer(server.Host, server.Port, server.ProtocolTypes)));
+ [NotNull]
public Task UpdateServerListAsync(IEnumerable endpoints) {
if (endpoints == null) {
ASF.ArchiLogger.LogNullError(nameof(endpoints));
diff --git a/ArchiSteamFarm/SteamKit2/ServerRecordEndPoint.cs b/ArchiSteamFarm/SteamKit2/ServerRecordEndPoint.cs
index c21491363..161477b0a 100644
--- a/ArchiSteamFarm/SteamKit2/ServerRecordEndPoint.cs
+++ b/ArchiSteamFarm/SteamKit2/ServerRecordEndPoint.cs
@@ -20,6 +20,7 @@
// limitations under the License.
using System;
+using JetBrains.Annotations;
using Newtonsoft.Json;
using SteamKit2;
@@ -34,7 +35,7 @@ namespace ArchiSteamFarm.SteamKit2 {
[JsonProperty(Required = Required.Always)]
internal readonly ProtocolTypes ProtocolTypes;
- internal ServerRecordEndPoint(string host, ushort port, ProtocolTypes protocolTypes) {
+ internal ServerRecordEndPoint([NotNull] string host, ushort port, ProtocolTypes protocolTypes) {
if (string.IsNullOrEmpty(host) || (port == 0) || (protocolTypes == 0)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(port) + " || " + nameof(protocolTypes));
}
diff --git a/ArchiSteamFarm/SteamSaleEvent.cs b/ArchiSteamFarm/SteamSaleEvent.cs
index 80a029b14..e4891edff 100644
--- a/ArchiSteamFarm/SteamSaleEvent.cs
+++ b/ArchiSteamFarm/SteamSaleEvent.cs
@@ -25,6 +25,7 @@ using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Localization;
using HtmlAgilityPack;
+using JetBrains.Annotations;
namespace ArchiSteamFarm {
internal sealed class SteamSaleEvent : IDisposable {
@@ -33,7 +34,7 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
private readonly Timer SaleEventTimer;
- internal SteamSaleEvent(Bot bot) {
+ internal SteamSaleEvent([NotNull] Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
SaleEventTimer = new Timer(
diff --git a/ArchiSteamFarm/Trading.cs b/ArchiSteamFarm/Trading.cs
index 89a4d8884..6897211e2 100644
--- a/ArchiSteamFarm/Trading.cs
+++ b/ArchiSteamFarm/Trading.cs
@@ -41,7 +41,7 @@ namespace ArchiSteamFarm {
private bool ParsingScheduled;
- internal Trading(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
+ internal Trading([NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
public void Dispose() => TradesSemaphore.Dispose();
@@ -517,6 +517,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
private async Task ShouldAcceptTrade(Steam.TradeOffer tradeOffer) {
if (tradeOffer == null) {
Bot.ArchiLogger.LogNullError(nameof(tradeOffer));
diff --git a/ArchiSteamFarm/Utilities.cs b/ArchiSteamFarm/Utilities.cs
index 5a1c6cee6..dbcff4e72 100644
--- a/ArchiSteamFarm/Utilities.cs
+++ b/ArchiSteamFarm/Utilities.cs
@@ -30,6 +30,7 @@ using System.Threading;
using System.Threading.Tasks;
using Humanizer;
using Humanizer.Localisation;
+using JetBrains.Annotations;
namespace ArchiSteamFarm {
internal static class Utilities {
@@ -237,6 +238,7 @@ namespace ArchiSteamFarm {
}
}
+ [NotNull]
internal static string ReadLineMasked(char mask = '*') {
StringBuilder result = new StringBuilder();
diff --git a/ArchiSteamFarm/WebBrowser.cs b/ArchiSteamFarm/WebBrowser.cs
index b9901c2d5..60db6fa6a 100644
--- a/ArchiSteamFarm/WebBrowser.cs
+++ b/ArchiSteamFarm/WebBrowser.cs
@@ -48,7 +48,7 @@ namespace ArchiSteamFarm {
private readonly HttpClient HttpClient;
private readonly HttpClientHandler HttpClientHandler;
- internal WebBrowser(ArchiLogger archiLogger, IWebProxy webProxy = null, bool extendedTimeout = false) {
+ internal WebBrowser([NotNull] ArchiLogger archiLogger, IWebProxy webProxy = null, bool extendedTimeout = false) {
ArchiLogger = archiLogger ?? throw new ArgumentNullException(nameof(archiLogger));
HttpClientHandler = new HttpClientHandler {
@@ -74,6 +74,7 @@ namespace ArchiSteamFarm {
HttpClientHandler.Dispose();
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task UrlGetToHtmlDocument(string request, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -87,6 +88,7 @@ namespace ArchiSteamFarm {
return response != null ? new HtmlDocumentResponse(response) : null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task> UrlGetToJsonObject(string request, string referer = null, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -127,6 +129,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task UrlGetToXmlDocument(string request, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -163,6 +166,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task UrlHead(string request, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -189,6 +193,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task UrlPost(string request, IReadOnlyCollection> data = null, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -215,6 +220,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task UrlPostToHtmlDocument(string request, IReadOnlyCollection> data = null, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -228,6 +234,7 @@ namespace ArchiSteamFarm {
return response != null ? new HtmlDocumentResponse(response) : null;
}
+ [ItemCanBeNull]
[PublicAPI]
public async Task> UrlPostToJsonObject(string request, IReadOnlyCollection> data = null, string referer = null, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
@@ -268,6 +275,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [NotNull]
internal HttpClient GenerateDisposableHttpClient(bool extendedTimeout = false) {
HttpClient result = new HttpClient(HttpClientHandler) {
Timeout = TimeSpan.FromSeconds(extendedTimeout ? ExtendedTimeoutMultiplier * Program.GlobalConfig.ConnectionTimeout : Program.GlobalConfig.ConnectionTimeout)
@@ -309,6 +317,7 @@ namespace ArchiSteamFarm {
return htmlDocument;
}
+ [ItemCanBeNull]
internal async Task UrlGetToBinaryWithProgress(string request, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
@@ -380,6 +389,7 @@ namespace ArchiSteamFarm {
return null;
}
+ [ItemCanBeNull]
internal async Task UrlGetToString(string request, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
@@ -546,6 +556,7 @@ namespace ArchiSteamFarm {
}
}
+ [ItemCanBeNull]
private async Task UrlPostToString(string request, IReadOnlyCollection> data = null, string referer = null, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
@@ -574,7 +585,7 @@ namespace ArchiSteamFarm {
public class BasicResponse {
internal readonly Uri FinalUri;
- internal BasicResponse(HttpResponseMessage httpResponseMessage) {
+ internal BasicResponse([NotNull] HttpResponseMessage httpResponseMessage) {
if (httpResponseMessage == null) {
throw new ArgumentNullException(nameof(httpResponseMessage));
}
@@ -582,7 +593,7 @@ namespace ArchiSteamFarm {
FinalUri = httpResponseMessage.Headers.Location ?? httpResponseMessage.RequestMessage.RequestUri;
}
- internal BasicResponse(BasicResponse basicResponse) {
+ internal BasicResponse([NotNull] BasicResponse basicResponse) {
if (basicResponse == null) {
throw new ArgumentNullException(nameof(basicResponse));
}
@@ -595,7 +606,7 @@ namespace ArchiSteamFarm {
[PublicAPI]
public readonly HtmlDocument Content;
- internal HtmlDocumentResponse(StringResponse stringResponse) : base(stringResponse) {
+ internal HtmlDocumentResponse([NotNull] StringResponse stringResponse) : base(stringResponse) {
if (stringResponse == null) {
throw new ArgumentNullException(nameof(stringResponse));
}
@@ -608,7 +619,7 @@ namespace ArchiSteamFarm {
[PublicAPI]
public readonly T Content;
- internal ObjectResponse(StringResponse stringResponse, T content) : base(stringResponse) {
+ internal ObjectResponse([NotNull] StringResponse stringResponse, T content) : base(stringResponse) {
if (stringResponse == null) {
throw new ArgumentNullException(nameof(stringResponse));
}
@@ -621,7 +632,7 @@ namespace ArchiSteamFarm {
[PublicAPI]
public readonly XmlDocument Content;
- internal XmlDocumentResponse(StringResponse stringResponse, XmlDocument content) : base(stringResponse) {
+ internal XmlDocumentResponse([NotNull] StringResponse stringResponse, XmlDocument content) : base(stringResponse) {
if (stringResponse == null) {
throw new ArgumentNullException(nameof(stringResponse));
}
@@ -633,7 +644,7 @@ namespace ArchiSteamFarm {
internal sealed class BinaryResponse : BasicResponse {
internal readonly byte[] Content;
- internal BinaryResponse(HttpResponseMessage httpResponseMessage, byte[] content) : base(httpResponseMessage) {
+ internal BinaryResponse([NotNull] HttpResponseMessage httpResponseMessage, [NotNull] byte[] content) : base(httpResponseMessage) {
if ((httpResponseMessage == null) || (content == null)) {
throw new ArgumentNullException(nameof(httpResponseMessage) + " || " + nameof(content));
}
@@ -645,7 +656,7 @@ namespace ArchiSteamFarm {
internal sealed class StringResponse : BasicResponse {
internal readonly string Content;
- internal StringResponse(HttpResponseMessage httpResponseMessage, string content) : base(httpResponseMessage) {
+ internal StringResponse([NotNull] HttpResponseMessage httpResponseMessage, [NotNull] string content) : base(httpResponseMessage) {
if ((httpResponseMessage == null) || (content == null)) {
throw new ArgumentNullException(nameof(httpResponseMessage) + " || " + nameof(content));
}