mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-06 17:10:13 +00:00
Many internal async improvements
This commit is contained in:
@@ -75,12 +75,14 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void ShutdownAllBots() {
|
||||
internal static async Task ShutdownAllBots() {
|
||||
List<Task> tasks = new List<Task>();
|
||||
lock (Bots) {
|
||||
foreach (Bot bot in Bots) {
|
||||
bot.Shutdown();
|
||||
tasks.Add(Task.Run(async () => await bot.Shutdown().ConfigureAwait(false)));
|
||||
}
|
||||
}
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal Bot(string botName) {
|
||||
@@ -203,26 +205,27 @@ namespace ArchiSteamFarm {
|
||||
Task.Run(() => HandleCallbacks());
|
||||
}
|
||||
|
||||
internal void Stop() {
|
||||
internal async Task Stop() {
|
||||
if (!IsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
await CardsFarmer.StopFarming().ConfigureAwait(false);
|
||||
SteamClient.Disconnect();
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
internal void Shutdown() {
|
||||
Stop();
|
||||
internal async Task Shutdown() {
|
||||
await Stop().ConfigureAwait(false);
|
||||
lock (Bots) {
|
||||
Bots.Remove(this);
|
||||
}
|
||||
Program.OnBotShutdown(this);
|
||||
}
|
||||
|
||||
internal void OnFarmingFinished() {
|
||||
internal async Task OnFarmingFinished() {
|
||||
if (ShutdownOnFarmingFinished) {
|
||||
Shutdown();
|
||||
await Shutdown().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +315,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFriendMsg(SteamFriends.FriendMsgCallback callback) {
|
||||
private async void OnFriendMsg(SteamFriends.FriendMsgCallback callback) {
|
||||
if (callback == null) {
|
||||
return;
|
||||
}
|
||||
@@ -334,6 +337,15 @@ namespace ArchiSteamFarm {
|
||||
if (message.Length == 17 && message[5] == '-' && message[11] == '-') {
|
||||
ArchiHandler.RedeemKey(message);
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case "!farm":
|
||||
await CardsFarmer.StartFarming().ConfigureAwait(false);
|
||||
break;
|
||||
case "!exit":
|
||||
await Shutdown().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPersonaState(SteamFriends.PersonaStateCallback callback) {
|
||||
@@ -405,13 +417,13 @@ namespace ArchiSteamFarm {
|
||||
case EResult.Timeout:
|
||||
case EResult.TryAnotherCM:
|
||||
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult + ", retrying...");
|
||||
Stop();
|
||||
await Stop().ConfigureAwait(false);
|
||||
Thread.Sleep(5000);
|
||||
Start();
|
||||
break;
|
||||
default:
|
||||
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult);
|
||||
Shutdown();
|
||||
await Shutdown().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,20 +31,32 @@ namespace ArchiSteamFarm {
|
||||
internal class CardsFarmer {
|
||||
private const byte StatusCheckSleep = 5; // In minutes, how long to wait before checking the appID again
|
||||
|
||||
private readonly ManualResetEvent FarmResetEvent = new ManualResetEvent(false);
|
||||
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
||||
private readonly Bot Bot;
|
||||
private bool NowFarming;
|
||||
private readonly AutoResetEvent AutoResetEvent = new AutoResetEvent(false);
|
||||
|
||||
private volatile bool NowFarming = false;
|
||||
|
||||
internal CardsFarmer(Bot bot) {
|
||||
Bot = bot;
|
||||
}
|
||||
|
||||
internal async Task StartFarming() {
|
||||
await StopFarming().ConfigureAwait(false);
|
||||
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
if (NowFarming) {
|
||||
Semaphore.Release();
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo(Bot.BotName, "Checking badges...");
|
||||
// Find the number of badge pages
|
||||
HtmlDocument badgesDocument = await Bot.ArchiWebHandler.GetBadgePage(1).ConfigureAwait(false);
|
||||
if (badgesDocument == null) {
|
||||
Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, farming is stopped!");
|
||||
Semaphore.Release();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +116,26 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo(Bot.BotName, "Farming finished!");
|
||||
Bot.OnFarmingFinished();
|
||||
await Bot.OnFarmingFinished().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task StopFarming() {
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
if (!NowFarming) {
|
||||
Semaphore.Release();
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo(Bot.BotName, "Sending signal to stop farming");
|
||||
FarmResetEvent.Set();
|
||||
while (NowFarming) {
|
||||
Logging.LogGenericInfo(Bot.BotName, "Waiting for reaction...");
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
FarmResetEvent.Reset();
|
||||
Logging.LogGenericInfo(Bot.BotName, "Farming stopped!");
|
||||
Semaphore.Release();
|
||||
}
|
||||
|
||||
private async Task<bool?> ShouldFarm(ulong appID) {
|
||||
@@ -120,12 +151,6 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private async Task<bool> Farm(ulong appID) {
|
||||
if (NowFarming) {
|
||||
AutoResetEvent.Set();
|
||||
Thread.Sleep(1000);
|
||||
AutoResetEvent.Reset();
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||
while (keepFarming == null || keepFarming.Value) {
|
||||
@@ -133,17 +158,20 @@ namespace ArchiSteamFarm {
|
||||
NowFarming = true;
|
||||
Logging.LogGenericInfo(Bot.BotName, "Now farming: " + appID);
|
||||
Bot.PlayGame(appID);
|
||||
Semaphore.Release(); // We're farming, allow other tasks to shut us down
|
||||
} else {
|
||||
Logging.LogGenericInfo(Bot.BotName, "Still farming: " + appID);
|
||||
}
|
||||
if (AutoResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
|
||||
if (FarmResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo(Bot.BotName, "Stopped farming: " + appID);
|
||||
Bot.PlayGame(0);
|
||||
NowFarming = false;
|
||||
Logging.LogGenericInfo(Bot.BotName, "Stopped farming: " + appID);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,11 +66,16 @@ namespace ArchiSteamFarm {
|
||||
Logging.LogGenericNotice("", "Remote version: " + remoteVersion);
|
||||
Logging.LogGenericNotice("", "Consider updating yourself!");
|
||||
Thread.Sleep(5000);
|
||||
} else if (localVersion.CompareTo(remoteVersion) > 0) {
|
||||
Logging.LogGenericNotice("", "You're currently using pre-release version!");
|
||||
Logging.LogGenericNotice("", "Local version: " + localVersion);
|
||||
Logging.LogGenericNotice("", "Remote version: " + remoteVersion);
|
||||
Logging.LogGenericNotice("", "Be careful!");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Exit(int exitCode = 0) {
|
||||
Bot.ShutdownAllBots();
|
||||
internal static async Task Exit(int exitCode = 0) {
|
||||
await Bot.ShutdownAllBots().ConfigureAwait(false);
|
||||
Environment.Exit(exitCode);
|
||||
}
|
||||
|
||||
@@ -121,8 +126,8 @@ namespace ArchiSteamFarm {
|
||||
if (!Directory.Exists(ConfigDirectoryPath)) {
|
||||
Logging.LogGenericError("Main", "Config directory doesn't exist!");
|
||||
Console.ReadLine();
|
||||
Exit(1);
|
||||
}
|
||||
Task.Run(async () => await Exit(1).ConfigureAwait(false)).Wait();
|
||||
}
|
||||
|
||||
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectoryPath, "*.xml")) {
|
||||
string botName = Path.GetFileNameWithoutExtension(configFile);
|
||||
|
||||
@@ -28,9 +28,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class Trading {
|
||||
private Bot Bot;
|
||||
private readonly Bot Bot;
|
||||
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
||||
private volatile byte ParsingTasks = 0;
|
||||
private SemaphoreSlim semaphore = new SemaphoreSlim(1);
|
||||
|
||||
internal Trading(Bot bot) {
|
||||
Bot = bot;
|
||||
@@ -44,7 +44,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private async Task ParseActiveTrades() {
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
List<SteamTradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
|
||||
if (tradeOffers != null) {
|
||||
@@ -62,7 +62,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
ParsingTasks--;
|
||||
semaphore.Release();
|
||||
Semaphore.Release();
|
||||
}
|
||||
|
||||
private async Task ParseTrade(SteamTradeOffer tradeOffer) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- When no bots are active, ASF will shutdown as well -->
|
||||
<!-- Some people may want to keep their bots 24/7, other disconnect them after job is done -->
|
||||
<!-- Choose yourself what you prefer -->
|
||||
<ShutdownOnFarmingFinished type="bool" value="true"/>
|
||||
<ShutdownOnFarmingFinished type="bool" value="false"/>
|
||||
|
||||
<!-- Comma-separated list of IDs that should not be considered for farming -->
|
||||
<!-- TIP: Most likely you don't want to change it -->
|
||||
|
||||
Reference in New Issue
Block a user