From 5069591eab0f0e318b28d18eb15766052f6de6e6 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 12:29:57 +0700 Subject: [PATCH 1/6] Admin bot with two admin commands --- Bot/Admin.fs | 24 ++++++++++++++++++++++++ Bot/Bot.fs | 9 +++++++++ Bot/Bot.fsproj | 1 + Bot/DbService.fs | 15 +++++++++++++++ Bot/GuildEnvironment.fs | 2 ++ Bot/InviteTracker.fs | 31 +++++++++++++++++++------------ 6 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 Bot/Admin.fs diff --git a/Bot/Admin.fs b/Bot/Admin.fs new file mode 100644 index 0000000..05fabf3 --- /dev/null +++ b/Bot/Admin.fs @@ -0,0 +1,24 @@ +module Degenz.Admin + +open System.Threading.Tasks +open DSharpPlus.Entities +open DSharpPlus.SlashCommands +open Degenz.Messaging + +type AdminBot() = + inherit ApplicationCommandModule () + + let enforceAdmin (ctx : IDiscordContext) (adminFn : IDiscordContext -> Task) = + let isAdmin = Seq.exists (fun (role : DiscordRole) -> role.Id = GuildEnvironment.roleAdmin) (ctx.GetDiscordMember().Roles) + if isAdmin then + adminFn ctx + else + Messaging.sendSimpleResponse ctx $"You are not admin" |> Async.StartAsTask :> Task + + [] + member this.GetAttributions (ctx : InteractionContext, [] user : DiscordUser) = + enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getAttributions user.Id) + + [] + member this.SetStock (ctx : InteractionContext, [] amount : int64) = + enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.setWhitelistStock (int amount)) diff --git a/Bot/Bot.fs b/Bot/Bot.fs index 0c3b50e..73c4c58 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -16,6 +16,7 @@ let hackerBattleConfig = DiscordConfiguration() let storeConfig = DiscordConfiguration() let stealConfig = DiscordConfiguration() let inviterConfig = DiscordConfiguration() +let adminConfig = DiscordConfiguration() //let slotMachineConfig = DiscordConfiguration() //hackerBattleConfig.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace //storeConfig.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace @@ -32,16 +33,21 @@ stealConfig.Intents <- DiscordIntents.All inviterConfig.TokenType <- TokenType.Bot inviterConfig.Intents <- DiscordIntents.All +adminConfig.TokenType <- TokenType.Bot +adminConfig.Intents <- DiscordIntents.All + hackerBattleConfig.Token <- GuildEnvironment.tokenHackerBattle storeConfig.Token <- GuildEnvironment.tokenStore stealConfig.Token <- GuildEnvironment.tokenSteal inviterConfig.Token <- GuildEnvironment.tokenInviter +adminConfig.Token <- GuildEnvironment.tokenAdmin //slotMachineConfig.Token <- Environment.GetEnvironmentVariable("BOT_SLOT_MACHINE") let hackerBattleBot = new DiscordClient(hackerBattleConfig) let storeBot = new DiscordClient(storeConfig) let stealBot = new DiscordClient(stealConfig) let inviterBot = new DiscordClient(inviterConfig) +let adminBot = new DiscordClient(adminConfig) //let slotMachineBot = new DiscordClient(slotMachineConfig) //let clients = [| hackerBattleBot ; storeBot ; slotMachineBot |] @@ -49,12 +55,14 @@ let hackerCommands = hackerBattleBot.UseSlashCommands() let storeCommands = storeBot.UseSlashCommands() let stealCommands = stealBot.UseSlashCommands() let inviterCommands = inviterBot.UseSlashCommands() +let adminCommands = adminBot.UseSlashCommands() //let sc3 = slotMachineBot.UseSlashCommands() hackerCommands.RegisterCommands(guild); storeCommands.RegisterCommands(guild); stealCommands.RegisterCommands(guild); inviterCommands.RegisterCommands(guild); +adminCommands.RegisterCommands(guild); //hackerCommands.RegisterCommands(guild); //sc3.RegisterCommands(guild); @@ -95,6 +103,7 @@ GuildEnvironment.botUserArmory <- Some storeBot.CurrentUser inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously GuildEnvironment.botClientRecruit <- Some inviterBot +adminBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously //stealBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously let rec loop areBotsRunning = diff --git a/Bot/Bot.fsproj b/Bot/Bot.fsproj index 23254fe..e7fe963 100644 --- a/Bot/Bot.fsproj +++ b/Bot/Bot.fsproj @@ -28,6 +28,7 @@ + diff --git a/Bot/DbService.fs b/Bot/DbService.fs index b45bb1a..1f0ccde 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -259,3 +259,18 @@ let updateWhitelistStock () = async { return true with _ -> return false } + +let setWhitelistStock amount = async { + try + do! connStr + |> Sql.connect + |> Sql.parameters [ ( "amount" , Sql.int amount ) ] + |> Sql.query """ + UPDATE item SET stock = @amount WHERE symbol = 'WHITELIST' + """ + |> Sql.executeNonQueryAsync + |> Async.AwaitTask + |> Async.Ignore + return true + with _ -> return false +} diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 1f0fbb6..6b0d217 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -22,6 +22,7 @@ let tokenSteal = getVar "TOKEN_STEAL" let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE" let tokenStore = getVar "TOKEN_STORE" let tokenInviter = getVar "TOKEN_INVITER" +let tokenAdmin = getVar "TOKEN_ADMINBOT" let tokenMixpanel = getVar "TOKEN_MIXPANEL" let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE" let channelTraining = getId "CHANNEL_TRAINING" @@ -44,6 +45,7 @@ let roleTrainee = getId "ROLE_TRAINEE" let roleHacker = getId "ROLE_HACKER" let rolePrisoner = getId "ROLE_PRISONER" let roleWhitelist = getId "ROLE_WHITELIST" +let roleAdmin = getId "ROLE_ADMIN" let mutable botUserHackerBattle : DiscordUser option = None let mutable botUserArmory : DiscordUser option = None diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index cf3fab6..7174122 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -232,14 +232,15 @@ let private listServerInvites (ctx : IDiscordContext) = task { do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) } -let private getAttributions (ctx : IDiscordContext) userId = task { - let! total = getInviteAttributions(userId) - let msg = - DiscordInteractionResponseBuilder() - .AsEphemeral(true) - .WithContent($"<@{userId}> has invited {total} people") - do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) -} +let getAttributions userId (ctx : IDiscordContext) = + task { + let! total = getInviteAttributions(userId) + let msg = + DiscordInteractionResponseBuilder() + .AsEphemeral(true) + .WithContent($"<@{userId}> has invited {total} people") + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) + } :> Task let private getInvitedUsersForId (ctx : IDiscordContext) = task { let! users = getInvitedUsers (ctx.GetDiscordMember().Id) @@ -581,6 +582,16 @@ let handleGuildMemberAdded _ (eventArgs : GuildMemberAddEventArgs) = do! processNewUser eventArgs } :> Task +let rec setWhitelistStock amount (ctx : IDiscordContext) = + task { + do! Messaging.defer ctx + let! result = DbService.setWhitelistStock amount + if result then + do! Messaging.sendFollowUpMessage ctx $"Set Whitelist stock to {amount}" + else + do! Messaging.sendFollowUpMessage ctx $"Error setting WL to {amount}, make sure it's greater than 0" + } :> Task + type Inviter() = inherit ApplicationCommandModule () @@ -596,10 +607,6 @@ type Inviter() = member this.ListServerInvites (ctx : InteractionContext) = listServerInvites (DiscordInteractionContext ctx) -// [] - member this.getAttributions (ctx : InteractionContext, [] user : DiscordUser) = - getAttributions (DiscordInteractionContext ctx) user.Id - // [] member this.ClearInvites (ctx : InteractionContext) = clearInvites (DiscordInteractionContext ctx) From 0e77c26b82d9203aa50268643610b1875176651c Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 12:52:00 +0700 Subject: [PATCH 2/6] Use same recruited embed --- Bot/Admin.fs | 2 +- Bot/InviteTracker.fs | 45 ++++++++++++++++++++++---------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Bot/Admin.fs b/Bot/Admin.fs index 05fabf3..69c85fc 100644 --- a/Bot/Admin.fs +++ b/Bot/Admin.fs @@ -17,7 +17,7 @@ type AdminBot() = [] member this.GetAttributions (ctx : InteractionContext, [] user : DiscordUser) = - enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getAttributions user.Id) + enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getInvitedUsersForId) [] member this.SetStock (ctx : InteractionContext, [] amount : int64) = diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index 02356f8..8297df7 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -242,28 +242,29 @@ let getAttributions userId (ctx : IDiscordContext) = do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) } :> Task -let private getInvitedUsersForId (ctx : IDiscordContext) = task { - let! users = getInvitedUsers (ctx.GetDiscordMember().Id) - let! total = getInvitedUserCount (ctx.GetDiscordMember().Id) - let sb = StringBuilder() - let mutable count = 0 - for user in users do - count <- count + 1 - sb.AppendLine($"{count}.) <@{user}>") |> ignore - let msg = - let str = - if users.Length > 0 then - $"**Total Recruited:** `{total} Degenz`\n**Total Earned:** `{total * InviteRewardAmount} 💰$GBT`\n\n**Last 10 users recruited:**\n{sb}" - else - $"You haven't recruited anyone yet, use the `/recruit` command to get the recruitment link" - DiscordInteractionResponseBuilder() - .AsEphemeral(true) - .WithContent(str) - do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) - let user = ctx.GetDiscordMember() - let channel = ctx.GetChannel() - do! Analytics.recruitedCommand total user.Id user.Username channel -} +let getInvitedUsersForId (ctx : IDiscordContext) = + task { + let! users = getInvitedUsers (ctx.GetDiscordMember().Id) + let! total = getInvitedUserCount (ctx.GetDiscordMember().Id) + let sb = StringBuilder() + let mutable count = 0 + for user in users do + count <- count + 1 + sb.AppendLine($"{count}.) <@{user}>") |> ignore + let msg = + let str = + if users.Length > 0 then + $"**Total Recruited:** `{total} Degenz`\n**Total Earned:** `{total * InviteRewardAmount} 💰$GBT`\n\n**Last 10 users recruited:**\n{sb}" + else + $"You haven't recruited anyone yet, use the `/recruit` command to get the recruitment link" + DiscordInteractionResponseBuilder() + .AsEphemeral(true) + .WithContent(str) + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) + let user = ctx.GetDiscordMember() + let channel = ctx.GetChannel() + do! Analytics.recruitedCommand total user.Id user.Username channel + } :> Task let clearInvites (ctx : IDiscordContext) = task { let! invites = ctx.GetGuild().GetInvitesAsync() From b2107b6664489eef50b2f013f8b331777c749f4b Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 12:58:58 +0700 Subject: [PATCH 3/6] Defer --- Bot/InviteTracker.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index 8297df7..d34d64a 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -244,6 +244,7 @@ let getAttributions userId (ctx : IDiscordContext) = let getInvitedUsersForId (ctx : IDiscordContext) = task { + do! Messaging.defer ctx let! users = getInvitedUsers (ctx.GetDiscordMember().Id) let! total = getInvitedUserCount (ctx.GetDiscordMember().Id) let sb = StringBuilder() @@ -257,10 +258,10 @@ let getInvitedUsersForId (ctx : IDiscordContext) = $"**Total Recruited:** `{total} Degenz`\n**Total Earned:** `{total * InviteRewardAmount} 💰$GBT`\n\n**Last 10 users recruited:**\n{sb}" else $"You haven't recruited anyone yet, use the `/recruit` command to get the recruitment link" - DiscordInteractionResponseBuilder() + DiscordFollowupMessageBuilder() .AsEphemeral(true) .WithContent(str) - do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) + do! ctx.FollowUp(msg) let user = ctx.GetDiscordMember() let channel = ctx.GetChannel() do! Analytics.recruitedCommand total user.Id user.Username channel From bdcd717a403355e8dc47ba4d82ab2f3ae7a50af8 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 13:06:33 +0700 Subject: [PATCH 4/6] Ugh --- Bot/InviteTracker.fs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index d34d64a..a821fe9 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -244,9 +244,13 @@ let getAttributions userId (ctx : IDiscordContext) = let getInvitedUsersForId (ctx : IDiscordContext) = task { + printfn "1" do! Messaging.defer ctx + printfn "2" let! users = getInvitedUsers (ctx.GetDiscordMember().Id) + printfn "3" let! total = getInvitedUserCount (ctx.GetDiscordMember().Id) + printfn "4" let sb = StringBuilder() let mutable count = 0 for user in users do @@ -262,9 +266,10 @@ let getInvitedUsersForId (ctx : IDiscordContext) = .AsEphemeral(true) .WithContent(str) do! ctx.FollowUp(msg) + printfn "5" let user = ctx.GetDiscordMember() - let channel = ctx.GetChannel() - do! Analytics.recruitedCommand total user.Id user.Username channel + do! Analytics.recruitedCommand total user.Id user.Username (ctx.GetChannel()) + printfn "6" } :> Task let clearInvites (ctx : IDiscordContext) = task { From 152ff8c110ea30d3003fd15f5debd22b0178c94b Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 13:26:00 +0700 Subject: [PATCH 5/6] Remove prints --- Bot/InviteTracker.fs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index a821fe9..c8ac2a9 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -153,7 +153,7 @@ let private getInviteAttributions userId = |> Sql.executeRowAsync (fun read -> read.int "count") |> Async.AwaitTask -let private getInvitedUsers userId = +let getInvitedUsers userId = connStr |> Sql.connect |> Sql.parameters [ "did" , Sql.string (string userId) ] @@ -244,13 +244,9 @@ let getAttributions userId (ctx : IDiscordContext) = let getInvitedUsersForId (ctx : IDiscordContext) = task { - printfn "1" do! Messaging.defer ctx - printfn "2" let! users = getInvitedUsers (ctx.GetDiscordMember().Id) - printfn "3" let! total = getInvitedUserCount (ctx.GetDiscordMember().Id) - printfn "4" let sb = StringBuilder() let mutable count = 0 for user in users do @@ -266,10 +262,8 @@ let getInvitedUsersForId (ctx : IDiscordContext) = .AsEphemeral(true) .WithContent(str) do! ctx.FollowUp(msg) - printfn "5" let user = ctx.GetDiscordMember() do! Analytics.recruitedCommand total user.Id user.Username (ctx.GetChannel()) - printfn "6" } :> Task let clearInvites (ctx : IDiscordContext) = task { From 9b5c3ef81e4ef1df406dce0f2f054d7a7dad2bf9 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 5 Apr 2022 14:09:16 +0700 Subject: [PATCH 6/6] Scan command --- Bot/DbService.fs | 14 ++++++++++++++ Bot/Games/HackerBattle.fs | 30 +++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Bot/DbService.fs b/Bot/DbService.fs index 1f0ccde..2f0eb5f 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -237,6 +237,20 @@ let addPlayerEvent (did : uint64) (playerEvent : PlayerEvent) = |> Sql.executeNonQueryAsync |> Async.AwaitTask +let getRandomHackablePlayers (did : uint64) = + connStr + |> Sql.connect + |> Sql.parameters [ "did", Sql.string (string did) ] + |> Sql.query """ + SELECT discord_id, display_name FROM "user" + JOIN user_achievements_achievement uaa ON "user".id = uaa.user_id + JOIN achievement a ON uaa.achievement_id = a.id AND a.symbol = 'FINISHED_TRAINER' + WHERE "user".in_game = true AND gbt > 20 AND "user".discord_id != @did + ORDER BY random() LIMIT 5 + """ + |> Sql.executeAsync (fun read -> {| Id = read.string "discord_id" |> uint64 ; Name = read.string "display_name" |}) + |> Async.AwaitTask + let getWhitelistItem () = connStr |> Sql.connect diff --git a/Bot/Games/HackerBattle.fs b/Bot/Games/HackerBattle.fs index 3317664..262b111 100644 --- a/Bot/Games/HackerBattle.fs +++ b/Bot/Games/HackerBattle.fs @@ -227,6 +227,30 @@ let handleDefense (ctx : IDiscordContext) = }) }) +let scan (ctx : IDiscordContext) = + executePlayerAction ctx (fun _ -> async { + let! targets = DbService.getRandomHackablePlayers (ctx.GetDiscordMember().Id) + let sb = StringBuilder() + let mutable count = 0 + for t in targets do + count <- count + 1 + sb.AppendLine($"{count}.) <@{t.Id}>") |> ignore + let msg = + if targets.Length > 0 then + $"**Targets Connected to the Network:**\n\n These are 5 targets you can attempt to hack right now... let's hope they're not shielded!\n\n{sb}" + else + $"There don't seem to be any targets available right now" + let embed = + DiscordEmbedBuilder() + .WithColor(DiscordColor.Green) + .WithDescription(msg) + let builder = + DiscordFollowupMessageBuilder() + .AddEmbed(embed) + .AsEphemeral(true) + do! ctx.FollowUp(builder) |> Async.AwaitTask + }) + let arsenal (ctx : IDiscordContext) = executePlayerAction ctx (fun player -> async { let updatedPlayer = Player.removeExpiredActions player @@ -297,7 +321,11 @@ type HackerGame() = [] member this.ShieldCommand (ctx : InteractionContext) = - enforceChannels (DiscordInteractionContext ctx) Trainer.defend defend + enforceChannels (DiscordInteractionContext ctx) Trainer. defend + + [] + member this.ScanCommand (ctx : InteractionContext) = + enforceChannels (DiscordInteractionContext ctx) scan scan // [] member this.TestAutoComplete (ctx : InteractionContext) =