Gigantic code review (with ReSharper)

This commit is contained in:
JustArchi
2016-05-13 06:32:42 +02:00
parent 6f93139a18
commit b8faca2517
34 changed files with 935 additions and 888 deletions

Binary file not shown.

View File

@@ -26,7 +26,9 @@ using SteamKit2;
using SteamKit2.Internal;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
@@ -36,7 +38,7 @@ namespace ArchiSteamFarm {
internal ArchiHandler(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
@@ -53,6 +55,7 @@ namespace ArchiSteamFarm {
internal sealed class NotificationsCallback : CallbackMsg {
internal enum ENotification : byte {
[SuppressMessage("ReSharper", "UnusedMember.Global")]
Unknown = 0,
Trading = 1,
// Only custom below, different than ones available as user_notification_type
@@ -62,21 +65,21 @@ namespace ArchiSteamFarm {
internal readonly HashSet<ENotification> Notifications;
internal NotificationsCallback(JobID jobID, CMsgClientUserNotifications msg) {
if (jobID == null || msg == null) {
throw new ArgumentNullException("jobID || msg");
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
JobID = jobID;
Notifications = new HashSet<ENotification>();
foreach (var notification in msg.notifications) {
foreach (CMsgClientUserNotifications.Notification notification in msg.notifications) {
Notifications.Add((ENotification) notification.user_notification_type);
}
}
internal NotificationsCallback(JobID jobID, CMsgClientItemAnnouncements msg) {
if (jobID == null || msg == null) {
throw new ArgumentNullException("jobID || msg");
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
JobID = jobID;
@@ -93,8 +96,8 @@ namespace ArchiSteamFarm {
internal readonly uint OfflineMessagesCount;
internal OfflineMessageCallback(JobID jobID, CMsgClientOfflineMessageNotification msg) {
if (jobID == null || msg == null) {
throw new ArgumentNullException("jobID || msg");
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
JobID = jobID;
@@ -104,6 +107,7 @@ namespace ArchiSteamFarm {
internal sealed class PurchaseResponseCallback : CallbackMsg {
internal enum EPurchaseResult : sbyte {
[SuppressMessage("ReSharper", "UnusedMember.Global")]
Unknown = -1,
OK = 0,
AlreadyOwned = 9,
@@ -114,31 +118,28 @@ namespace ArchiSteamFarm {
OnCooldown = 53
}
internal readonly EResult Result;
internal readonly EPurchaseResult PurchaseResult;
internal readonly KeyValue ReceiptInfo;
internal readonly Dictionary<uint, string> Items;
internal PurchaseResponseCallback(JobID jobID, CMsgClientPurchaseResponse msg) {
if (jobID == null || msg == null) {
throw new ArgumentNullException("jobID || msg");
if ((jobID == null) || (msg == null)) {
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
}
JobID = jobID;
Result = (EResult) msg.eresult;
PurchaseResult = (EPurchaseResult) msg.purchase_result_details;
if (msg.purchase_receipt_info == null) {
return;
}
ReceiptInfo = new KeyValue();
KeyValue receiptInfo = new KeyValue();
using (MemoryStream ms = new MemoryStream(msg.purchase_receipt_info)) {
if (!ReceiptInfo.TryReadAsBinary(ms)) {
if (!receiptInfo.TryReadAsBinary(ms)) {
return;
}
var lineItems = ReceiptInfo["lineitems"].Children;
List<KeyValue> lineItems = receiptInfo["lineitems"].Children;
Items = new Dictionary<uint, string>(lineItems.Count);
foreach (KeyValue lineItem in lineItems) {
@@ -165,11 +166,11 @@ namespace ArchiSteamFarm {
return;
}
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
ClientMsgProtobuf<CMsgClientGamesPlayed> request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
if (!string.IsNullOrEmpty(gameName)) {
request.Body.games_played.Add(new CMsgClientGamesPlayed.GamePlayed {
game_extra_info = gameName,
game_id = new GameID() {
game_id = new GameID {
AppType = GameID.GameType.Shortcut,
ModID = uint.MaxValue
}
@@ -188,18 +189,14 @@ namespace ArchiSteamFarm {
}
internal void PlayGames(HashSet<uint> gameIDs) {
if (gameIDs == null || !Client.IsConnected) {
if ((gameIDs == null) || !Client.IsConnected) {
return;
}
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
foreach (uint gameID in gameIDs) {
if (gameID == 0) {
continue;
}
ClientMsgProtobuf<CMsgClientGamesPlayed> request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
foreach (uint gameID in gameIDs.Where(gameID => gameID != 0)) {
request.Body.games_played.Add(new CMsgClientGamesPlayed.GamePlayed {
game_id = new GameID(gameID),
game_id = new GameID(gameID)
});
}
@@ -211,7 +208,7 @@ namespace ArchiSteamFarm {
return null;
}
var request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey) {
ClientMsgProtobuf<CMsgClientRegisterKey> request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey) {
SourceJobID = Client.GetNextJobID()
};
@@ -235,8 +232,11 @@ namespace ArchiSteamFarm {
SteamID steamID = new SteamID(details.AccountID, details.AccountInstance, Client.ConnectedUniverse, EAccountType.Individual);
var logon = new ClientMsgProtobuf<CMsgClientLogon>(EMsg.ClientLogon);
ClientMsgProtobuf<CMsgClientLogon> logon = new ClientMsgProtobuf<CMsgClientLogon>(EMsg.ClientLogon);
if (details.LoginID != null) {
logon.Body.obfustucated_private_ip = details.LoginID.Value;
}
logon.ProtoHeader.client_sessionid = 0;
logon.ProtoHeader.steamid = steamID.ConvertToUInt64();
logon.Body.account_name = details.Username;
@@ -292,7 +292,7 @@ namespace ArchiSteamFarm {
return;
}
var response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
ClientMsgProtobuf<CMsgClientOfflineMessageNotification> response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
Client.PostCallback(new OfflineMessageCallback(packetMsg.TargetJobID, response.Body));
}
@@ -301,7 +301,7 @@ namespace ArchiSteamFarm {
return;
}
var response = new ClientMsgProtobuf<CMsgClientItemAnnouncements>(packetMsg);
ClientMsgProtobuf<CMsgClientItemAnnouncements> response = new ClientMsgProtobuf<CMsgClientItemAnnouncements>(packetMsg);
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
}
@@ -310,7 +310,7 @@ namespace ArchiSteamFarm {
return;
}
var response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
ClientMsgProtobuf<CMsgClientPurchaseResponse> response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
Client.PostCallback(new PurchaseResponseCallback(packetMsg.TargetJobID, response.Body));
}
@@ -319,7 +319,7 @@ namespace ArchiSteamFarm {
return;
}
var response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
ClientMsgProtobuf<CMsgClientUserNotifications> response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
}
}

View File

@@ -32,6 +32,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Threading;
using ArchiSteamFarm.JSON;
namespace ArchiSteamFarm {
internal sealed class ArchiWebHandler {
@@ -63,11 +64,7 @@ namespace ArchiSteamFarm {
}
uint appID;
if (!uint.TryParse(hashName.Substring(0, index), out appID)) {
return 0;
}
return appID;
return !uint.TryParse(hashName.Substring(0, index), out appID) ? 0 : appID;
}
private static Steam.Item.EType GetItemType(string name) {
@@ -87,21 +84,23 @@ namespace ArchiSteamFarm {
default:
if (name.EndsWith("Emoticon", StringComparison.Ordinal)) {
return Steam.Item.EType.Emoticon;
} else if (name.EndsWith("Foil Trading Card", StringComparison.Ordinal)) {
return Steam.Item.EType.FoilTradingCard;
} else if (name.EndsWith("Profile Background", StringComparison.Ordinal)) {
return Steam.Item.EType.ProfileBackground;
} else if (name.EndsWith("Trading Card", StringComparison.Ordinal)) {
return Steam.Item.EType.TradingCard;
} else {
return Steam.Item.EType.Unknown;
}
if (name.EndsWith("Foil Trading Card", StringComparison.Ordinal)) {
return Steam.Item.EType.FoilTradingCard;
}
if (name.EndsWith("Profile Background", StringComparison.Ordinal)) {
return Steam.Item.EType.ProfileBackground;
}
return name.EndsWith("Trading Card", StringComparison.Ordinal) ? Steam.Item.EType.TradingCard : Steam.Item.EType.Unknown;
}
}
internal ArchiWebHandler(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
@@ -110,11 +109,14 @@ namespace ArchiSteamFarm {
}
internal bool Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
if (steamClient == null || steamClient.SteamID == null || string.IsNullOrEmpty(webAPIUserNonce)) {
if ((steamClient == null) || string.IsNullOrEmpty(webAPIUserNonce)) {
return false;
}
ulong steamID = steamClient.SteamID;
if (steamID == 0) {
return false;
}
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(steamID.ToString()));
@@ -198,16 +200,16 @@ namespace ArchiSteamFarm {
};
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
}
if (!result) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
if (result) {
return true;
}
return true;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
}
internal async Task<bool> JoinGroup(ulong groupID) {
@@ -232,16 +234,16 @@ namespace ArchiSteamFarm {
};
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
}
if (!result) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
if (result) {
return true;
}
return true;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
}
internal async Task<Dictionary<uint, string>> GetOwnedGames() {
@@ -252,7 +254,7 @@ namespace ArchiSteamFarm {
string request = SteamCommunityURL + "/my/games/?xml=1";
XmlDocument response = null;
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
response = await WebBrowser.UrlGetToXML(request).ConfigureAwait(false);
}
@@ -262,7 +264,7 @@ namespace ArchiSteamFarm {
}
XmlNodeList xmlNodeList = response.SelectNodes("gamesList/games/game");
if (xmlNodeList == null || xmlNodeList.Count == 0) {
if ((xmlNodeList == null) || (xmlNodeList.Count == 0)) {
return null;
}
@@ -290,7 +292,7 @@ namespace ArchiSteamFarm {
}
internal Dictionary<uint, string> GetOwnedGames(ulong steamID) {
if (steamID == 0 || string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
if ((steamID == 0) || string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
return null;
}
@@ -298,7 +300,7 @@ namespace ArchiSteamFarm {
using (dynamic iPlayerService = WebAPI.GetInterface("IPlayerService", Bot.BotConfig.SteamApiKey)) {
iPlayerService.Timeout = Timeout;
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
try {
response = iPlayerService.GetOwnedGames(
steamid: steamID,
@@ -338,7 +340,7 @@ namespace ArchiSteamFarm {
using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) {
iEconService.Timeout = Timeout;
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
try {
response = iEconService.GetTradeOffers(
get_received_offers: 1,
@@ -389,7 +391,6 @@ namespace ArchiSteamFarm {
HashSet<Steam.TradeOffer> result = new HashSet<Steam.TradeOffer>();
foreach (KeyValue trade in response["trade_offers_received"].Children) {
// TODO: Correct some of these when SK2 with https://github.com/SteamRE/SteamKit/pull/255 gets released
Steam.TradeOffer tradeOffer = new Steam.TradeOffer {
TradeOfferID = trade["tradeofferid"].AsUnsignedLong(),
OtherSteamID3 = (uint) trade["accountid_other"].AsUnsignedLong(),
@@ -468,16 +469,16 @@ namespace ArchiSteamFarm {
};
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
}
if (!result) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
if (result) {
return true;
}
return true;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
}
internal async Task<HashSet<Steam.Item>> GetMyTradableInventory() {
@@ -492,7 +493,7 @@ namespace ArchiSteamFarm {
string request = SteamCommunityURL + "/my/inventory/json/" + Steam.Item.SteamAppID + "/" + Steam.Item.SteamContextID + "?trading=1&start=" + nextPage;
JObject jObject = null;
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (jObject == null); i++) {
jObject = await WebBrowser.UrlGetToJObject(request).ConfigureAwait(false);
}
@@ -514,7 +515,7 @@ namespace ArchiSteamFarm {
}
ulong classID;
if (!ulong.TryParse(classIDString, out classID) || classID == 0) {
if (!ulong.TryParse(classIDString, out classID) || (classID == 0)) {
continue;
}
@@ -550,7 +551,7 @@ namespace ArchiSteamFarm {
}
IEnumerable<JToken> items = jObject.SelectTokens("$.rgInventory.*");
if (descriptions == null) {
if (items == null) {
return null;
}
@@ -594,7 +595,7 @@ namespace ArchiSteamFarm {
}
internal async Task<bool> SendTradeOffer(HashSet<Steam.Item> inventory, ulong partnerID, string token = null) {
if (inventory == null || inventory.Count == 0 || partnerID == 0) {
if ((inventory == null) || (inventory.Count == 0) || (partnerID == 0)) {
return false;
}
@@ -608,13 +609,12 @@ namespace ArchiSteamFarm {
return false;
}
HashSet<Steam.TradeOfferRequest> trades = new HashSet<Steam.TradeOfferRequest>();
Steam.TradeOfferRequest singleTrade = null;
Steam.TradeOfferRequest singleTrade = new Steam.TradeOfferRequest();
HashSet<Steam.TradeOfferRequest> trades = new HashSet<Steam.TradeOfferRequest> { singleTrade };
byte itemID = 0;
foreach (Steam.Item item in inventory) {
if (itemID % Trading.MaxItemsPerTrade == 0) {
if (itemID >= Trading.MaxItemsPerTrade) {
if (trades.Count >= Trading.MaxTradesPerAccount) {
break;
}
@@ -624,7 +624,7 @@ namespace ArchiSteamFarm {
itemID = 0;
}
singleTrade.ItemsToGive.Assets.Add(new Steam.Item() {
singleTrade.ItemsToGive.Assets.Add(new Steam.Item {
AppID = Steam.Item.SteamAppID,
ContextID = Steam.Item.SteamContextID,
Amount = item.Amount,
@@ -647,15 +647,17 @@ namespace ArchiSteamFarm {
};
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
}
if (!result) {
if (result) {
continue;
}
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
}
}
return true;
}
@@ -672,16 +674,16 @@ namespace ArchiSteamFarm {
string request = SteamCommunityURL + "/my/badges?p=" + page;
HtmlDocument htmlDocument = null;
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (htmlDocument == null); i++) {
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(request).ConfigureAwait(false);
}
if (htmlDocument == null) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
if (htmlDocument != null) {
return htmlDocument;
}
return htmlDocument;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
}
internal async Task<HtmlDocument> GetGameCardsPage(ulong appID) {
@@ -696,16 +698,16 @@ namespace ArchiSteamFarm {
string request = SteamCommunityURL + "/my/gamecards/" + appID;
HtmlDocument htmlDocument = null;
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (htmlDocument == null); i++) {
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(request).ConfigureAwait(false);
}
if (htmlDocument == null) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
if (htmlDocument != null) {
return htmlDocument;
}
return htmlDocument;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
}
internal async Task<bool> MarkInventory() {
@@ -716,32 +718,32 @@ namespace ArchiSteamFarm {
string request = SteamCommunityURL + "/my/inventory";
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlHead(request).ConfigureAwait(false);
}
if (!result) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
if (result) {
return true;
}
return true;
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return false;
}
private async Task<bool?> IsLoggedIn() {
string request = SteamCommunityURL + "/my/profile";
Uri uri = null;
for (byte i = 0; i < WebBrowser.MaxRetries && uri == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (uri == null); i++) {
uri = await WebBrowser.UrlHeadToUri(request).ConfigureAwait(false);
}
if (uri == null) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
if (uri != null) {
return !uri.AbsolutePath.StartsWith("/login", StringComparison.Ordinal);
}
return !uri.AbsolutePath.StartsWith("/login", StringComparison.Ordinal);
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
return null;
}
private async Task<bool> RefreshSessionIfNeeded() {
@@ -784,7 +786,7 @@ namespace ArchiSteamFarm {
};
bool result = false;
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && !result; i++) {
result = await WebBrowser.UrlPost(request, data, SteamCommunityURL).ConfigureAwait(false);
}

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,8 @@ using System.Collections.Generic;
using System.IO;
namespace ArchiSteamFarm {
// ReSharper disable once ClassCannotBeInstantiated
// ReSharper disable once ClassNeverInstantiated.Global
internal sealed class BotConfig {
[JsonProperty(Required = Required.DisallowNull)]
internal bool Enabled { get; private set; } = false;
@@ -36,10 +38,10 @@ namespace ArchiSteamFarm {
internal bool StartOnLaunch { get; private set; } = true;
[JsonProperty]
internal string SteamLogin { get; set; } = null;
internal string SteamLogin { get; set; }
[JsonProperty]
internal string SteamPassword { get; set; } = null;
internal string SteamPassword { get; set; }
[JsonProperty]
internal string SteamParentalPIN { get; set; } = "0";
@@ -99,7 +101,7 @@ namespace ArchiSteamFarm {
internal string CustomGamePlayedWhileIdle { get; private set; } = null;
[JsonProperty(Required = Required.DisallowNull)]
internal HashSet<uint> GamesPlayedWhileIdle { get; private set; } = new HashSet<uint>() { 0 };
internal HashSet<uint> GamesPlayedWhileIdle { get; private set; } = new HashSet<uint> { 0 };
internal static BotConfig Load(string filePath) {

View File

@@ -93,7 +93,7 @@ namespace ArchiSteamFarm {
// This constructor is used when creating new database
private BotDatabase(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
@@ -101,6 +101,7 @@ namespace ArchiSteamFarm {
}
// This constructor is used only by deserializer
// ReSharper disable once UnusedMember.Local
private BotDatabase() { }
internal void Save() {

View File

@@ -48,12 +48,12 @@ namespace ArchiSteamFarm {
internal CardsFarmer(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
if (Timer == null && Program.GlobalConfig.IdleFarmingPeriod > 0) {
if ((Timer == null) && (Program.GlobalConfig.IdleFarmingPeriod > 0)) {
Timer = new Timer(
async e => await CheckGamesForFarming().ConfigureAwait(false),
null,
@@ -132,12 +132,14 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Chosen farming algorithm: Simple", Bot.BotName);
while (GamesToFarm.Count > 0) {
uint appID = GamesToFarm.Keys.FirstOrDefault();
if (!await FarmSolo(appID).ConfigureAwait(false)) {
if (await FarmSolo(appID).ConfigureAwait(false)) {
continue;
}
NowFarming = false;
return;
}
}
}
} while (await IsAnythingToFarm().ConfigureAwait(false));
CurrentGamesFarming.Clear();
@@ -164,7 +166,7 @@ namespace ArchiSteamFarm {
FarmResetEvent.Set();
Logging.LogGenericInfo("Waiting for reaction...", Bot.BotName);
for (byte i = 0; i < Program.GlobalConfig.HttpTimeout && NowFarming; i++) {
for (byte i = 0; (i < Program.GlobalConfig.HttpTimeout) && NowFarming; i++) {
await Utilities.SleepAsync(1000).ConfigureAwait(false);
}
@@ -188,11 +190,9 @@ namespace ArchiSteamFarm {
}
HashSet<uint> result = new HashSet<uint>();
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm) {
if (keyValue.Value >= 2) {
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm.Where(keyValue => keyValue.Value >= 2)) {
result.Add(keyValue.Key);
}
}
return result;
}
@@ -210,7 +210,7 @@ namespace ArchiSteamFarm {
byte maxPages = 1;
HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='pagelink']");
if (htmlNodeCollection != null && htmlNodeCollection.Count > 0) {
if ((htmlNodeCollection != null) && (htmlNodeCollection.Count > 0)) {
HtmlNode htmlNode = htmlNodeCollection[htmlNodeCollection.Count - 1];
string lastPage = htmlNode.InnerText;
if (!string.IsNullOrEmpty(lastPage)) {
@@ -224,16 +224,19 @@ namespace ArchiSteamFarm {
CheckPage(htmlDocument);
if (maxPages > 1) {
if (maxPages <= 1) {
return GamesToFarm.Count > 0;
}
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
List<Task> tasks = new List<Task>(maxPages - 1);
for (byte page = 2; page <= maxPages; page++) {
byte currentPage = page; // We need a copy of variable being passed when in for loops, as loop will proceed before task is launched
tasks.Add(CheckPage(currentPage));
}
await Task.WhenAll(tasks).ConfigureAwait(false);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
return GamesToFarm.Count > 0;
}
@@ -370,15 +373,11 @@ namespace ArchiSteamFarm {
}
Logging.LogGenericInfo("Now farming: " + string.Join(", ", CurrentGamesFarming), Bot.BotName);
if (FarmHours(maxHour, CurrentGamesFarming)) {
bool result = FarmHours(maxHour, CurrentGamesFarming);
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return true;
} else {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return false;
}
return result;
}
private async Task<bool> FarmSolo(uint appID) {
@@ -389,20 +388,23 @@ namespace ArchiSteamFarm {
CurrentGamesFarming.Add(appID);
Logging.LogGenericInfo("Now farming: " + appID, Bot.BotName);
if (await Farm(appID).ConfigureAwait(false)) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
float hours;
if (GamesToFarm.TryRemove(appID, out hours)) {
TimeSpan timeSpan = TimeSpan.FromHours(hours);
Logging.LogGenericInfo("Done farming: " + appID + " after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!", Bot.BotName);
}
return true;
} else {
bool result = await Farm(appID).ConfigureAwait(false);
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
if (!result) {
return false;
}
float hours;
if (!GamesToFarm.TryRemove(appID, out hours)) {
return false;
}
TimeSpan timeSpan = TimeSpan.FromHours(hours);
Logging.LogGenericInfo("Done farming: " + appID + " after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!", Bot.BotName);
return true;
}
private async Task<bool> Farm(uint appID) {
@@ -415,7 +417,7 @@ namespace ArchiSteamFarm {
bool success = true;
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
for (ushort farmingTime = 0; farmingTime <= 60 * Program.GlobalConfig.MaxFarmingTime && keepFarming.GetValueOrDefault(true); farmingTime += Program.GlobalConfig.FarmingDelay) {
for (ushort farmingTime = 0; (farmingTime <= 60 * Program.GlobalConfig.MaxFarmingTime) && keepFarming.GetValueOrDefault(true); farmingTime += Program.GlobalConfig.FarmingDelay) {
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
success = false;
break;
@@ -435,7 +437,7 @@ namespace ArchiSteamFarm {
}
private bool FarmHours(float maxHour, HashSet<uint> appIDs) {
if (maxHour < 0 || appIDs == null || appIDs.Count == 0) {
if ((maxHour < 0) || (appIDs == null) || (appIDs.Count == 0)) {
return false;
}

View File

@@ -29,14 +29,14 @@ using System.IO;
namespace ArchiSteamFarm {
internal static class Debugging {
#if DEBUG
// ReSharper disable once ConvertToConstant.Global
internal static readonly bool IsDebugBuild = true;
#else
// ReSharper disable once ConvertToConstant.Global
internal static readonly bool IsDebugBuild = false;
#endif
internal static bool IsReleaseBuild => !IsDebugBuild;
internal static bool NetHookAlreadyInitialized { get; set; } = false;
internal static bool NetHookAlreadyInitialized { get; set; }
internal sealed class DebugListener : IDebugListener {
private readonly string FilePath;

View File

@@ -25,11 +25,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Sockets;
namespace ArchiSteamFarm {
// ReSharper disable once ClassCannotBeInstantiated
// ReSharper disable once ClassNeverInstantiated.Global
internal sealed class GlobalConfig {
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal enum EUpdateChannel : byte {
Unknown,
Stable,
@@ -160,10 +164,12 @@ namespace ArchiSteamFarm {
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
if (globalConfig.WCFPort != 0) {
return globalConfig;
}
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
}
return globalConfig;
}

View File

@@ -75,7 +75,7 @@ namespace ArchiSteamFarm {
// This constructor is used when creating new database
private GlobalDatabase(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
@@ -83,6 +83,7 @@ namespace ArchiSteamFarm {
}
// This constructor is used only by deserializer
// ReSharper disable once UnusedMember.Local
private GlobalDatabase() { }
private void Save() {

View File

@@ -22,12 +22,16 @@
*/
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Newtonsoft.Json;
namespace ArchiSteamFarm {
namespace ArchiSteamFarm.JSON {
internal static class GitHub {
// ReSharper disable once ClassNeverInstantiated.Global
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")]
internal sealed class ReleaseResponse {
// ReSharper disable once ClassNeverInstantiated.Global
internal sealed class Asset {
[JsonProperty(PropertyName = "name", Required = Required.Always)]
internal string Name { get; private set; }

View File

@@ -22,11 +22,13 @@
*/
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Newtonsoft.Json;
using SteamKit2;
using System.Collections.Generic;
namespace ArchiSteamFarm {
namespace ArchiSteamFarm.JSON {
internal static class Steam {
internal sealed class Item { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
internal const ushort SteamAppID = 753;
@@ -48,11 +50,13 @@ namespace ArchiSteamFarm {
internal uint AppID { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "appid", Required = Required.DisallowNull)]
internal string AppIDString {
private string AppIDString {
get {
return AppID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -69,11 +73,13 @@ namespace ArchiSteamFarm {
internal ulong ContextID { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "contextid", Required = Required.DisallowNull)]
internal string ContextIDString {
private string ContextIDString {
get {
return ContextID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -91,10 +97,11 @@ namespace ArchiSteamFarm {
internal ulong AssetID { get; set; }
[JsonProperty(PropertyName = "assetid", Required = Required.DisallowNull)]
internal string AssetIDString {
private string AssetIDString {
get {
return AssetID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -109,19 +116,22 @@ namespace ArchiSteamFarm {
}
}
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "id", Required = Required.DisallowNull)]
internal string ID {
private string ID {
get { return AssetIDString; }
set { AssetIDString = value; }
}
internal ulong ClassID { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "classid", Required = Required.DisallowNull)]
internal string ClassIDString {
private string ClassIDString {
get {
return ClassID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -138,11 +148,13 @@ namespace ArchiSteamFarm {
internal ulong InstanceID { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "instanceid", Required = Required.DisallowNull)]
internal string InstanceIDString {
private string InstanceIDString {
get {
return InstanceID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -159,11 +171,13 @@ namespace ArchiSteamFarm {
internal uint Amount { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "amount", Required = Required.Always)]
internal string AmountString {
private string AmountString {
get {
return Amount.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -183,6 +197,7 @@ namespace ArchiSteamFarm {
}
internal sealed class TradeOffer { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal enum ETradeOfferState : byte {
Unknown,
Invalid,
@@ -200,11 +215,13 @@ namespace ArchiSteamFarm {
internal ulong TradeOfferID { get; set; }
// ReSharper disable once UnusedMember.Local
[JsonProperty(PropertyName = "tradeofferid", Required = Required.Always)]
internal string TradeOfferIDString {
private string TradeOfferIDString {
get {
return TradeOfferID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -220,7 +237,7 @@ namespace ArchiSteamFarm {
}
[JsonProperty(PropertyName = "accountid_other", Required = Required.Always)]
internal uint OtherSteamID3 { get; set; }
internal uint OtherSteamID3 { private get; set; }
[JsonProperty(PropertyName = "trade_offer_state", Required = Required.Always)]
internal ETradeOfferState State { get; set; }
@@ -232,82 +249,57 @@ namespace ArchiSteamFarm {
internal HashSet<Item> ItemsToReceive { get; } = new HashSet<Item>();
// Extra
internal ulong OtherSteamID64 {
get {
if (OtherSteamID3 == 0) {
return 0;
}
internal ulong OtherSteamID64 => OtherSteamID3 == 0 ? 0 : new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual);
return new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual);
}
set {
if (value == 0) {
return;
}
OtherSteamID3 = new SteamID(value).AccountID;
}
}
internal bool IsSteamCardsOnlyTradeForUs() {
foreach (Item item in ItemsToGive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || (item.Type != Item.EType.FoilTradingCard && item.Type != Item.EType.TradingCard)) {
return false;
}
}
return true;
}
internal bool IsSteamCardsOnlyTradeForUs() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamContextID) && ((item.Type == Item.EType.FoilTradingCard) || (item.Type == Item.EType.TradingCard)));
internal bool IsPotentiallyDupesTradeForUs() {
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
Dictionary<uint, Dictionary<Item.EType, uint>> itemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToGive) {
Dictionary<Item.EType, uint> ItemsPerType;
if (!ItemsToGivePerGame.TryGetValue(item.RealAppID, out ItemsPerType)) {
ItemsPerType = new Dictionary<Item.EType, uint>();
ItemsPerType[item.Type] = item.Amount;
ItemsToGivePerGame[item.RealAppID] = ItemsPerType;
Dictionary<Item.EType, uint> itemsPerType;
if (!itemsToGivePerGame.TryGetValue(item.RealAppID, out itemsPerType)) {
itemsPerType = new Dictionary<Item.EType, uint> { [item.Type] = item.Amount };
itemsToGivePerGame[item.RealAppID] = itemsPerType;
} else {
uint amount;
if (ItemsPerType.TryGetValue(item.Type, out amount)) {
ItemsPerType[item.Type] = amount + item.Amount;
if (itemsPerType.TryGetValue(item.Type, out amount)) {
itemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
itemsPerType[item.Type] = item.Amount;
}
}
}
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToReceivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
Dictionary<uint, Dictionary<Item.EType, uint>> itemsToReceivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToReceive) {
Dictionary<Item.EType, uint> ItemsPerType;
if (!ItemsToReceivePerGame.TryGetValue(item.RealAppID, out ItemsPerType)) {
ItemsPerType = new Dictionary<Item.EType, uint>();
ItemsPerType[item.Type] = item.Amount;
ItemsToReceivePerGame[item.RealAppID] = ItemsPerType;
Dictionary<Item.EType, uint> itemsPerType;
if (!itemsToReceivePerGame.TryGetValue(item.RealAppID, out itemsPerType)) {
itemsPerType = new Dictionary<Item.EType, uint> { [item.Type] = item.Amount };
itemsToReceivePerGame[item.RealAppID] = itemsPerType;
} else {
uint amount;
if (ItemsPerType.TryGetValue(item.Type, out amount)) {
ItemsPerType[item.Type] = amount + item.Amount;
if (itemsPerType.TryGetValue(item.Type, out amount)) {
itemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
itemsPerType[item.Type] = item.Amount;
}
}
}
// Ensure that amount of items to give is at least amount of items to receive (per game and per type)
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> ItemsPerGame in ItemsToGivePerGame) {
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> itemsPerGame in itemsToGivePerGame) {
Dictionary<Item.EType, uint> otherItemsPerType;
if (!ItemsToReceivePerGame.TryGetValue(ItemsPerGame.Key, out otherItemsPerType)) {
if (!itemsToReceivePerGame.TryGetValue(itemsPerGame.Key, out otherItemsPerType)) {
return false;
}
foreach (KeyValuePair<Item.EType, uint> ItemsPerType in ItemsPerGame.Value) {
foreach (KeyValuePair<Item.EType, uint> itemsPerType in itemsPerGame.Value) {
uint otherAmount;
if (!otherItemsPerType.TryGetValue(ItemsPerType.Key, out otherAmount)) {
if (!otherItemsPerType.TryGetValue(itemsPerType.Key, out otherAmount)) {
return false;
}
if (ItemsPerType.Value > otherAmount) {
if (itemsPerType.Value > otherAmount) {
return false;
}
}
@@ -317,6 +309,7 @@ namespace ArchiSteamFarm {
}
}
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal sealed class TradeOfferRequest {
internal sealed class ItemList {
[JsonProperty(PropertyName = "assets", Required = Required.Always)]

View File

@@ -36,7 +36,10 @@ namespace ArchiSteamFarm {
internal static void Init() {
LogToFile = Program.GlobalConfig.LogToFile;
if (LogToFile) {
if (!LogToFile) {
return;
}
lock (FileLock) {
if (!LogToFile) {
return;
@@ -50,7 +53,6 @@ namespace ArchiSteamFarm {
}
}
}
}
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
@@ -69,6 +71,7 @@ namespace ArchiSteamFarm {
}
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
while (true) {
if (exception == null) {
return;
}
@@ -77,7 +80,11 @@ namespace ArchiSteamFarm {
Log("[!] StackTrace:" + Environment.NewLine + exception.StackTrace);
if (exception.InnerException != null) {
LogGenericException(exception.InnerException, botName, previousMethodName);
exception = exception.InnerException;
continue;
}
break;
}
}
@@ -102,9 +109,11 @@ namespace ArchiSteamFarm {
return;
}
// ReSharper disable once ExplicitCallerInfoArgument
LogGenericError(nullObjectName + " is null!", botName, previousMethodName);
}
// ReSharper disable once UnusedMember.Global
[Conditional("DEBUG")]
internal static void LogGenericDebug(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
@@ -125,10 +134,16 @@ namespace ArchiSteamFarm {
if (!Program.ConsoleIsBusy) {
try {
Console.Write(loggedMessage);
} catch { }
}
catch {
// Ignored
}
}
if (!LogToFile) {
return;
}
if (LogToFile) {
lock (FileLock) {
if (!LogToFile) {
return;
@@ -143,5 +158,4 @@ namespace ArchiSteamFarm {
}
}
}
}
}

View File

@@ -26,11 +26,13 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.JSON;
namespace ArchiSteamFarm {
internal static class Program {
@@ -49,21 +51,22 @@ namespace ArchiSteamFarm {
}
private enum EMode : byte {
[SuppressMessage("ReSharper", "UnusedMember.Local")]
Unknown,
Normal, // Standard most common usage
Client, // WCF client only
Server // Normal + WCF server
}
internal const string ASF = "ASF";
internal const string ConfigDirectory = "config";
internal const string DebugDirectory = "debug";
internal const string LogFile = "log.txt";
internal const string GithubRepo = "JustArchi/ArchiSteamFarm";
internal const string GlobalConfigFile = ASF + ".json";
internal const string GlobalDatabaseFile = ASF + ".db";
private const string ASF = "ASF";
private const string GithubReleaseURL = "https://api.github.com/repos/" + GithubRepo + "/releases"; // GitHub API is HTTPS only
private const string GlobalConfigFile = ASF + ".json";
private const string GlobalDatabaseFile = ASF + ".db";
internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
@@ -76,7 +79,7 @@ namespace ArchiSteamFarm {
internal static GlobalConfig GlobalConfig { get; private set; }
internal static GlobalDatabase GlobalDatabase { get; private set; }
internal static bool ConsoleIsBusy { get; private set; } = false;
internal static bool ConsoleIsBusy { get; private set; }
private static Timer AutoUpdatesTimer;
private static EMode Mode = EMode.Normal;
@@ -109,7 +112,7 @@ namespace ArchiSteamFarm {
string response = null;
Logging.LogGenericInfo("Checking new version...");
for (byte i = 0; i < WebBrowser.MaxRetries && string.IsNullOrEmpty(response); i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && string.IsNullOrEmpty(response); i++) {
response = await WebBrowser.UrlGetToContent(releaseURL).ConfigureAwait(false);
}
@@ -135,7 +138,7 @@ namespace ArchiSteamFarm {
return;
}
if (releases == null || releases.Count == 0) {
if ((releases == null) || (releases.Count == 0)) {
Logging.LogGenericWarning("Could not check latest version!");
return;
}
@@ -153,15 +156,19 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + newVersion);
if (Version.CompareTo(newVersion) >= 0) { // If local version is the same or newer than remote version
if (AutoUpdatesTimer == null && GlobalConfig.AutoUpdates) {
if ((AutoUpdatesTimer != null) || !GlobalConfig.AutoUpdates) {
return;
}
Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
AutoUpdatesTimer = new Timer(
async e => await CheckForUpdate().ConfigureAwait(false),
null,
TimeSpan.FromDays(1), // Delay
TimeSpan.FromDays(1) // Period
);
}
return;
}
@@ -183,15 +190,7 @@ namespace ArchiSteamFarm {
return;
}
GitHub.ReleaseResponse.Asset binaryAsset = null;
foreach (var asset in releaseResponse.Assets) {
if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase)) {
continue;
}
binaryAsset = asset;
break;
}
GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase));
if (binaryAsset == null) {
Logging.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!");
@@ -204,7 +203,7 @@ namespace ArchiSteamFarm {
}
byte[] result = null;
for (byte i = 0; i < WebBrowser.MaxRetries && result == null; i++) {
for (byte i = 0; (i < WebBrowser.MaxRetries) && (result == null); i++) {
Logging.LogGenericInfo("Downloading new version...");
result = await WebBrowser.UrlGetToBytes(binaryAsset.DownloadURL).ConfigureAwait(false);
}
@@ -232,7 +231,9 @@ namespace ArchiSteamFarm {
try {
// Cleanup
File.Delete(newExeFile);
} catch { }
} catch {
// Ignored
}
return;
}
@@ -245,7 +246,9 @@ namespace ArchiSteamFarm {
// Cleanup
File.Move(oldExeFile, ExecutableFile);
File.Delete(newExeFile);
} catch { }
} catch {
// Ignored
}
return;
}
@@ -326,6 +329,7 @@ namespace ArchiSteamFarm {
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter not documented yet value of \"" + userInputType + "\": ");
break;
}
result = Console.ReadLine();
if (!Console.IsOutputRedirected) {
Console.Clear(); // For security purposes
@@ -337,11 +341,9 @@ namespace ArchiSteamFarm {
}
internal static void OnBotShutdown() {
foreach (Bot bot in Bot.Bots.Values) {
if (bot.KeepRunning) {
if (Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
return;
}
}
if (WCF.IsServerRunning()) {
return;
@@ -374,7 +376,11 @@ namespace ArchiSteamFarm {
WebBrowser = new WebBrowser("Main");
}
private static void ParseArgs(string[] args) {
private static void ParseArgs(IEnumerable<string> args) {
if (args == null) {
return;
}
foreach (string arg in args) {
switch (arg) {
case "--client":
@@ -385,7 +391,7 @@ namespace ArchiSteamFarm {
WCF.StartServer();
break;
default:
if (arg.StartsWith("--")) {
if (arg.StartsWith("--", StringComparison.Ordinal)) {
Logging.LogGenericWarning("Unrecognized parameter: " + arg);
continue;
}
@@ -410,7 +416,7 @@ namespace ArchiSteamFarm {
}
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
if (sender == null || args == null) {
if ((sender == null) || (args == null)) {
return;
}
@@ -418,14 +424,14 @@ namespace ArchiSteamFarm {
}
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
if (sender == null || args == null) {
if ((sender == null) || (args == null)) {
return;
}
Logging.LogGenericException(args.Exception);
}
private static void Init(string[] args) {
private static void Init(IEnumerable<string> args) {
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
@@ -437,7 +443,7 @@ namespace ArchiSteamFarm {
if (Debugging.IsDebugBuild) {
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
for (var i = 0; i < 4; i++) {
for (byte i = 0; i < 4; i++) {
Directory.SetCurrentDirectory("..");
if (Directory.Exists(ConfigDirectory)) {
break;
@@ -458,7 +464,7 @@ namespace ArchiSteamFarm {
}
Directory.CreateDirectory(DebugDirectory);
SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(Program.DebugDirectory, "debug.txt")));
SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(DebugDirectory, "debug.txt")));
SteamKit2.DebugLog.Enabled = true;
}
@@ -486,8 +492,7 @@ namespace ArchiSteamFarm {
bool isRunning = false;
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.json")) {
string botName = Path.GetFileNameWithoutExtension(configFile);
foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
switch (botName) {
case ASF:
case "example":
@@ -496,7 +501,7 @@ namespace ArchiSteamFarm {
}
Bot bot = new Bot(botName);
if (bot.BotConfig != null && bot.BotConfig.Enabled) {
if ((bot.BotConfig != null) && bot.BotConfig.Enabled) {
if (bot.BotConfig.StartOnLaunch) {
isRunning = true;
}

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@@ -25,8 +25,10 @@
using SteamAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.JSON;
namespace ArchiSteamFarm {
internal sealed class Trading {
@@ -50,7 +52,7 @@ namespace ArchiSteamFarm {
internal Trading(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
@@ -77,7 +79,7 @@ namespace ArchiSteamFarm {
private async Task ParseActiveTrades() {
HashSet<Steam.TradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
if (tradeOffers == null || tradeOffers.Count == 0) {
if ((tradeOffers == null) || (tradeOffers.Count == 0)) {
return;
}
@@ -86,7 +88,7 @@ namespace ArchiSteamFarm {
}
private async Task ParseTrade(Steam.TradeOffer tradeOffer) {
if (tradeOffer == null || tradeOffer.State != Steam.TradeOffer.ETradeOfferState.Active) {
if ((tradeOffer == null) || (tradeOffer.State != Steam.TradeOffer.ETradeOfferState.Active)) {
return;
}
@@ -110,7 +112,7 @@ namespace ArchiSteamFarm {
}
// Always accept trades from SteamMasterID
if (tradeOffer.OtherSteamID64 != 0 && tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID) {
if ((tradeOffer.OtherSteamID64 != 0) && (tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID)) {
return true;
}
@@ -132,7 +134,7 @@ namespace ArchiSteamFarm {
// At this point we're sure that STM trade is valid
// Now check if it's worth for us to do the trade
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMyTradableInventory().ConfigureAwait(false);
if (inventory == null || inventory.Count == 0) {
if ((inventory == null) || (inventory.Count == 0)) {
return true; // OK, assume that this trade is valid, we can't check our EQ
}
@@ -166,9 +168,7 @@ namespace ArchiSteamFarm {
// Calculate our value of items to give
List<uint> amountsToGive = new List<uint>(tradeOffer.ItemsToGive.Count);
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
foreach (Tuple<ulong, ulong> key in tradeOffer.ItemsToGive.Select(item => new Tuple<ulong, ulong>(item.ClassID, item.InstanceID))) {
uint amount;
if (!amountMap.TryGetValue(key, out amount)) {
amountsToGive.Add(0);
@@ -183,9 +183,7 @@ namespace ArchiSteamFarm {
// Calculate our value of items to receive
List<uint> amountsToReceive = new List<uint>(tradeOffer.ItemsToReceive.Count);
foreach (Steam.Item item in tradeOffer.ItemsToReceive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
foreach (Tuple<ulong, ulong> key in tradeOffer.ItemsToReceive.Select(item => new Tuple<ulong, ulong>(item.ClassID, item.InstanceID))) {
uint amount;
if (!amountMap.TryGetValue(key, out amount)) {
amountsToReceive.Add(0);
@@ -199,10 +197,7 @@ namespace ArchiSteamFarm {
amountsToReceive.Sort();
// Check actual difference
int difference = 0;
for (int i = 0; i < amountsToGive.Count; i++) {
difference += (int) (amountsToGive[i] - amountsToReceive[i]);
}
int difference = amountsToGive.Select((t, i) => (int) (t - amountsToReceive[i])).Sum();
// Trade is worth for us if the difference is greater than 0
return difference > 0;

View File

@@ -30,43 +30,20 @@ using System.Threading.Tasks;
namespace ArchiSteamFarm {
internal static class Utilities {
// ReSharper disable once UnusedParameter.Global
internal static void Forget(this Task task) { }
internal static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
if (action == null) {
return Task.FromResult(true);
}
internal static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) => action == null ? Task.FromResult(true) : Task.WhenAll(sequence.Select(action));
return Task.WhenAll(sequence.Select(action));
}
internal static string GetCookieValue(this CookieContainer cookieContainer, string URL, string name) {
if (string.IsNullOrEmpty(URL) || string.IsNullOrEmpty(name)) {
internal static string GetCookieValue(this CookieContainer cookieContainer, string url, string name) {
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(name)) {
return null;
}
CookieCollection cookies = cookieContainer.GetCookies(new Uri(URL));
if (cookies == null || cookies.Count == 0) {
return null;
CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));
return cookies.Count == 0 ? null : (from Cookie cookie in cookies where cookie.Name.Equals(name, StringComparison.Ordinal) select cookie.Value).FirstOrDefault();
}
foreach (Cookie cookie in cookies) {
if (!cookie.Name.Equals(name, StringComparison.Ordinal)) {
continue;
}
return cookie.Value;
}
return null;
}
internal static Task SleepAsync(int miliseconds) {
if (miliseconds < 0) {
return Task.FromResult(true);
}
return Task.Delay(miliseconds);
}
internal static Task SleepAsync(int miliseconds) => miliseconds < 0 ? Task.FromResult(true) : Task.Delay(miliseconds);
}
}

View File

@@ -52,9 +52,7 @@ namespace ArchiSteamFarm {
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
}
internal bool IsServerRunning() {
return ServiceHost != null;
}
internal bool IsServerRunning() => ServiceHost != null;
internal void StartServer() {
if (ServiceHost != null) {

View File

@@ -27,7 +27,6 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
@@ -65,7 +64,7 @@ namespace ArchiSteamFarm {
internal WebBrowser(string identifier) {
if (string.IsNullOrEmpty(identifier)) {
throw new ArgumentNullException("identifier");
throw new ArgumentNullException(nameof(identifier));
}
Identifier = identifier;
@@ -99,11 +98,7 @@ namespace ArchiSteamFarm {
}
using (HttpResponseMessage response = await UrlHeadToResponse(request, referer).ConfigureAwait(false)) {
if (response == null) {
return null;
}
return response.RequestMessage.RequestUri;
return response == null ? null : response.RequestMessage.RequestUri;
}
}
@@ -229,7 +224,7 @@ namespace ArchiSteamFarm {
}
private async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, string referer = null) {
if (string.IsNullOrEmpty(request) || httpMethod == null) {
if (string.IsNullOrEmpty(request) || (httpMethod == null)) {
return null;
}
@@ -239,7 +234,7 @@ namespace ArchiSteamFarm {
HttpResponseMessage responseMessage;
using (HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request)) {
if (data != null && data.Count > 0) {
if ((data != null) && (data.Count > 0)) {
try {
requestMessage.Content = new FormUrlEncodedContent(data);
} catch (UriFormatException e) {
@@ -263,17 +258,18 @@ namespace ArchiSteamFarm {
return null;
}
if (!responseMessage.IsSuccessStatusCode) {
if (responseMessage.IsSuccessStatusCode) {
return responseMessage;
}
if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
Logging.LogGenericError("Request: " + request + " failed!", Identifier);
Logging.LogGenericError("Status code: " + responseMessage.StatusCode, Identifier);
Logging.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false), Identifier);
}
responseMessage.Dispose();
return null;
}
return responseMessage;
}
}
}

View File

@@ -39,13 +39,13 @@ namespace ConfigGenerator {
protected ASFConfig(string filePath) : this() {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
}
internal virtual void Save() {
internal void Save() {
lock (FilePath) {
try {
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
@@ -55,7 +55,7 @@ namespace ConfigGenerator {
}
}
internal virtual void Remove() {
internal void Remove() {
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
lock (FilePath) {
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
@@ -66,10 +66,11 @@ namespace ConfigGenerator {
}
}
}
ASFConfigs.Remove(this);
}
internal virtual void Rename(string botName) {
internal void Rename(string botName) {
if (string.IsNullOrEmpty(botName)) {
return;
}
@@ -83,6 +84,7 @@ namespace ConfigGenerator {
Logging.LogGenericException(e);
}
}
FilePath = Path.Combine(Program.ConfigDirectory, botName + ".json");
}
}

View File

@@ -26,9 +26,11 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
namespace ConfigGenerator {
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global"), SuppressMessage("ReSharper", "CollectionNeverQueried.Global"), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "UnusedMember.Global")]
internal sealed class BotConfig : ASFConfig {
[JsonProperty(Required = Required.DisallowNull)]
public bool Enabled { get; set; } = false;
@@ -39,8 +41,7 @@ namespace ConfigGenerator {
[JsonProperty]
public string SteamLogin { get; set; } = null;
[JsonProperty]
[PasswordPropertyText(true)]
[JsonProperty, PasswordPropertyText(true)]
public string SteamPassword { get; set; } = null;
[JsonProperty]
@@ -130,11 +131,12 @@ namespace ConfigGenerator {
}
// This constructor is used only by deserializer
// ReSharper disable once UnusedMember.Local
private BotConfig() { }
private BotConfig(string filePath) : base(filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
GamesPlayedWhileIdle.Add(0);

View File

@@ -83,6 +83,7 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">

View File

@@ -42,8 +42,6 @@ namespace ConfigGenerator {
Controls.Add(enhancedPropertyGrid);
}
internal void RefreshText() {
Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
}
internal void RefreshText() => Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
}
}

View File

@@ -25,11 +25,11 @@
namespace ConfigGenerator {
internal static class Debugging {
#if DEBUG
// ReSharper disable once ConvertToConstant.Global
internal static readonly bool IsDebugBuild = true;
#else
// ReSharper disable once ConvertToConstant.Global
internal static readonly bool IsDebugBuild = false;
#endif
internal static bool IsReleaseBuild => !IsDebugBuild;
}
}

View File

@@ -25,50 +25,53 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using ConfigGenerator.Properties;
namespace ConfigGenerator {
internal sealed class DialogBox {
internal static class DialogBox {
internal static DialogResult InputBox(string title, string promptText, out string value) {
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(promptText)) {
value = null;
return DialogResult.Abort;
}
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
TextBox textBox = new TextBox {
Anchor = AnchorStyles.Right,
Bounds = new Rectangle(12, 36, 372, 20),
Width = 1000
};
textBox.Width = 1000;
Button buttonOk = new Button();
Button buttonCancel = new Button();
Button buttonOk = new Button {
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
Bounds = new Rectangle(228, 72, 75, 23),
DialogResult = DialogResult.OK,
Text = Resources.OK
};
form.Text = title;
label.Text = promptText;
Button buttonCancel = new Button {
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
Bounds = new Rectangle(309, 72, 75, 23),
DialogResult = DialogResult.Cancel,
Text = Resources.Cancel
};
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
Label label = new Label {
AutoSize = true,
Bounds = new Rectangle(9, 20, 372, 13),
Text = promptText
};
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonCancel.SetBounds(309, 72, 75, 23);
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
Form form = new Form {
AcceptButton = buttonOk,
CancelButton = buttonCancel,
ClientSize = new Size(Math.Max(300, label.Right + 10), 107),
Controls = { label, textBox, buttonOk, buttonCancel },
FormBorderStyle = FormBorderStyle.FixedDialog,
MinimizeBox = false,
MaximizeBox = false,
StartPosition = FormStartPosition.CenterScreen,
Text = title
};
DialogResult dialogResult = form.ShowDialog();
value = textBox.Text;
@@ -80,37 +83,37 @@ namespace ConfigGenerator {
return DialogResult.Abort;
}
Form form = new Form();
Label label = new Label();
Button buttonYes = new Button {
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
Bounds = new Rectangle(228, 72, 75, 23),
DialogResult = DialogResult.Yes,
Text = Resources.Yes
};
Button buttonOk = new Button();
Button buttonCancel = new Button();
Button buttonNo = new Button {
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
Bounds = new Rectangle(309, 72, 75, 23),
DialogResult = DialogResult.No,
Text = Resources.No
};
form.Text = title;
label.Text = promptText;
Label label = new Label {
AutoSize = true,
Bounds = new Rectangle(9, 20, 372, 13),
Text = promptText
};
buttonOk.Text = "Yes";
buttonCancel.Text = "No";
buttonOk.DialogResult = DialogResult.Yes;
buttonCancel.DialogResult = DialogResult.No;
label.SetBounds(9, 20, 372, 13);
buttonOk.SetBounds(228, 50, 75, 23);
buttonCancel.SetBounds(309, 50, 75, 23);
label.AutoSize = true;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 80);
form.Controls.AddRange(new Control[] { label, buttonOk, buttonCancel });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
Form form = new Form {
AcceptButton = buttonYes,
CancelButton = buttonNo,
ClientSize = new Size(Math.Max(300, label.Right + 10), 107),
Controls = { label, buttonYes, buttonNo },
FormBorderStyle = FormBorderStyle.FixedDialog,
MinimizeBox = false,
MaximizeBox = false,
StartPosition = FormStartPosition.CenterScreen,
Text = title
};
DialogResult dialogResult = form.ShowDialog();
return dialogResult;

View File

@@ -31,7 +31,7 @@ namespace ConfigGenerator {
internal EnhancedPropertyGrid(ASFConfig config) {
if (config == null) {
throw new ArgumentNullException("config");
throw new ArgumentNullException(nameof(config));
}
ASFConfig = config;
@@ -53,22 +53,26 @@ namespace ConfigGenerator {
BotConfig botConfig = ASFConfig as BotConfig;
if (botConfig != null) {
if (botConfig.Enabled) {
if (!botConfig.Enabled) {
return;
}
Tutorial.OnAction(Tutorial.EPhase.BotEnabled);
if (!string.IsNullOrEmpty(botConfig.SteamLogin) && !string.IsNullOrEmpty(botConfig.SteamPassword)) {
Tutorial.OnAction(Tutorial.EPhase.BotReady);
}
}
return;
}
GlobalConfig globalConfig = ASFConfig as GlobalConfig;
if (globalConfig != null) {
if (globalConfig == null) {
return;
}
if (globalConfig.SteamOwnerID != 0) {
Tutorial.OnAction(Tutorial.EPhase.GlobalConfigReady);
}
}
}
protected override void OnGotFocus(EventArgs e) {
if (e == null) {

View File

@@ -25,11 +25,14 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Sockets;
namespace ConfigGenerator {
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global"), SuppressMessage("ReSharper", "CollectionNeverQueried.Global"), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "UnusedMember.Global")]
internal sealed class GlobalConfig : ASFConfig {
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal enum EUpdateChannel : byte {
Unknown,
Stable,
@@ -43,7 +46,7 @@ namespace ConfigGenerator {
private const ProtocolType DefaultSteamProtocol = ProtocolType.Tcp;
// This is hardcoded blacklist which should not be possible to change
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
private static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
[JsonProperty(Required = Required.DisallowNull)]
public bool Debug { get; set; } = false;
@@ -102,7 +105,6 @@ namespace ConfigGenerator {
[JsonProperty(Required = Required.DisallowNull)]
public bool Statistics { get; set; } = true;
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
[JsonProperty(Required = Required.DisallowNull)]
public bool HackIgnoreMachineID { get; set; } = false;
@@ -161,20 +163,22 @@ namespace ConfigGenerator {
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
if (globalConfig.WCFPort != 0) {
return globalConfig;
}
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
}
return globalConfig;
}
// This constructor is used only by deserializer
// ReSharper disable once UnusedMember.Local
private GlobalConfig() { }
private GlobalConfig(string filePath) : base(filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
Blacklist.AddRange(GlobalBlacklist);

View File

@@ -23,9 +23,9 @@
*/
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using ConfigGenerator.Properties;
namespace ConfigGenerator {
internal static class Logging {
@@ -34,15 +34,7 @@ namespace ConfigGenerator {
return;
}
MessageBox.Show(message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
internal static void LogGenericWTF(string message, [CallerMemberName] string previousMethodName = "") {
if (string.IsNullOrEmpty(message)) {
return;
}
MessageBox.Show(previousMethodName + "() " + message, "WTF", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(message, Resources.Information, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
internal static void LogGenericError(string message, [CallerMemberName] string previousMethodName = "") {
@@ -50,18 +42,23 @@ namespace ConfigGenerator {
return;
}
MessageBox.Show(previousMethodName + "() " + message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(previousMethodName + @"() " + message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") {
while (true) {
if (exception == null) {
return;
}
MessageBox.Show(previousMethodName + "() " + exception.Message + Environment.NewLine + exception.StackTrace, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(previousMethodName + @"() " + exception.Message + Environment.NewLine + exception.StackTrace, Resources.Exception, MessageBoxButtons.OK, MessageBoxIcon.Error);
if (exception.InnerException != null) {
LogGenericException(exception.InnerException, previousMethodName);
exception = exception.InnerException;
continue;
}
break;
}
}
@@ -70,24 +67,7 @@ namespace ConfigGenerator {
return;
}
MessageBox.Show(previousMethodName + "() " + message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
internal static void LogNullError(string nullObjectName, [CallerMemberName] string previousMethodName = "") {
if (string.IsNullOrEmpty(nullObjectName)) {
return;
}
LogGenericError(nullObjectName + " is null!", previousMethodName);
}
[Conditional("DEBUG")]
internal static void LogGenericDebug(string message, [CallerMemberName] string previousMethodName = "") {
if (string.IsNullOrEmpty(message)) {
return;
}
MessageBox.Show(previousMethodName + "() " + message, "Debug", MessageBoxButtons.OK, MessageBoxIcon.Information);
MessageBox.Show(previousMethodName + @"() " + message, Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}

View File

@@ -26,6 +26,7 @@ using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
@@ -33,9 +34,9 @@ namespace ConfigGenerator {
internal sealed partial class MainForm : Form {
private const byte ReservedTabs = 3;
private readonly TabPage NewTab = new TabPage { Text = "+" };
private readonly TabPage RemoveTab = new TabPage { Text = "-" };
private readonly TabPage RenameTab = new TabPage { Text = "~" };
private readonly TabPage NewTab = new TabPage { Text = @"+" };
private readonly TabPage RemoveTab = new TabPage { Text = @"-" };
private readonly TabPage RenameTab = new TabPage { Text = @"~" };
private ConfigPage ASFTab;
private TabPage OldTab;
@@ -45,7 +46,7 @@ namespace ConfigGenerator {
}
private void MainForm_Load(object sender, EventArgs e) {
if (sender == null || e == null) {
if ((sender == null) || (e == null)) {
return;
}
@@ -53,7 +54,7 @@ namespace ConfigGenerator {
MainTab.TabPages.Add(ASFTab);
foreach (var configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) {
foreach (string configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) {
string botName = Path.GetFileNameWithoutExtension(configFile);
switch (botName) {
case Program.ASF:
@@ -71,7 +72,7 @@ namespace ConfigGenerator {
}
private void MainTab_Selected(object sender, TabControlEventArgs e) {
if (sender == null || e == null) {
if ((sender == null) || (e == null)) {
return;
}
@@ -151,12 +152,10 @@ namespace ConfigGenerator {
// Get rid of any potential whitespaces in bot name
input = Regex.Replace(input, @"\s+", "");
foreach (ASFConfig config in ASFConfig.ASFConfigs) {
if (Path.GetFileNameWithoutExtension(config.FilePath).Equals(input)) {
if (ASFConfig.ASFConfigs.Select(config => Path.GetFileNameWithoutExtension(config.FilePath)).Any(fileNameWithoutExtension => (fileNameWithoutExtension == null) || fileNameWithoutExtension.Equals(input))) {
Logging.LogGenericError("Bot with such name exists already!");
return;
}
}
input = Path.Combine(Program.ConfigDirectory, input + ".json");
@@ -170,7 +169,7 @@ namespace ConfigGenerator {
}
private void MainTab_Deselecting(object sender, TabControlCancelEventArgs e) {
if (sender == null || e == null) {
if ((sender == null) || (e == null)) {
return;
}
@@ -178,7 +177,7 @@ namespace ConfigGenerator {
}
private void MainForm_Shown(object sender, EventArgs e) {
if (sender == null || e == null) {
if ((sender == null) || (e == null)) {
return;
}
@@ -186,7 +185,7 @@ namespace ConfigGenerator {
}
private void MainForm_HelpButtonClicked(object sender, CancelEventArgs e) {
if (sender == null || e == null) {
if ((sender == null) || (e == null)) {
return;
}

View File

@@ -61,11 +61,13 @@ namespace ConfigGenerator {
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
for (byte i = 0; i < 4; i++) {
Directory.SetCurrentDirectory("..");
if (Directory.Exists(ASFDirectory)) {
if (!Directory.Exists(ASFDirectory)) {
continue;
}
Directory.SetCurrentDirectory(ASFDirectory);
break;
}
}
// If config directory doesn't exist after our adjustment, abort all of that
if (!Directory.Exists(ConfigDirectory)) {
@@ -73,14 +75,16 @@ namespace ConfigGenerator {
}
}
if (!Directory.Exists(ConfigDirectory)) {
if (Directory.Exists(ConfigDirectory)) {
return;
}
Logging.LogGenericError("Config directory could not be found!");
Environment.Exit(1);
}
}
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
if (sender == null || args == null) {
if ((sender == null) || (args == null)) {
return;
}
@@ -88,7 +92,7 @@ namespace ConfigGenerator {
}
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
if (sender == null || args == null) {
if ((sender == null) || (args == null)) {
return;
}

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@@ -9,6 +9,7 @@
//------------------------------------------------------------------------------
namespace ConfigGenerator.Properties {
using System;
/// <summary>
@@ -37,7 +38,7 @@ namespace ConfigGenerator.Properties {
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConfigGenerator.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
@@ -58,5 +59,77 @@ namespace ConfigGenerator.Properties {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Cancel.
/// </summary>
internal static string Cancel {
get {
return ResourceManager.GetString("Cancel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error.
/// </summary>
internal static string Error {
get {
return ResourceManager.GetString("Error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Exception.
/// </summary>
internal static string Exception {
get {
return ResourceManager.GetString("Exception", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Information.
/// </summary>
internal static string Information {
get {
return ResourceManager.GetString("Information", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No.
/// </summary>
internal static string No {
get {
return ResourceManager.GetString("No", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to OK.
/// </summary>
internal static string OK {
get {
return ResourceManager.GetString("OK", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warning.
/// </summary>
internal static string Warning {
get {
return ResourceManager.GetString("Warning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Yes.
/// </summary>
internal static string Yes {
get {
return ResourceManager.GetString("Yes", resourceCulture);
}
}
}
}

View File

@@ -114,4 +114,28 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Information" xml:space="preserve">
<value>Information</value>
</data>
<data name="Error" xml:space="preserve">
<value>Error</value>
</data>
<data name="Exception" xml:space="preserve">
<value>Exception</value>
</data>
<data name="Warning" xml:space="preserve">
<value>Warning</value>
</data>
<data name="OK" xml:space="preserve">
<value>OK</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Yes</value>
</data>
<data name="No" xml:space="preserve">
<value>No</value>
</data>
</root>

View File

@@ -38,12 +38,12 @@ namespace ConfigGenerator {
GlobalConfigReady
}
internal static bool Enabled { get; set; } = true;
internal static bool Enabled { private get; set; } = true;
private static EPhase NextPhase = EPhase.Start;
internal static void OnAction(EPhase phase) {
if (!Enabled || phase != NextPhase) {
if (!Enabled || (phase != NextPhase)) {
return;
}