mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-05-02 12:32:03 -04:00
Big update introducing ghetto command interface, settings, database and howl.gg bet feed scraping
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using KfChatDotNetKickBot.Models;
|
||||
using KfChatDotNetKickBot.Models;
|
||||
using KfChatDotNetKickBot.Models.DbModels;
|
||||
using KfChatDotNetKickBot.Services;
|
||||
using KfChatDotNetKickBot.Settings;
|
||||
using KfChatDotNetWsClient;
|
||||
using KfChatDotNetWsClient.Models;
|
||||
using KfChatDotNetWsClient.Models.Events;
|
||||
@@ -14,12 +14,11 @@ namespace KfChatDotNetKickBot;
|
||||
|
||||
public class KickBot
|
||||
{
|
||||
private readonly ChatClient _kfClient;
|
||||
internal readonly ChatClient KfClient;
|
||||
private readonly KickWsClient.KickWsClient _kickClient;
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly ConfigModel _config;
|
||||
private readonly bool _pingEnabled = true;
|
||||
private bool _gambaSeshPresent;
|
||||
internal bool GambaSeshPresent;
|
||||
private string _xfSessionToken = null!;
|
||||
// Oh no it's an ever expanding list that may never get cleaned up!
|
||||
// BUY MORE RAM
|
||||
@@ -32,43 +31,51 @@ public class KickBot
|
||||
private DiscordService _discord;
|
||||
private TwitchChat _twitchChat;
|
||||
private string? _lastDiscordStatus;
|
||||
private bool _isBmjLive = false;
|
||||
internal bool IsBmjLive = false;
|
||||
private bool _isBmjLiveSynced = false;
|
||||
private Dictionary<string, int> _userIdMapping = new();
|
||||
private DateTime _lastKfEvent = DateTime.Now;
|
||||
private BotCommands _botCommands;
|
||||
private string _bmjTwitchUsername;
|
||||
private Howlgg _howlgg;
|
||||
|
||||
public KickBot()
|
||||
{
|
||||
_logger.Info("Bot starting!");
|
||||
const string configPath = "config.json";
|
||||
if (!Path.Exists(configPath))
|
||||
{
|
||||
_logger.Error($"{configPath} is missing! Exiting");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
_config = JsonSerializer.Deserialize<Models.ConfigModel>(File.ReadAllText(configPath)) ??
|
||||
throw new InvalidOperationException();
|
||||
RefreshXfToken().Wait(_cancellationToken);
|
||||
|
||||
_kfClient = new ChatClient(new ChatClientConfigModel
|
||||
var settings = Helpers.GetMultipleValues([
|
||||
BuiltIn.Keys.KiwiFarmsWsEndpoint, BuiltIn.Keys.KiwiFarmsDomain, BuiltIn.Keys.PusherEndpoint,
|
||||
BuiltIn.Keys.Proxy, BuiltIn.Keys.PusherReconnectTimeout, BuiltIn.Keys.PusherChannels,
|
||||
BuiltIn.Keys.TwitchBossmanJackId, BuiltIn.Keys.DiscordToken, BuiltIn.Keys.KiwiFarmsWsReconnectTimeout,
|
||||
BuiltIn.Keys.KiwiFarmsToken
|
||||
]).Result;
|
||||
|
||||
_xfSessionToken = settings[BuiltIn.Keys.KiwiFarmsToken].Value ?? "unset";
|
||||
if (_xfSessionToken == "unset")
|
||||
{
|
||||
WsUri = _config.KfWsEndpoint,
|
||||
RefreshXfToken().Wait(_cancellationToken);
|
||||
}
|
||||
|
||||
KfClient = new ChatClient(new ChatClientConfigModel
|
||||
{
|
||||
WsUri = new Uri(settings[BuiltIn.Keys.KiwiFarmsWsEndpoint].Value ?? throw new InvalidOperationException($"{BuiltIn.Keys.KiwiFarmsWsEndpoint} cannot be null")),
|
||||
XfSessionToken = _xfSessionToken,
|
||||
CookieDomain = _config.KfWsEndpoint.Host,
|
||||
Proxy = _config.Proxy,
|
||||
ReconnectTimeout = _config.KfReconnectTimeout
|
||||
CookieDomain = settings[BuiltIn.Keys.KiwiFarmsDomain].Value ?? throw new InvalidOperationException($"{BuiltIn.Keys.KiwiFarmsDomain} cannot be null"),
|
||||
Proxy = settings[BuiltIn.Keys.Proxy].Value,
|
||||
ReconnectTimeout = Convert.ToInt32(settings[BuiltIn.Keys.KiwiFarmsWsReconnectTimeout].Value)
|
||||
});
|
||||
|
||||
_kickClient = new KickWsClient.KickWsClient(_config.PusherEndpoint.ToString(),
|
||||
_config.Proxy, _config.PusherReconnectTimeout);
|
||||
_kickClient = new KickWsClient.KickWsClient(settings[BuiltIn.Keys.PusherEndpoint].Value!,
|
||||
settings[BuiltIn.Keys.Proxy].Value, Convert.ToInt32(settings[BuiltIn.Keys.PusherReconnectTimeout].Value));
|
||||
|
||||
_logger.Debug("Creating bot command instance");
|
||||
_botCommands = new BotCommands(this, _cancellationToken);
|
||||
|
||||
_kfClient.OnMessages += OnKfChatMessage;
|
||||
_kfClient.OnUsersParted += OnUsersParted;
|
||||
_kfClient.OnUsersJoined += OnUsersJoined;
|
||||
_kfClient.OnWsDisconnection += OnKfWsDisconnected;
|
||||
_kfClient.OnWsReconnect += OnKfWsReconnected;
|
||||
_kfClient.OnFailedToJoinRoom += OnFailedToJoinRoom;
|
||||
KfClient.OnMessages += OnKfChatMessage;
|
||||
KfClient.OnUsersParted += OnUsersParted;
|
||||
KfClient.OnUsersJoined += OnUsersJoined;
|
||||
KfClient.OnWsDisconnection += OnKfWsDisconnected;
|
||||
KfClient.OnWsReconnect += OnKfWsReconnected;
|
||||
KfClient.OnFailedToJoinRoom += OnFailedToJoinRoom;
|
||||
|
||||
_kickClient.OnStreamerIsLive += OnStreamerIsLive;
|
||||
_kickClient.OnChatMessage += OnKickChatMessage;
|
||||
@@ -76,10 +83,11 @@ public class KickBot
|
||||
_kickClient.OnPusherSubscriptionSucceeded += OnPusherSubscriptionSucceeded;
|
||||
_kickClient.OnStopStreamBroadcast += OnStopStreamBroadcast;
|
||||
|
||||
_kfClient.StartWsClient().Wait(_cancellationToken);
|
||||
KfClient.StartWsClient().Wait(_cancellationToken);
|
||||
|
||||
_kickClient.StartWsClient().Wait(_cancellationToken);
|
||||
foreach (var channel in _config.PusherChannels)
|
||||
var pusherChannels = settings[BuiltIn.Keys.PusherChannels].Value ?? "";
|
||||
foreach (var channel in pusherChannels.Split(','))
|
||||
{
|
||||
_kickClient.SendPusherSubscribe(channel);
|
||||
}
|
||||
@@ -88,47 +96,78 @@ public class KickBot
|
||||
var pingThread = new Thread(PingThread);
|
||||
pingThread.Start();
|
||||
|
||||
if (_config.BossmanJackTwitchId != null)
|
||||
if (settings[BuiltIn.Keys.TwitchBossmanJackId].Value != null)
|
||||
{
|
||||
_logger.Debug("Creating Twitch live stream notification client");
|
||||
_twitch = new Twitch([_config.BossmanJackTwitchId.Value], _config.Proxy, _cancellationToken);
|
||||
_twitch = new Twitch([Convert.ToInt32(settings[BuiltIn.Keys.TwitchBossmanJackId].Value)], settings[BuiltIn.Keys.Proxy].Value, _cancellationToken);
|
||||
_twitch.OnStreamStateUpdated += OnTwitchStreamStateUpdated;
|
||||
_twitch.StartWsClient().Wait(_cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug("Ignoring Twitch client as TwitchChannels is not defined");
|
||||
_logger.Debug($"Ignoring Twitch client as {BuiltIn.Keys.TwitchBossmanJackId} is not defined");
|
||||
}
|
||||
|
||||
BuildShuffle();
|
||||
BuildDiscord();
|
||||
BuildTwitchChat();
|
||||
|
||||
_howlgg = new Howlgg(settings[BuiltIn.Keys.Proxy].Value, _cancellationToken);
|
||||
_howlgg.OnHowlggBetHistory += OnHowlggBetHistory;
|
||||
_howlgg.StartWsClient().Wait(_cancellationToken);
|
||||
|
||||
_logger.Debug("Blocking the main thread");
|
||||
var exitEvent = new ManualResetEvent(false);
|
||||
exitEvent.WaitOne();
|
||||
}
|
||||
|
||||
private void OnHowlggBetHistory(object sender, HowlggBetHistoryResponseModel data)
|
||||
{
|
||||
_logger.Debug("Received bet history from Howl.gg");
|
||||
using var db = new ApplicationDbContext();
|
||||
foreach (var bets in data.History.Data)
|
||||
{
|
||||
if (db.HowlggBets.Any(b => b.GameId == bets.GameId))
|
||||
{
|
||||
_logger.Trace("Bet already exists in DB");
|
||||
continue;
|
||||
}
|
||||
|
||||
db.HowlggBets.Add(new HowlggBetsDbModel
|
||||
{
|
||||
UserId = data.User.Id,
|
||||
BetId = bets.Id,
|
||||
GameId = bets.GameId,
|
||||
Bet = bets.Bet,
|
||||
Profit = bets.Profit,
|
||||
Date = bets.Date,
|
||||
Game = bets.Game
|
||||
});
|
||||
_logger.Debug("Added bet to DB");
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
private void BuildShuffle()
|
||||
{
|
||||
_logger.Debug("Building Shuffle");
|
||||
_shuffle = new Shuffle(_config.Proxy, _cancellationToken);
|
||||
_shuffle = new Shuffle(Helpers.GetValue(BuiltIn.Keys.Proxy).Result.Value, _cancellationToken);
|
||||
_shuffle.OnLatestBetUpdated += ShuffleOnLatestBetUpdated;
|
||||
_shuffle.OnWsDisconnection += ShuffleOnWsDisconnection;
|
||||
_shuffle.StartWsClient().Wait(_cancellationToken);
|
||||
}
|
||||
|
||||
private void BuildDiscord()
|
||||
{
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.DiscordToken, BuiltIn.Keys.Proxy]).Result;
|
||||
_logger.Debug("Building Discord");
|
||||
if (_config.DiscordToken == null)
|
||||
if (settings[BuiltIn.Keys.DiscordToken].Value == null)
|
||||
{
|
||||
_logger.Info("Not building Discord as the token is not configured");
|
||||
return;
|
||||
}
|
||||
_discord = new DiscordService(_config.DiscordToken, _config.Proxy, _cancellationToken);
|
||||
_discord = new DiscordService(settings[BuiltIn.Keys.DiscordToken].Value!, settings[BuiltIn.Keys.Proxy].Value, _cancellationToken);
|
||||
_discord.OnInvalidCredentials += DiscordOnInvalidCredentials;
|
||||
_discord.OnWsDisconnection += DiscordOnWsDisconnection;
|
||||
_discord.OnMessageReceived += DiscordOnMessageReceived;
|
||||
_discord.OnPresenceUpdated += DiscordOnPresenceUpdated;
|
||||
_discord.StartWsClient().Wait(_cancellationToken);
|
||||
@@ -136,105 +175,81 @@ public class KickBot
|
||||
|
||||
private void BuildTwitchChat()
|
||||
{
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.TwitchBossmanJackUsername, BuiltIn.Keys.Proxy]).Result;
|
||||
_logger.Debug("Building Twitch Chat");
|
||||
if (_config.BossmanJackTwitchUsername == null)
|
||||
if (settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value == null)
|
||||
{
|
||||
_logger.Info("Not building Twitch Chat client as BMJ's username is not configured");
|
||||
return;
|
||||
}
|
||||
|
||||
_twitchChat = new TwitchChat($"#{_config.BossmanJackTwitchUsername}", _config.Proxy, _cancellationToken);
|
||||
_bmjTwitchUsername = settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value!;
|
||||
|
||||
_twitchChat = new TwitchChat($"#{settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value}", settings[BuiltIn.Keys.Proxy].Value, _cancellationToken);
|
||||
_twitchChat.OnMessageReceived += TwitchChatOnMessageReceived;
|
||||
_twitchChat.OnWsDisconnection += TwitchChatOnWsDisconnection;
|
||||
_twitchChat.StartWsClient().Wait(_cancellationToken);
|
||||
}
|
||||
|
||||
private void TwitchChatOnWsDisconnection(object sender, DisconnectionInfo e)
|
||||
{
|
||||
if (e.Type == DisconnectionType.ByServer)
|
||||
{
|
||||
_twitchChat.Dispose();
|
||||
BuildTwitchChat();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TwitchChatOnMessageReceived(object sender, string nick, string target, string message)
|
||||
{
|
||||
if (nick != _config.BossmanJackTwitchUsername)
|
||||
if (nick != _bmjTwitchUsername)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_sendChatMessage($"[img]https://i.postimg.cc/QMFVV2Xk/twitch16.png[/img] {nick}: {message}", true);
|
||||
// Not caching this value as it won't harm it to have to look this up in even the worst spergout sesh
|
||||
var twitchIcon = Helpers.GetValue(BuiltIn.Keys.TwitchIcon).Result.Value;
|
||||
SendChatMessage($"[img]{twitchIcon}[/img] {nick}: {message}", true);
|
||||
}
|
||||
|
||||
private void DiscordOnPresenceUpdated(object sender, DiscordPresenceUpdateModel presence)
|
||||
{
|
||||
if (presence.User.Id != _config.DiscordBmjId)
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.DiscordBmjId, BuiltIn.Keys.DiscordIcon]).Result;
|
||||
if (presence.User.Id != settings[BuiltIn.Keys.DiscordBmjId].Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_lastDiscordStatus == presence.Status)
|
||||
{
|
||||
_logger.Debug("Ignoring status update as it's the same as the last one");
|
||||
return;
|
||||
}
|
||||
_lastDiscordStatus = presence.Status;
|
||||
// if (_lastDiscordStatus == presence.Status)
|
||||
// {
|
||||
// _logger.Debug("Ignoring status update as it's the same as the last one");
|
||||
// return;
|
||||
// }
|
||||
// _lastDiscordStatus = presence.Status;
|
||||
var clientStatus = presence.ClientStatus.Keys.Aggregate(string.Empty, (current, device) => current + $"{device} is {presence.ClientStatus[device]}; ");
|
||||
_sendChatMessage($"[img]https://i.postimg.cc/cLmQrp89/discord16.png[/img] BossmanJack has updated his Discord presence: {clientStatus}");
|
||||
SendChatMessage($"[img]{settings[BuiltIn.Keys.DiscordIcon].Value}[/img] BossmanJack has updated his Discord presence: {clientStatus}");
|
||||
}
|
||||
|
||||
private void DiscordOnMessageReceived(object sender, DiscordMessageModel message)
|
||||
{
|
||||
if (message.Author.Id != _config.DiscordBmjId)
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.DiscordBmjId, BuiltIn.Keys.DiscordIcon]).Result;
|
||||
if (message.Author.Id != settings[BuiltIn.Keys.DiscordBmjId].Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = $"[img]https://i.postimg.cc/cLmQrp89/discord16.png[/img] BossmanJack: {message.Content}";
|
||||
var result = $"[img]{settings[BuiltIn.Keys.DiscordIcon].Value}[/img] BossmanJack: {message.Content}";
|
||||
foreach (var attachment in message.Attachments ?? [])
|
||||
{
|
||||
result += $"[br]Attachment: {attachment.GetProperty("filename").GetString()} {attachment.GetProperty("url").GetString()}";
|
||||
}
|
||||
_sendChatMessage(result);
|
||||
}
|
||||
|
||||
private void DiscordOnWsDisconnection(object sender, DisconnectionInfo e)
|
||||
{
|
||||
_logger.Error($"Discord dropped, reason {e.Type}");
|
||||
// This is raised when the Websocket client is disposed
|
||||
// Attempting to dispose it again while it is being disposed causes a loop and probably eventually a stack overflow
|
||||
if (e.Type == DisconnectionType.Exit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_discord.Dispose();
|
||||
BuildDiscord();
|
||||
SendChatMessage(result);
|
||||
}
|
||||
|
||||
private void DiscordOnInvalidCredentials(object sender, DiscordPacketReadModel packet)
|
||||
{
|
||||
_logger.Error("Credentials failed to validate. Killing service.");
|
||||
_discord.Dispose();
|
||||
}
|
||||
|
||||
private void ShuffleOnWsDisconnection(object sender, DisconnectionInfo e)
|
||||
{
|
||||
if (e.Type == DisconnectionType.ByServer)
|
||||
{
|
||||
_shuffle.Dispose();
|
||||
BuildShuffle();
|
||||
}
|
||||
_logger.Error("Credentials failed to validate.");
|
||||
}
|
||||
|
||||
private void ShuffleOnLatestBetUpdated(object sender, ShuffleLatestBetModel bet)
|
||||
{
|
||||
_logger.Debug("Shuffle bet has arrived");
|
||||
if (bet.Username != "TheBossmanJack")
|
||||
var settings = Helpers
|
||||
.GetMultipleValues([BuiltIn.Keys.ShuffleBmjUsername, BuiltIn.Keys.TwitchBossmanJackUsername]).Result;
|
||||
_logger.Trace("Shuffle bet has arrived");
|
||||
if (bet.Username != settings[BuiltIn.Keys.ShuffleBmjUsername].Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_logger.Info("ALERT BMJ IS BETTING");
|
||||
if (_isBmjLive)
|
||||
if (IsBmjLive)
|
||||
{
|
||||
_logger.Info("Ignoring as BMJ is live");
|
||||
return;
|
||||
@@ -245,10 +260,10 @@ public class KickBot
|
||||
// He was schizo betting on Dice, so I want to avoid a lot of API requests to Twitch in case they rate limit
|
||||
if (!_isBmjLiveSynced)
|
||||
{
|
||||
_isBmjLive = _twitch.IsStreamLive("thebossmanjack").Result;
|
||||
IsBmjLive = _twitch.IsStreamLive(settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value!).Result;
|
||||
_isBmjLiveSynced = true;
|
||||
}
|
||||
if (_isBmjLive)
|
||||
if (IsBmjLive)
|
||||
{
|
||||
_logger.Info("Double checked and he is really online");
|
||||
return;
|
||||
@@ -257,7 +272,7 @@ public class KickBot
|
||||
var payoutColor = "green";
|
||||
if (float.Parse(bet.Payout) < float.Parse(bet.Amount)) payoutColor = "red";
|
||||
// There will be a check for live status but ignoring that while we deal with an emergency dice situation
|
||||
_sendChatMessage($"🚨🚨 {bet.Username} just bet {bet.Amount} {bet.Currency} which paid out [color={payoutColor}]{bet.Payout} {bet.Currency}[/color] ({bet.Multiplier}x) on {bet.GameName} 💰💰", true);
|
||||
SendChatMessage($"🚨🚨 {bet.Username} just bet {bet.Amount} {bet.Currency} which paid out [color={payoutColor}]{bet.Payout} {bet.Currency}[/color] ({bet.Multiplier}x) on {bet.GameName} 💰💰", true);
|
||||
}
|
||||
|
||||
private void OnTwitchStreamStateUpdated(object sender, int channelId, bool isLive)
|
||||
@@ -265,13 +280,13 @@ public class KickBot
|
||||
_logger.Info($"BossmanJack stream event came in. isLive => {isLive}");
|
||||
if (isLive)
|
||||
{
|
||||
_sendChatMessage("BossmanJack just went live on Twitch! https://www.twitch.tv/thebossmanjack\r\n" +
|
||||
SendChatMessage("BossmanJack just went live on Twitch! https://www.twitch.tv/thebossmanjack\r\n" +
|
||||
"Ad-free re-stream at https://bossmanjack.tv courtesy of @Kees H");
|
||||
_isBmjLive = true;
|
||||
IsBmjLive = true;
|
||||
return;
|
||||
}
|
||||
_sendChatMessage("BossmanJack is no longer live! :lossmanjack:");
|
||||
_isBmjLive = false;
|
||||
SendChatMessage("BossmanJack is no longer live! :lossmanjack:");
|
||||
IsBmjLive = false;
|
||||
}
|
||||
|
||||
private void OnFailedToJoinRoom(object sender, string message)
|
||||
@@ -279,10 +294,10 @@ public class KickBot
|
||||
_logger.Error($"Couldn't join the room. KF returned: {message}");
|
||||
_logger.Error("This is likely due to the session cookie expiring. Retrieving a new one.");
|
||||
RefreshXfToken().Wait(_cancellationToken);
|
||||
_kfClient.UpdateToken(_xfSessionToken);
|
||||
KfClient.UpdateToken(_xfSessionToken);
|
||||
_logger.Info("Retrieved fresh token. Reconnecting.");
|
||||
_kfClient.Disconnect();
|
||||
_kfClient.StartWsClient().Wait(_cancellationToken);
|
||||
KfClient.Disconnect();
|
||||
KfClient.StartWsClient().Wait(_cancellationToken);
|
||||
_logger.Info("Client should be reconnecting now");
|
||||
}
|
||||
|
||||
@@ -291,8 +306,8 @@ public class KickBot
|
||||
while (_pingEnabled)
|
||||
{
|
||||
Thread.Sleep(TimeSpan.FromSeconds(15));
|
||||
_logger.Debug("Pinging KF and Pusher");
|
||||
_kfClient.SendMessage("/ping");
|
||||
_logger.Debug("Pinging KF");
|
||||
KfClient.SendMessage("/ping");
|
||||
_kickClient.SendPusherPing();
|
||||
if (_initialStartCooldown) _initialStartCooldown = false;
|
||||
var inactivityTime = DateTime.Now - _lastKfEvent;
|
||||
@@ -300,80 +315,55 @@ public class KickBot
|
||||
if (inactivityTime.TotalMinutes > 10)
|
||||
{
|
||||
_logger.Error("Forcing reconnection as bot is completely dead");
|
||||
_kfClient.Reconnect().Wait(_cancellationToken);
|
||||
KfClient.Reconnect().Wait(_cancellationToken);
|
||||
}
|
||||
_logger.Debug("Polling Bossman's Howl.gg stats");
|
||||
_howlgg.GetUserInfo("951905");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshXfToken()
|
||||
{
|
||||
var cookie = await KfTokenService.FetchSessionTokenAsync(_config.KfDomain, _config.KfUsername, _config.KfPassword,
|
||||
_config.ChromiumPath, _config.Proxy);
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.KiwiFarmsDomain,
|
||||
BuiltIn.Keys.KiwiFarmsUsername, BuiltIn.Keys.KiwiFarmsPassword, BuiltIn.Keys.KiwiFarmsChromiumPath,
|
||||
BuiltIn.Keys.Proxy]).Result;
|
||||
var cookie = await KfTokenService.FetchSessionTokenAsync(settings[BuiltIn.Keys.KiwiFarmsDomain].Value!,
|
||||
settings[BuiltIn.Keys.KiwiFarmsUsername].Value!, settings[BuiltIn.Keys.KiwiFarmsPassword].Value!,
|
||||
settings[BuiltIn.Keys.KiwiFarmsChromiumPath].Value!, settings[BuiltIn.Keys.Proxy].Value);
|
||||
_logger.Debug($"FetchSessionTokenAsync returned {cookie}");
|
||||
_xfSessionToken = cookie;
|
||||
await Helpers.SetValue(BuiltIn.Keys.KiwiFarmsToken, _xfSessionToken);
|
||||
}
|
||||
|
||||
private void OnStreamerIsLive(object sender, KickModels.StreamerIsLiveEventModel? e)
|
||||
{
|
||||
if (e == null) return;
|
||||
_sendChatMessage($"Dirt Devils LFG! @Juhlonduss is live! {e.Livestream.SessionTitle} https://kick.com/dirtdevil-enjoyer", true);
|
||||
SendChatMessage($"Dirt Devils LFG! @Juhlonduss is live! {e.Livestream.SessionTitle} https://kick.com/dirtdevil-enjoyer", true);
|
||||
}
|
||||
|
||||
private void OnStopStreamBroadcast(object sender, KickModels.StopStreamBroadcastEventModel? e)
|
||||
{
|
||||
_sendChatMessage("Dirt Devils felted. Stream is over. :lossmanjack:", true);
|
||||
SendChatMessage("Dirt Devils felted. Stream is over. :lossmanjack:", true);
|
||||
}
|
||||
|
||||
private void OnKfChatMessage(object sender, List<MessageModel> messages, MessagesJsonModel jsonPayload)
|
||||
{
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.GambaSeshDetectEnabled, BuiltIn.Keys.GambaSeshUserId])
|
||||
.Result;
|
||||
_lastKfEvent = DateTime.Now;
|
||||
_logger.Debug($"Received {messages.Count} message(s)");
|
||||
foreach (var message in messages)
|
||||
{
|
||||
_logger.Info($"KF ({message.MessageDate.ToLocalTime():HH:mm:ss}) <{message.Author.Username}> {message.Message}");
|
||||
if (_config.EnableGambaSeshDetect && !_initialStartCooldown && message.Author.Id == _config.GambaSeshUserId && !_gambaSeshPresent)
|
||||
if (settings[BuiltIn.Keys.GambaSeshDetectEnabled].Value == "true" && !_initialStartCooldown && message.Author.Id == Convert.ToInt32(settings[BuiltIn.Keys.GambaSeshUserId].Value) && !GambaSeshPresent)
|
||||
{
|
||||
_logger.Info("Received a GambaSesh message after cooldown and while thinking he's not here. Setting the presence flag to avoid spamming chat");
|
||||
_gambaSeshPresent = true;
|
||||
GambaSeshPresent = true;
|
||||
}
|
||||
if (!_seenMsgIds.Contains(message.MessageId) && !_initialStartCooldown)
|
||||
{
|
||||
if (message.MessageRaw.StartsWith("!time"))
|
||||
{
|
||||
var bmt = new DateTimeOffset(TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,
|
||||
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")), TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").BaseUtcOffset);
|
||||
_sendChatMessage($"It's currently {bmt:h:mm:ss tt} BMT");
|
||||
}
|
||||
else if (message.MessageRaw.StartsWith("!twisted"))
|
||||
{
|
||||
_sendChatMessage("🦍 🗣 GET IT TWISTED 🌪 , GAMBLE ✅ . PLEASE START GAMBLING 👍 . GAMBLING IS AN INVESTMENT 🎰 AND AN INVESTMENT ONLY 👍 . YOU WILL PROFIT 💰 , YOU WILL WIN ❗ ️. YOU WILL DO ALL OF THAT 💯 , YOU UNDERSTAND ⁉ ️ YOU WILL BECOME A BILLIONAIRE 💵 📈 AND REBUILD YOUR FUCKING LIFE 🤯");
|
||||
}
|
||||
else if (message.MessageRaw.StartsWith("!insanity"))
|
||||
{
|
||||
// ReSharper disable once StringLiteralTypo
|
||||
_sendChatMessage("definition of insanity = doing the same thing over and over and over excecting a different result, and heres my dumbass trying to get rich every day and losing everythign i fucking touch every fucking time FUCK this bullshit FUCK MY LIEFdefinition of insanity = doing the same thing over and over and over excecting a different result, and heres my dumbass trying to get rich every day and losing everythign i fucking touch every fucking time FUCK this bullshit FUCK MY LIEF");
|
||||
}
|
||||
else if (message.MessageRaw.StartsWith("!helpme"))
|
||||
{
|
||||
_sendChatMessage("[img]https://i.postimg.cc/fTw6tGWZ/ineedmoneydumbfuck.png[/img]", true);
|
||||
}
|
||||
else if (message.MessageRaw.StartsWith("!whois"))
|
||||
{
|
||||
var lookup = WebUtility.HtmlDecode(message.MessageRaw.Replace("!whois ", string.Empty)
|
||||
.TrimStart('@').TrimEnd(' ').TrimEnd(','));
|
||||
if (_userIdMapping.ContainsKey(lookup))
|
||||
{
|
||||
_sendChatMessage($"{lookup}'s ID is {_userIdMapping[lookup]}", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sendChatMessage("Don't know they who they are.", true);
|
||||
}
|
||||
}
|
||||
else if (message.MessageRaw == "!sent")
|
||||
{
|
||||
_sendChatMessage("[img]https://i.ibb.co/GHq7hb1/4373-g-N5-HEH2-Hkc.png[/img]", true);
|
||||
}
|
||||
_logger.Debug("Passing message to command interface");
|
||||
_botCommands.ProcessMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -383,21 +373,24 @@ public class KickBot
|
||||
}
|
||||
}
|
||||
|
||||
private void _sendChatMessage(string message, bool bypassSeshDetect = false)
|
||||
public void SendChatMessage(string message, bool bypassSeshDetect = false)
|
||||
{
|
||||
if (_config.SuppressChatMessages)
|
||||
var settings = Helpers
|
||||
.GetMultipleValues([BuiltIn.Keys.KiwiFarmsSuppressChatMessages, BuiltIn.Keys.GambaSeshDetectEnabled])
|
||||
.Result;
|
||||
if (settings[BuiltIn.Keys.KiwiFarmsSuppressChatMessages].Value == "true")
|
||||
{
|
||||
_logger.Info("Not sending message as SuppressChatMessages is enabled");
|
||||
_logger.Info($"Message was: {message}");
|
||||
return;
|
||||
}
|
||||
if (_gambaSeshPresent && _config.EnableGambaSeshDetect && !bypassSeshDetect)
|
||||
if (GambaSeshPresent && settings[BuiltIn.Keys.GambaSeshDetectEnabled].Value == "true" && !bypassSeshDetect)
|
||||
{
|
||||
_logger.Info($"Not sending message '{message}' as GambaSesh is present");
|
||||
return;
|
||||
}
|
||||
|
||||
_kfClient.SendMessage(message);
|
||||
KfClient.SendMessage(message);
|
||||
}
|
||||
|
||||
private void OnKickChatMessage(object sender, KickModels.ChatMessageEventModel? e)
|
||||
@@ -407,59 +400,81 @@ public class KickBot
|
||||
_logger.Debug($"BB Code Translation: {e.Content.TranslateKickEmotes()}");
|
||||
|
||||
if (e.Sender.Slug != "bossmanjack") return;
|
||||
var kickIcon = Helpers.GetValue(BuiltIn.Keys.KickIcon).Result;
|
||||
|
||||
_logger.Debug("Message from BossmanJack");
|
||||
_sendChatMessage($"[img]{_config.KickIcon}[/img] BossmanJack: {e.Content.TranslateKickEmotes()}");
|
||||
SendChatMessage($"[img]{kickIcon.Value}[/img] BossmanJack: {e.Content.TranslateKickEmotes()}");
|
||||
}
|
||||
|
||||
private void OnUsersJoined(object sender, List<UserModel> users, UsersJsonModel jsonPayload)
|
||||
{
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.GambaSeshUserId, BuiltIn.Keys.GambaSeshDetectEnabled])
|
||||
.Result;
|
||||
_lastKfEvent = DateTime.Now;
|
||||
_logger.Debug($"Received {users.Count} user join events");
|
||||
using var db = new ApplicationDbContext();
|
||||
foreach (var user in users)
|
||||
{
|
||||
if (user.Id == _config.GambaSeshUserId && _config.EnableGambaSeshDetect)
|
||||
if (user.Id == Convert.ToInt32(settings[BuiltIn.Keys.GambaSeshUserId].Value) && settings[BuiltIn.Keys.GambaSeshDetectEnabled].Value == "true")
|
||||
{
|
||||
_logger.Info("GambaSesh is now present");
|
||||
_gambaSeshPresent = true;
|
||||
GambaSeshPresent = true;
|
||||
}
|
||||
_logger.Info($"{user.Username} joined!");
|
||||
if (!_userIdMapping.ContainsKey(user.Username))
|
||||
|
||||
var userDb = db.Users.FirstOrDefault(u => u.KfId == user.Id);
|
||||
if (userDb == null)
|
||||
{
|
||||
_userIdMapping.Add(user.Username, user.Id);
|
||||
db.Users.Add(new UserDbModel { KfId = user.Id, KfUsername = user.Username });
|
||||
_logger.Debug("Adding user to DB");
|
||||
continue;
|
||||
}
|
||||
// Detect a username change
|
||||
if (userDb.KfUsername != user.Username)
|
||||
{
|
||||
_logger.Debug("Username has updated, updating DB");
|
||||
userDb.KfUsername = user.Username;
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
private void OnUsersParted(object sender, List<int> userIds)
|
||||
{
|
||||
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.GambaSeshUserId, BuiltIn.Keys.GambaSeshDetectEnabled])
|
||||
.Result;
|
||||
_lastKfEvent = DateTime.Now;
|
||||
if (userIds.Contains(_config.GambaSeshUserId) && _config.EnableGambaSeshDetect)
|
||||
if (userIds.Contains(Convert.ToInt32(settings[BuiltIn.Keys.GambaSeshUserId].Value)) && settings[BuiltIn.Keys.GambaSeshDetectEnabled].Value == "true")
|
||||
{
|
||||
_logger.Info("GambaSesh is no longer present");
|
||||
_gambaSeshPresent = false;
|
||||
GambaSeshPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKfWsDisconnected(object sender, DisconnectionInfo disconnectionInfo)
|
||||
{
|
||||
_logger.Error($"Sneedchat disconnected due to {disconnectionInfo.Type}");
|
||||
_logger.Error(JsonSerializer.Serialize(disconnectionInfo));
|
||||
_logger.Error($"Close Status => {disconnectionInfo.CloseStatus}; Close Status Description => {disconnectionInfo.CloseStatusDescription}");
|
||||
_logger.Error(disconnectionInfo.Exception);
|
||||
}
|
||||
|
||||
private void OnKfWsReconnected(object sender, ReconnectionInfo reconnectionInfo)
|
||||
{
|
||||
var roomId = Convert.ToInt32(Helpers.GetValue(BuiltIn.Keys.KiwiFarmsRoomId).Result.Value);
|
||||
_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");
|
||||
_gambaSeshPresent = false;
|
||||
_logger.Info($"Rejoining {_config.KfChatRoomId}");
|
||||
_kfClient.JoinRoom(_config.KfChatRoomId);
|
||||
GambaSeshPresent = false;
|
||||
_logger.Info($"Rejoining {roomId}");
|
||||
KfClient.JoinRoom(roomId);
|
||||
}
|
||||
|
||||
private void OnPusherWsReconnected(object sender, ReconnectionInfo reconnectionInfo)
|
||||
{
|
||||
_logger.Error($"Pusher reconnected due to {reconnectionInfo.Type}");
|
||||
foreach (var channel in _config.PusherChannels)
|
||||
var channels = Helpers.GetValue(BuiltIn.Keys.PusherChannels).Result.Value ?? "";
|
||||
foreach (var channel in channels.Split(','))
|
||||
{
|
||||
_logger.Info($"Rejoining {channel}");
|
||||
_kickClient.SendPusherSubscribe(channel);
|
||||
|
||||
Reference in New Issue
Block a user