diff --git a/KfChatDotNetBot/ApplicationDbContext.cs b/KfChatDotNetBot/ApplicationDbContext.cs index baea14d..2610418 100644 --- a/KfChatDotNetBot/ApplicationDbContext.cs +++ b/KfChatDotNetBot/ApplicationDbContext.cs @@ -19,4 +19,7 @@ public class ApplicationDbContext : DbContext public DbSet ChipsggBets { get; set; } public DbSet Images { get; set; } public DbSet UsersWhoWere { get; set; } + // public DbSet PocketWatchAddresses { get; set; } + // public DbSet PocketWatchTransactions { get; set; } + public DbSet Moms { get; set; } } \ No newline at end of file diff --git a/KfChatDotNetBot/Commands/MomCommands.cs b/KfChatDotNetBot/Commands/MomCommands.cs new file mode 100644 index 0000000..68fde0f --- /dev/null +++ b/KfChatDotNetBot/Commands/MomCommands.cs @@ -0,0 +1,44 @@ +using System.Text.RegularExpressions; +using Humanizer; +using Humanizer.Localisation; +using KfChatDotNetBot.Models.DbModels; +using KfChatDotNetBot.Settings; +using KfChatDotNetWsClient.Models.Events; +using Microsoft.EntityFrameworkCore; + +namespace KfChatDotNetBot.Commands; + +public class MomCommand : ICommand +{ + public List Patterns => [new Regex("^mom")]; + public string HelpText => "DTPN!"; + public bool HideFromHelp => false; + public UserRight RequiredRight => UserRight.Loser; + public TimeSpan Timeout => TimeSpan.FromSeconds(60); + + public async Task RunCommand(ChatBot botInstance, MessageModel message, UserDbModel user, GroupCollection arguments, + CancellationToken ctx) + { + await using var db = new ApplicationDbContext(); + db.Users.Attach(user); + var momSettings = await SettingsProvider.GetMultipleValuesAsync( + [BuiltIn.Keys.MomCooldown, BuiltIn.Keys.TwitchBossmanJackUsername, BuiltIn.Keys.KiwiFarmsRedColor]); + var cooldown = momSettings[BuiltIn.Keys.MomCooldown].ToType(); + var lastMom = (await db.Moms.ToListAsync(ctx)).OrderByDescending(j => j.Time).Take(1).ToList(); + if (lastMom.Count == 0 || (lastMom[0].Time.AddSeconds(cooldown) - DateTimeOffset.UtcNow).TotalSeconds <= 0) + { + await db.Moms.AddAsync(new MomDbModel { User = user, Time = DateTimeOffset.UtcNow }, ctx); + await db.SaveChangesAsync(ctx); + var count = await db.Moms.CountAsync(ctx); + await botInstance.SendChatMessageAsync( + $"[b][color={momSettings[BuiltIn.Keys.KiwiFarmsRedColor].Value}]DTPN![/color][/b] - {momSettings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} has fucked {count:N0} MILFs!", + true); + return; + } + + var secondsRemaining = lastMom[0].Time.AddSeconds(cooldown) - DateTimeOffset.UtcNow; + await botInstance.SendChatMessageAsync( + $"{momSettings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} (one pump chump) needs {secondsRemaining.Humanize(precision: 2, minUnit: TimeUnit.Millisecond)} rest before he can fuck another MILF", + true); + } +} \ No newline at end of file diff --git a/KfChatDotNetBot/Migrations/20250518184208_Mom.Designer.cs b/KfChatDotNetBot/Migrations/20250518184208_Mom.Designer.cs new file mode 100644 index 0000000..89191dd --- /dev/null +++ b/KfChatDotNetBot/Migrations/20250518184208_Mom.Designer.cs @@ -0,0 +1,358 @@ +// +using System; +using KfChatDotNetBot; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace KfChatDotNetBot.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250518184208_Mom")] + partial class Mom + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.4"); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.ChipsggBetDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("REAL"); + + b.Property("BetId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CurrencyPrice") + .HasColumnType("REAL"); + + b.Property("GameTitle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Multiplier") + .HasColumnType("REAL"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.Property("Winnings") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("ChipsggBets"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.HowlggBetsDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Bet") + .HasColumnType("INTEGER"); + + b.Property("BetId") + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Game") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("Profit") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("HowlggBets"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.ImageDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastSeen") + .HasColumnType("TEXT"); + + b.Property("Url") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.JuicerDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("REAL"); + + b.Property("JuicedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Juicers"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.MomDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Moms"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.RainbetBetsDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BetId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("BetSeenAt") + .HasColumnType("TEXT"); + + b.Property("GameName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Multiplier") + .HasColumnType("REAL"); + + b.Property("Payout") + .HasColumnType("REAL"); + + b.Property("PublicId") + .HasColumnType("TEXT"); + + b.Property("RainbetUserId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("RainbetBets"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.SettingDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CacheDuration") + .HasColumnType("REAL"); + + b.Property("Default") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsSecret") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Regex") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.Property("ValueType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.TwitchViewCountDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServerTime") + .HasColumnType("REAL"); + + b.Property("Time") + .HasColumnType("TEXT"); + + b.Property("Topic") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Viewers") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TwitchViewCounts"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.UserDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Ignored") + .HasColumnType("INTEGER"); + + b.Property("KfId") + .HasColumnType("INTEGER"); + + b.Property("KfUsername") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserRight") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.UserWhoWasDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActivityType") + .HasColumnType("INTEGER"); + + b.Property("FirstOccurence") + .HasColumnType("TEXT"); + + b.Property("LatestOccurence") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UsersWhoWere"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.JuicerDbModel", b => + { + b.HasOne("KfChatDotNetBot.Models.DbModels.UserDbModel", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.MomDbModel", b => + { + b.HasOne("KfChatDotNetBot.Models.DbModels.UserDbModel", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.UserWhoWasDbModel", b => + { + b.HasOne("KfChatDotNetBot.Models.DbModels.UserDbModel", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/KfChatDotNetBot/Migrations/20250518184208_Mom.cs b/KfChatDotNetBot/Migrations/20250518184208_Mom.cs new file mode 100644 index 0000000..7502433 --- /dev/null +++ b/KfChatDotNetBot/Migrations/20250518184208_Mom.cs @@ -0,0 +1,47 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace KfChatDotNetBot.Migrations +{ + /// + public partial class Mom : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Moms", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "INTEGER", nullable: false), + Time = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Moms", x => x.Id); + table.ForeignKey( + name: "FK_Moms_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Moms_UserId", + table: "Moms", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Moms"); + } + } +} diff --git a/KfChatDotNetBot/Migrations/ApplicationDbContextModelSnapshot.cs b/KfChatDotNetBot/Migrations/ApplicationDbContextModelSnapshot.cs index dd5cc95..4fca39a 100644 --- a/KfChatDotNetBot/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/KfChatDotNetBot/Migrations/ApplicationDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace KfChatDotNetBot.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "9.0.4"); modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.ChipsggBetDbModel", b => { @@ -146,6 +146,25 @@ namespace KfChatDotNetBot.Migrations b.ToTable("Juicers"); }); + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.MomDbModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Moms"); + }); + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.RainbetBetsDbModel", b => { b.Property("Id") @@ -309,6 +328,17 @@ namespace KfChatDotNetBot.Migrations b.Navigation("User"); }); + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.MomDbModel", b => + { + b.HasOne("KfChatDotNetBot.Models.DbModels.UserDbModel", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("KfChatDotNetBot.Models.DbModels.UserWhoWasDbModel", b => { b.HasOne("KfChatDotNetBot.Models.DbModels.UserDbModel", "User") diff --git a/KfChatDotNetBot/Models/DbModels/MomDbModel.cs b/KfChatDotNetBot/Models/DbModels/MomDbModel.cs new file mode 100644 index 0000000..e14431c --- /dev/null +++ b/KfChatDotNetBot/Models/DbModels/MomDbModel.cs @@ -0,0 +1,8 @@ +namespace KfChatDotNetBot.Models.DbModels; + +public class MomDbModel +{ + public int Id { get; set; } + public required UserDbModel User { get; set; } + public DateTimeOffset Time { get; set; } +} \ No newline at end of file diff --git a/KfChatDotNetBot/Settings/BuiltIn.cs b/KfChatDotNetBot/Settings/BuiltIn.cs index e80cf8a..e85e1b0 100644 --- a/KfChatDotNetBot/Settings/BuiltIn.cs +++ b/KfChatDotNetBot/Settings/BuiltIn.cs @@ -887,7 +887,17 @@ public static class BuiltIn IsSecret = false, CacheDuration = TimeSpan.FromHours(1), ValueType = SettingValueType.Text - } + }, + new BuiltInSettingsModel + { + Key = Keys.MomCooldown, + Regex = @"\d+", + Description = "Cooldown in seconds for the mom command, 0 to disable", + Default = "30", + IsSecret = false, + CacheDuration = TimeSpan.FromHours(1), + ValueType = SettingValueType.Text + }, ]; public static class Keys @@ -968,5 +978,6 @@ public static class BuiltIn public static string YeetEnabled = "Yeet.Enabled"; public static string YeetBmjUsernames = "Yeet.BmjUsernames"; public static string YeetProxy = "Yeet.Proxy"; + public static string MomCooldown = "Mom.Cooldown"; } } \ No newline at end of file