Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 20 additions & 2 deletions DotNetTwitchBot.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33414.496
# Visual Studio Version 18
VisualStudioVersion = 18.2.11408.102 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetTwitchBot", "DotNetTwitchBot\DotNetTwitchBot.csproj", "{AAE6EFEA-8861-4AAA-B8D3-20163977C51C}"
EndProject
Expand All @@ -12,6 +12,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KickLib", "KickLib\KickLib.csproj", "{C159B553-D873-4480-B5D4-B649773E2671}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KickLib.Api.Unofficial", "KickLib.Api.Unofficial\KickLib.Api.Unofficial.csproj", "{D471B236-49DF-EE4C-F52D-A366E673DE03}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KickLib.Client", "KickLib.Client\KickLib.Client.csproj", "{BB7DB04D-A6D2-0EC2-93CF-65EBFD575A19}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -26,6 +32,18 @@ Global
{01E5DBD1-FF3E-4C27-B47A-7485785AE23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01E5DBD1-FF3E-4C27-B47A-7485785AE23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01E5DBD1-FF3E-4C27-B47A-7485785AE23C}.Release|Any CPU.Build.0 = Release|Any CPU
{C159B553-D873-4480-B5D4-B649773E2671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C159B553-D873-4480-B5D4-B649773E2671}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C159B553-D873-4480-B5D4-B649773E2671}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C159B553-D873-4480-B5D4-B649773E2671}.Release|Any CPU.Build.0 = Release|Any CPU
{D471B236-49DF-EE4C-F52D-A366E673DE03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D471B236-49DF-EE4C-F52D-A366E673DE03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D471B236-49DF-EE4C-F52D-A366E673DE03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D471B236-49DF-EE4C-F52D-A366E673DE03}.Release|Any CPU.Build.0 = Release|Any CPU
{BB7DB04D-A6D2-0EC2-93CF-65EBFD575A19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB7DB04D-A6D2-0EC2-93CF-65EBFD575A19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB7DB04D-A6D2-0EC2-93CF-65EBFD575A19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB7DB04D-A6D2-0EC2-93CF-65EBFD575A19}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
using DotNetTwitchBot.Application.ChatMessage.Notifications;
using DotNetTwitchBot.Bot.KickServices;
using DotNetTwitchBot.Bot.TwitchServices;
using MediatR;

