mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-05-02 04:22:04 -04:00
Added a lot more error handling to the bot so issues retrieving tokens should no longer completely take the bot down. Also added a last ditch exit if the bot has completely died and isn't reconnecting at all
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Humanizer;
|
|
||||||
using KfChatDotNetBot.Models;
|
using KfChatDotNetBot.Models;
|
||||||
using KfChatDotNetBot.Models.DbModels;
|
using KfChatDotNetBot.Models.DbModels;
|
||||||
using KfChatDotNetBot.Services;
|
using KfChatDotNetBot.Services;
|
||||||
@@ -11,7 +9,6 @@ using KfChatDotNetWsClient.Models;
|
|||||||
using KfChatDotNetWsClient.Models.Events;
|
using KfChatDotNetWsClient.Models.Events;
|
||||||
using KfChatDotNetWsClient.Models.Json;
|
using KfChatDotNetWsClient.Models.Json;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.IO;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using Websocket.Client;
|
using Websocket.Client;
|
||||||
|
|
||||||
@@ -34,11 +31,14 @@ public class ChatBot
|
|||||||
private Task _kfChatPing;
|
private Task _kfChatPing;
|
||||||
private KfTokenService _kfTokenService;
|
private KfTokenService _kfTokenService;
|
||||||
private int _joinFailures = 0;
|
private int _joinFailures = 0;
|
||||||
|
private Task _kfDeadBotDetection;
|
||||||
|
private DateTime _lastReconnectAttempt = DateTime.UtcNow;
|
||||||
|
|
||||||
public ChatBot()
|
public ChatBot()
|
||||||
{
|
{
|
||||||
_logger.Info("Bot starting!");
|
_logger.Info("Bot starting!");
|
||||||
|
|
||||||
|
_kfDeadBotDetection = KfDeadBotDetectionTask();
|
||||||
var settings = SettingsProvider.GetMultipleValuesAsync([
|
var settings = SettingsProvider.GetMultipleValuesAsync([
|
||||||
BuiltIn.Keys.KiwiFarmsWsEndpoint, BuiltIn.Keys.KiwiFarmsDomain,
|
BuiltIn.Keys.KiwiFarmsWsEndpoint, BuiltIn.Keys.KiwiFarmsDomain,
|
||||||
BuiltIn.Keys.Proxy, BuiltIn.Keys.KiwiFarmsWsReconnectTimeout]).Result;
|
BuiltIn.Keys.Proxy, BuiltIn.Keys.KiwiFarmsWsReconnectTimeout]).Result;
|
||||||
@@ -57,7 +57,15 @@ public class ChatBot
|
|||||||
|
|
||||||
if (_kfTokenService.GetXfSessionCookie() == null)
|
if (_kfTokenService.GetXfSessionCookie() == null)
|
||||||
{
|
{
|
||||||
RefreshXfToken().Wait(_cancellationToken);
|
try
|
||||||
|
{
|
||||||
|
RefreshXfToken().Wait(_cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error("Caught an exception while trying to refresh the XF token");
|
||||||
|
_logger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Creating bot command instance");
|
_logger.Debug("Creating bot command instance");
|
||||||
@@ -95,7 +103,16 @@ public class ChatBot
|
|||||||
_logger.Error("Seems we're in a rejoin loop. Wiping out cookies entirely in hopes it'll make this piece of shit work");
|
_logger.Error("Seems we're in a rejoin loop. Wiping out cookies entirely in hopes it'll make this piece of shit work");
|
||||||
_kfTokenService.WipeCookies();
|
_kfTokenService.WipeCookies();
|
||||||
}
|
}
|
||||||
RefreshXfToken().Wait(_cancellationToken);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RefreshXfToken().Wait(_cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error("Caught an exception while trying to refresh the XF token");
|
||||||
|
_logger.Error(e);
|
||||||
|
}
|
||||||
_kfTokenService.SaveCookies().Wait(_cancellationToken);
|
_kfTokenService.SaveCookies().Wait(_cancellationToken);
|
||||||
// Shouldn't be null if we've just refreshed the token
|
// Shouldn't be null if we've just refreshed the token
|
||||||
// It's only null if a logon has never been attempted since the cookie DB entry was created
|
// It's only null if a logon has never been attempted since the cookie DB entry was created
|
||||||
@@ -134,20 +151,60 @@ public class ChatBot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task KfDeadBotDetectionTask()
|
||||||
|
{
|
||||||
|
var interval = (await SettingsProvider.GetValueAsync(BuiltIn.Keys.BotDeadBotDetectionInterval)).ToType<int>();
|
||||||
|
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(interval));
|
||||||
|
while (await timer.WaitForNextTickAsync(_cancellationToken))
|
||||||
|
{
|
||||||
|
var inactivityTime = DateTime.UtcNow - KfClient.LastPacketReceived;
|
||||||
|
var deadTime = DateTime.UtcNow - _lastReconnectAttempt;
|
||||||
|
// No connection and no successful reconnection attempt in the last 5 minutes
|
||||||
|
// Either the site is completely dead or the bot got screwed by a nasty error and can't reconnect
|
||||||
|
if (!KfClient.IsConnected() && inactivityTime > TimeSpan.FromMinutes(10) && deadTime > TimeSpan.FromMinutes(15))
|
||||||
|
{
|
||||||
|
var shouldExit = (await SettingsProvider.GetValueAsync(BuiltIn.Keys.BotExitOnDeath)).ToBoolean();
|
||||||
|
_logger.Error("The bot as is dead beyond belief right now");
|
||||||
|
_logger.Error($"IsConnected() -> {KfClient.IsConnected()}");
|
||||||
|
_logger.Error($"inactivityTime -> {inactivityTime:g}");
|
||||||
|
_logger.Error($"deadTime -> {deadTime:g}");
|
||||||
|
if (shouldExit) Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task RefreshXfToken()
|
private async Task RefreshXfToken()
|
||||||
{
|
{
|
||||||
if (await _kfTokenService.IsLoggedIn())
|
try
|
||||||
{
|
{
|
||||||
_logger.Info("We were already logged in and should have a fresh cookie for chat now");
|
if (await _kfTokenService.IsLoggedIn())
|
||||||
// Only seems to happen if the bot thinks it's already logged in
|
{
|
||||||
|
_logger.Info("We were already logged in and should have a fresh cookie for chat now");
|
||||||
|
// Only seems to happen if the bot thinks it's already logged in
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error("Caught an error when trying to retrieve a fresh cookie");
|
||||||
|
_logger.Error(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var settings =
|
||||||
|
await SettingsProvider.GetMultipleValuesAsync([BuiltIn.Keys.KiwiFarmsUsername, BuiltIn.Keys.KiwiFarmsPassword]);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _kfTokenService.PerformLogin(settings[BuiltIn.Keys.KiwiFarmsUsername].Value!,
|
||||||
|
settings[BuiltIn.Keys.KiwiFarmsPassword].Value!);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error("Caught an error when trying to login");
|
||||||
|
_logger.Error(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings =
|
|
||||||
await SettingsProvider.GetMultipleValuesAsync([BuiltIn.Keys.KiwiFarmsUsername, BuiltIn.Keys.KiwiFarmsPassword]);
|
|
||||||
await _kfTokenService.PerformLogin(settings[BuiltIn.Keys.KiwiFarmsUsername].Value!,
|
|
||||||
settings[BuiltIn.Keys.KiwiFarmsPassword].Value!);
|
|
||||||
_logger.Info("Successfully logged in");
|
_logger.Info("Successfully logged in");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,6 +516,7 @@ public class ChatBot
|
|||||||
|
|
||||||
private void OnKfWsReconnected(object sender, ReconnectionInfo reconnectionInfo)
|
private void OnKfWsReconnected(object sender, ReconnectionInfo reconnectionInfo)
|
||||||
{
|
{
|
||||||
|
_lastReconnectAttempt = DateTime.UtcNow;
|
||||||
var roomId = SettingsProvider.GetValueAsync(BuiltIn.Keys.KiwiFarmsRoomId).Result.ToType<int>();
|
var roomId = SettingsProvider.GetValueAsync(BuiltIn.Keys.KiwiFarmsRoomId).Result.ToType<int>();
|
||||||
_logger.Error($"Sneedchat reconnected due to {reconnectionInfo.Type}");
|
_logger.Error($"Sneedchat reconnected due to {reconnectionInfo.Type}");
|
||||||
_logger.Info("Resetting GambaSesh presence so it can resync if he crashed while the bot was DC'd");
|
_logger.Info("Resetting GambaSesh presence so it can resync if he crashed while the bot was DC'd");
|
||||||
|
|||||||
@@ -911,6 +911,22 @@ public static class BuiltIn
|
|||||||
Default = "false",
|
Default = "false",
|
||||||
ValueType = SettingValueType.Boolean,
|
ValueType = SettingValueType.Boolean,
|
||||||
Regex = "(true|false)"
|
Regex = "(true|false)"
|
||||||
|
},
|
||||||
|
new BuiltInSettingsModel
|
||||||
|
{
|
||||||
|
Key = Keys.BotDeadBotDetectionInterval,
|
||||||
|
Description = "Interval in seconds for checking if the bot is completely dead",
|
||||||
|
Default = "15",
|
||||||
|
ValueType = SettingValueType.Text,
|
||||||
|
Regex = @"\d+"
|
||||||
|
},
|
||||||
|
new BuiltInSettingsModel
|
||||||
|
{
|
||||||
|
Key = Keys.BotExitOnDeath,
|
||||||
|
Description = "Whether the bot should exit if it's dead and unrecoverable",
|
||||||
|
Default = "true",
|
||||||
|
ValueType = SettingValueType.Boolean,
|
||||||
|
Regex = "(true|false)"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -1014,5 +1030,7 @@ public static class BuiltIn
|
|||||||
public static string KiwiPeerTubeEnabled = "KiwiPeerTube.Enabled";
|
public static string KiwiPeerTubeEnabled = "KiwiPeerTube.Enabled";
|
||||||
public static string KiwiPeerTubeCheckInterval = "KiwiPeerTube.CheckInterval";
|
public static string KiwiPeerTubeCheckInterval = "KiwiPeerTube.CheckInterval";
|
||||||
public static string KiwiPeerTubeEnforceWhitelist = "KiwiPeerTube.EnforceWhitelist";
|
public static string KiwiPeerTubeEnforceWhitelist = "KiwiPeerTube.EnforceWhitelist";
|
||||||
|
public static string BotDeadBotDetectionInterval = "Bot.DeadBotDetectionInterval";
|
||||||
|
public static string BotExitOnDeath = "Bot.ExitOnDeath";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user