namespace DotNetTwitchBot.Application.ChatMessage.Handlers
{
public class ReplyToMessageHandler(ITwitchChatBot chatBot) : INotificationHandler<ReplyToMessage>
public class ReplyToMessageHandler(ITwitchChatBot chatBot, IKickService kickService) : INotificationHandler<ReplyToMessage>
{
public Task Handle(ReplyToMessage request, CancellationToken cancellationToken)
{
if(request.Platform == PlatformType.Kick)
{
return kickService.ReplyToMessage(request.Name, request.MessageId, request.Message);
}
return chatBot.ReplyToMessage(request.Name ,request.MessageId, request.Message);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
using DotNetTwitchBot.Application.ChatMessage.Notification;
using DotNetTwitchBot.Bot.KickServices;
using DotNetTwitchBot.Bot.TwitchServices;
using MediatR;

namespace DotNetTwitchBot.Application.ChatMessage.Handlers
{
public class SendBotMessageHandler(ITwitchChatBot chatBot) : INotificationHandler<SendBotMessage>
public class SendBotMessageHandler(ITwitchChatBot chatBot, IKickService kickService) : INotificationHandler<SendBotMessage>
{
public Task Handle(SendBotMessage request, CancellationToken cancellationToken)
{
if (request.Platform == PlatformType.Kick)
{
return kickService.SendMessage(request.Message);
}
return chatBot.SendMessage(request.Message);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

namespace DotNetTwitchBot.Application.ChatMessage.Notifications
{
public class ReplyToMessage(string name, string messageId, string message) : INotification
public class ReplyToMessage(string name, string messageId, string message, PlatformType platform) : INotification
{
public string Name { get; } = name;
public string MessageId { get; } = messageId;
public string Message { get; } = message;
public PlatformType Platform { get; } = platform;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace DotNetTwitchBot.Application.ChatMessage.Notification
{
public class SendBotMessage(string message) : INotification
public class SendBotMessage(string message, PlatformType platform) : INotification
{
public SendBotMessage(string message) : this(message, PlatformType.Twitch)
{
}

public string Message { get; } = message;
public PlatformType Platform { get; } = platform;
}
}
17 changes: 11 additions & 6 deletions DotNetTwitchBot/Bot/Commands/AudioCommand/AudioCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,23 @@ public async Task RunCommand(CommandEventArgs e)

if (command.SayCooldown)
{
if (await CommandHandler.IsCoolDownExpiredWithMessage(e.Name, e.DisplayName, e.Command) == false) return;
if (await CommandHandler.IsCoolDownExpiredWithMessage(e.Name, e.Platform, e.DisplayName, e.Command) == false) return;
}
else
{
if (await CommandHandler.IsCoolDownExpired(e.Name, e.Command) == false) return;
if (await CommandHandler.IsCoolDownExpired(e.Name, e.Platform, e.Command) == false) return;
}

if (await CommandHandler.CheckPermission(Commands[e.Command], e) == false)
{
return;
}

if(command.Platforms.Contains(e.Platform) == false)
{
return;
}

await RunCommand(Commands[e.Command], e);
}

Expand Down Expand Up @@ -197,15 +202,15 @@ private async Task ToggleAudioCommandDisable(CommandEventArgs e, bool disabled)
var command = await db.AudioCommands.Find(x => x.CommandName.Equals(e.Arg)).FirstOrDefaultAsync();
if (command == null)
{
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.fail.enable").Replace("(command)", e.Arg));
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.fail.enable").Replace("(command)", e.Arg), e.Platform);
return;
}
command.Disabled = disabled;
value.Disabled = disabled;
db.AudioCommands.Update(command);
await db.SaveChangesAsync();
}
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.success.enable").Replace("(command)", e.Arg));
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.success.enable").Replace("(command)", e.Arg), e.Platform);
}

private async Task RefreshAudio()
Expand All @@ -221,11 +226,11 @@ private async Task AddAudioCommand(CommandEventArgs e)
if (newAudioCommand != null)
{
await AddAudioCommand(newAudioCommand);
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.success.add"));
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.success.add"), e.Platform);
}
else
{
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.fail.add"));
await ServiceBackbone.SendChatMessage(language.Get("audiocommands.fail.add"), e.Platform);
}

}
Expand Down
9 changes: 7 additions & 2 deletions DotNetTwitchBot/Bot/Commands/BaseCommandRunHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,20 @@ public async Task Handle(RunCommandNotification notification, CancellationToken
var commandService = commandHandler.GetCommand(eventArgs.Command);
if (commandService != null && commandService.CommandProperties.Disabled == false && CommandHandler.CheckToRunBroadcasterOnly(eventArgs, commandService.CommandProperties))
{
if(!commandService.CommandProperties.Platforms.Contains(eventArgs.Platform))
{
return;
}

if (await commandHandler.CheckPermission(commandService.CommandProperties, eventArgs))
{
if (commandService.CommandProperties.SayCooldown)
{
if (await commandHandler.IsCoolDownExpiredWithMessage(eventArgs.Name, eventArgs.DisplayName, commandService.CommandProperties) == false) return;
if (await commandHandler.IsCoolDownExpiredWithMessage(eventArgs.Name, eventArgs.Platform, eventArgs.DisplayName, commandService.CommandProperties) == false) return;
}
else
{
if (await commandHandler.IsCoolDownExpired(eventArgs.Name, commandService.CommandProperties.CommandName) == false) return;
if (await commandHandler.IsCoolDownExpired(eventArgs.Name, eventArgs.Platform, commandService.CommandProperties.CommandName) == false) return;
}
//This will throw a SkipCooldownException if the command fails to by pass setting cooldown
await commandService.CommandService.OnCommand(this, eventArgs);
Expand Down
13 changes: 6 additions & 7 deletions DotNetTwitchBot/Bot/Commands/BaseCommandService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,26 @@ protected BaseCommandService(IServiceBackbone serviceBackbone, ICommandHandler c

protected IServiceBackbone ServiceBackbone { get; }

public async Task SendChatMessage(string message)
public async Task SendChatMessage(string message, PlatformType platform)
{
await ServiceBackbone.SendChatMessage(message);
await ServiceBackbone.SendChatMessage(message, platform);
}

public async Task SendChatMessage(string name, string message)
public async Task SendChatMessage(string name, string message, PlatformType platform)
{
await ServiceBackbone.SendChatMessage(name, message);
await ServiceBackbone.SendChatMessage(name, message, platform);
}

public async Task RespondWithMessage(CommandEventArgs e, string message)
{
message = message.TrimStart('!').Trim();

if (string.IsNullOrWhiteSpace(e.MessageId))
{
await ServiceBackbone.SendChatMessage(e.DisplayName, message);
await ServiceBackbone.SendChatMessage(e.DisplayName, message, e.Platform);
}
else
{
await mediator.Publish(new ReplyToMessage(e.DisplayName, e.MessageId, message));
await mediator.Publish(new ReplyToMessage(e.DisplayName, e.MessageId, message, e.Platform));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ private async Task ExecuteRedeem(Models.ChannelPointRedeem redeem, ChannelPointR
IsBroadcaster = redeem.ElevatedPermission == Rank.Streamer,
DisplayName = e.Sender,
Name = e.Sender,
SkipLock = true
SkipLock = true,
Platform = PlatformType.Twitch
};
await ServiceBackbone.RunCommand(command);
}
Expand Down
28 changes: 14 additions & 14 deletions DotNetTwitchBot/Bot/Commands/CommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,25 @@ public async Task DeleteExternalCommand(ExternalCommands externalCommand)
await db.SaveChangesAsync();
}

public async Task<bool> IsCoolDownExpired(string user, string command)
public async Task<bool> IsCoolDownExpired(string user, PlatformType platform, string command)
{
if(await GetGlobalCooldown(command) > DateTime.Now)
{
return false;
}

if (await GetUserCooldown(user, command) > DateTime.Now)
if (await GetUserCooldown(user, platform, command) > DateTime.Now)
{
return false;
}
return true;
}

private async Task<DateTime> GetUserCooldown(string user, string command)
private async Task<DateTime> GetUserCooldown(string user, PlatformType platform, string command)
{
await using var scope = scopeFactory.CreateAsyncScope();
var db = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
var userCooldown = await db.Cooldowns.Find(x => x.CommandName.Equals(command) && x.UserName.Equals(user)).FirstOrDefaultAsync();
var userCooldown = await db.Cooldowns.Find(x => x.CommandName.Equals(command) && x.UserName.Equals(user) && x.Platform.Equals(platform)).FirstOrDefaultAsync();
if (userCooldown == null)
{
return DateTime.MinValue;
Expand All @@ -197,40 +197,40 @@ private async Task<DateTime> GetGlobalCooldown(string command)
return globalCooldown.NextGlobalCooldownTime;
}

public async Task<bool> IsCoolDownExpiredWithMessage(string user, string displayName, string command)
public async Task<bool> IsCoolDownExpiredWithMessage(string user, PlatformType platform, string displayName, string command)
{
if (!await IsCoolDownExpired(user, command))
if (!await IsCoolDownExpired(user, platform, command))
{
await using var scope = scopeFactory.CreateAsyncScope();
var serviceBackbone = scope.ServiceProvider.GetRequiredService<Core.IServiceBackbone>();
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", command, await CooldownLeft(user, command)));
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", command, await CooldownLeft(user, platform, command)), platform);

return false;
}
return true;
}

public async Task<bool> IsCoolDownExpiredWithMessage(string user, string displayName, BaseCommandProperties command)
public async Task<bool> IsCoolDownExpiredWithMessage(string user, PlatformType platform, string displayName, BaseCommandProperties command)
{
if (!await IsCoolDownExpired(user, command.CommandName))
if (!await IsCoolDownExpired(user, platform, command.CommandName))
{
await using var scope = scopeFactory.CreateAsyncScope();
var serviceBackbone = scope.ServiceProvider.GetRequiredService<Core.IServiceBackbone>();
if (command is DefaultCommand commandProperties)
{
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", commandProperties.CustomCommandName, await CooldownLeft(user, command.CommandName)));
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", commandProperties.CustomCommandName, await CooldownLeft(user, platform, command.CommandName)), platform);
}
else
{
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", command, await CooldownLeft(user, command.CommandName)));
await serviceBackbone.SendChatMessage(displayName, string.Format("!{0} is still on cooldown {1}", command, await CooldownLeft(user, platform, command.CommandName)), platform);
}

return false;
}
return true;
}

private async Task<string> CooldownLeft(string user, string command)
private async Task<string> CooldownLeft(string user, PlatformType platform, string command)
{

var globalCooldown = DateTime.MinValue;
Expand All @@ -240,7 +240,7 @@ private async Task<string> CooldownLeft(string user, string command)
{
globalCooldown = dbGlobalCooldown;
}
var dbUserCooldown = await GetUserCooldown(user, command);
var dbUserCooldown = await GetUserCooldown(user, platform, command);
if (dbUserCooldown > DateTime.Now)
{
userCooldown = dbUserCooldown;
Expand Down Expand Up @@ -342,7 +342,7 @@ public async Task<bool> CheckPermission(BaseCommandProperties commandProperties,
using (var scope = scopeFactory.CreateAsyncScope())
{
var viewerService = scope.ServiceProvider.GetRequiredService<Commands.Features.IViewerFeature>();
passed = await viewerService.IsFollowerByUsername(eventArgs.Name);
passed = await viewerService.IsFollowerByUsername(eventArgs.Name, eventArgs.Platform);
break;
}
case Rank.Subscriber:
Expand Down
Loading
Loading