New Whitelist flow and accept invite when completing training

This commit is contained in:
Joseph Ferano 2022-03-24 23:21:08 +07:00
parent 7b26bd05cd
commit a8ab4a6abd
6 changed files with 216 additions and 77 deletions

View File

@ -81,20 +81,20 @@ let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEven
:> Task :> Task
//hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf)) //hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf))
//if guild <> 922419263275425832uL then if guild <> 922419263275425832uL then
// Trainer.sendInitialEmbed hackerBattleBot // Trainer.sendInitialEmbed hackerBattleBot
InviteTracker.sendInitialEmbed inviterBot InviteTracker.sendInitialEmbed inviterBot
hackerBattleBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously hackerBattleBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botUserHackerBattle <- Some hackerBattleBot.CurrentUser GuildEnvironment.botUserHackerBattle <- Some hackerBattleBot.CurrentUser
storeBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously storeBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botUserArmory <- Some storeBot.CurrentUser GuildEnvironment.botUserArmory <- Some storeBot.CurrentUser
inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
//stealBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously //stealBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
let rec loop areBotsRunning = let rec loop areBotsRunning =

View File

@ -15,6 +15,7 @@ type User = {
Focus : int Focus : int
Charisma : int Charisma : int
Luck : int Luck : int
Active : bool
} }
let getPlayerEvents (did : uint64) = let getPlayerEvents (did : uint64) =
@ -75,7 +76,7 @@ let tryFindPlayer (discordId : uint64) = async {
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "did", Sql.string (string discordId) ] |> Sql.parameters [ "did", Sql.string (string discordId) ]
|> Sql.query """ |> Sql.query """
SELECT discord_id, display_name, gbt, inventory, strength, focus, charisma, luck FROM "user" SELECT discord_id, display_name, gbt, in_game, inventory, strength, focus, charisma, luck FROM "user"
WHERE discord_id = @did WHERE discord_id = @did
""" """
|> Sql.executeAsync (fun read -> |> Sql.executeAsync (fun read ->
@ -89,6 +90,7 @@ let tryFindPlayer (discordId : uint64) = async {
Focus = read.intOrNone "focus" |> Option.defaultValue 0 Focus = read.intOrNone "focus" |> Option.defaultValue 0
Charisma = read.intOrNone "charisma" |> Option.defaultValue 0 Charisma = read.intOrNone "charisma" |> Option.defaultValue 0
Luck = read.intOrNone "luck" |> Option.defaultValue 0 Luck = read.intOrNone "luck" |> Option.defaultValue 0
Active = read.bool "in_game"
}) })
|> Async.AwaitTask |> Async.AwaitTask
match List.tryHead user with match List.tryHead user with
@ -106,7 +108,8 @@ let tryFindPlayer (discordId : uint64) = async {
Inventory = inventory Inventory = inventory
Events = events Events = events
Stats = { Strength = strength ; Focus = focus ; Charisma = charisma ; Luck = luck } Stats = { Strength = strength ; Focus = focus ; Charisma = charisma ; Luck = luck }
Bank = u.Bank } Bank = u.Bank
Active = u.Active }
with e -> with e ->
printfn $"Got an error{e.Message}" printfn $"Got an error{e.Message}"
return None return None

View File

@ -174,6 +174,7 @@ type PlayerData = {
Events : PlayerEvent list Events : PlayerEvent list
Stats : Stats Stats : Stats
Bank : int<GBT> Bank : int<GBT>
Active : bool
} }
// Achievements : string array // Achievements : string array
// XP : int // XP : int
@ -186,4 +187,5 @@ with member this.toDiscordPlayer = { Id = this.DiscordId ; Name = this.Name }
Stats = Stats.empty Stats = Stats.empty
// Achievements = [||] // Achievements = [||]
// XP = 0 // XP = 0
Bank = 0<GBT> } Bank = 0<GBT>
Active = false }

View File

@ -174,6 +174,9 @@ type the `/arsenal` command NOW"""
if not completed then if not completed then
do! sendFollowUpMessage ctx message do! sendFollowUpMessage ctx message
else else
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!") do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!")
}) })
@ -219,13 +222,20 @@ let handleArsenal (ctx : IDiscordContext) = PlayerInteractions.executePlayerActi
do! ctx.FollowUp(embed) |> Async.AwaitTask do! ctx.FollowUp(embed) |> Async.AwaitTask
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee) let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
do! ctx.GetDiscordMember().RevokeRoleAsync(role) do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
|> Async.AwaitTask
do! Async.Sleep 2000 let role = ctx.GetGuild().GetRole(GuildEnvironment.roleHacker)
do! ctx.GetDiscordMember().GrantRoleAsync(role) |> Async.AwaitTask
do! InviteTracker.acceptInvite ctx player |> Async.AwaitTask
do! Async.Sleep 1000
do! sendFollowUpMessage ctx $"Now get out of there and go hack other Degenz in the <#{GuildEnvironment.channelBattle}> channel!" do! sendFollowUpMessage ctx $"Now get out of there and go hack other Degenz in the <#{GuildEnvironment.channelBattle}> channel!"
else else
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!") do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!")
}) })

View File

@ -26,6 +26,9 @@ let channelArmory = getId "CHANNEL_ARMORY"
let channelBattle = getId "CHANNEL_BATTLE" let channelBattle = getId "CHANNEL_BATTLE"
let channelWelcome = getId "CHANNEL_WELCOME" let channelWelcome = getId "CHANNEL_WELCOME"
let channelWhitelist = getId "CHANNEL_WHITELIST" let channelWhitelist = getId "CHANNEL_WHITELIST"
let channelElite = getId "CHANNEL_ELITE"
let channelTosserTed = getId "CHANNEL_TOSSERTED"
let channelShelters = getId "CHANNEL_SHELTERS"
//let channelBackAlley = getId "CHANNEL_BACKALLEY" //let channelBackAlley = getId "CHANNEL_BACKALLEY"
//let channelMarket = getId "CHANNEL_MARKET" //let channelMarket = getId "CHANNEL_MARKET"
//let channelAccessoryShop = getId "CHANNEL_ACCESSORIES" //let channelAccessoryShop = getId "CHANNEL_ACCESSORIES"
@ -33,8 +36,10 @@ let channelWhitelist = getId "CHANNEL_WHITELIST"
//let channelThievery = getId "CHANNEL_THIEVERY" //let channelThievery = getId "CHANNEL_THIEVERY"
let botIdHackerBattle = getId "BOT_HACKER_BATTLE" let botIdHackerBattle = getId "BOT_HACKER_BATTLE"
let botIdArmory = getId "BOT_ARMORY" let botIdArmory = getId "BOT_ARMORY"
let botIdTosserTed = getId "BOT_TOSSERTED"
//let botInviter = getId "BOT_INVITER" //let botInviter = getId "BOT_INVITER"
let roleTrainee = getId "ROLE_TRAINEE" let roleTrainee = getId "ROLE_TRAINEE"
let roleHacker = getId "ROLE_HACKER"
let rolePrisoner = getId "ROLE_PRISONER" let rolePrisoner = getId "ROLE_PRISONER"
let roleWhitelist = getId "ROLE_WHITELIST" let roleWhitelist = getId "ROLE_WHITELIST"

View File

@ -11,7 +11,7 @@ open Npgsql.FSharp
let connStr = GuildEnvironment.connectionString let connStr = GuildEnvironment.connectionString
let InviteRewardAmount = 100<GBT> let InviteRewardAmount = 100<GBT>
let WhitelistInviteRequirement = 5 let WhitelistPrice = 1000
type Invite = { type Invite = {
Code : string Code : string
@ -19,20 +19,18 @@ type Invite = {
Count : int Count : int
} }
let getInvites () = async { let private mapInvite (reader : RowReader) = {
Code = reader.string "code"
Inviter = reader.string "inviter" |> uint64
Count = reader.int "count"
}
let private getInvites () = async {
let! invites = let! invites =
connStr connStr
|> Sql.connect |> Sql.connect
// TODO: Invites shouldn't expire anymore |> Sql.query "SELECT code, inviter, count FROM invite"
|> Sql.query """ |> Sql.executeAsync mapInvite
SELECT code, inviter, count FROM invite
WHERE created_at > (current_timestamp at time zone 'utc') - interval '1 day'
"""
|> Sql.executeAsync (fun read -> {
Code = read.string "code"
Inviter = read.string "inviter" |> uint64
Count = read.int "count"
})
|> Async.AwaitTask |> Async.AwaitTask
return return
invites invites
@ -40,7 +38,7 @@ let getInvites () = async {
|> Map.ofList |> Map.ofList
} }
let getInvitesFromUser discordId = async { let private getInvitesFromUser discordId = async {
let! invites = let! invites =
connStr connStr
|> Sql.connect |> Sql.connect
@ -61,7 +59,7 @@ let getInvitesFromUser discordId = async {
|> Map.ofList |> Map.ofList
} }
let createInvite inviter code = let private createInvite inviter code =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "code" , Sql.string code ; "inviter" , Sql.string (string inviter) ] |> Sql.parameters [ "code" , Sql.string code ; "inviter" , Sql.string (string inviter) ]
@ -69,7 +67,7 @@ let createInvite inviter code =
|> Sql.executeNonQueryAsync |> Sql.executeNonQueryAsync
|> Async.AwaitTask |> Async.AwaitTask
let addInvitedUser did code count = let private addInvitedUser did code count =
try try
connStr connStr
|> Sql.connect |> Sql.connect
@ -84,7 +82,7 @@ let addInvitedUser did code count =
|> Async.Ignore |> Async.Ignore
with _ -> async.Zero () with _ -> async.Zero ()
let acceptInvite did = let private markInvitedAccepted did =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "did" , Sql.string (string did) ] |> Sql.parameters [ "did" , Sql.string (string did) ]
@ -92,7 +90,19 @@ let acceptInvite did =
|> Sql.executeNonQueryAsync |> Sql.executeNonQueryAsync
|> Async.AwaitTask |> Async.AwaitTask
let removeInvitedUser did = let private getInviteFromInvitedUser invitedUser =
connStr
|> Sql.connect
|> Sql.parameters [ "did" , Sql.string (string invitedUser) ]
|> Sql.query """
SELECT code, inviter, count FROM invite
JOIN invited_user iu ON invite.id = iu.invite_id
WHERE iu.discord_id = @did
"""
|> Sql.executeRowAsync mapInvite
|> Async.AwaitTask
let private removeInvitedUser did =
try try
connStr connStr
|> Sql.connect |> Sql.connect
@ -103,7 +113,7 @@ let removeInvitedUser did =
|> Async.Ignore |> Async.Ignore
with _ -> async.Zero () with _ -> async.Zero ()
let checkUserInvited userId = async { let private checkUserAlreadyInvited userId = async {
let! result = let! result =
connStr connStr
|> Sql.connect |> Sql.connect
@ -117,7 +127,22 @@ let checkUserInvited userId = async {
return List.isEmpty result |> not return List.isEmpty result |> not
} }
let getInviteAttributions userId = let checkInviteAccepted (userId : uint64) = async {
try
let! result =
connStr
|> Sql.connect
|> Sql.parameters [ "did" , Sql.string (string userId) ]
|> Sql.query "SELECT accepted FROM invited_user WHERE discord_id = @did"
|> Sql.executeRowAsync (fun read -> read.bool "accepted")
|> Async.AwaitTask
return result
with ex ->
printfn "%s %u" ex.Message userId
return false
}
let private getInviteAttributions userId =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "did" , Sql.string (string userId) ] |> Sql.parameters [ "did" , Sql.string (string userId) ]
@ -129,7 +154,7 @@ let getInviteAttributions userId =
|> Sql.executeRowAsync (fun read -> read.int "count") |> Sql.executeRowAsync (fun read -> read.int "count")
|> Async.AwaitTask |> Async.AwaitTask
let getInvitedUsers userId = let private getInvitedUsers userId =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "did" , Sql.string (string userId) ] |> Sql.parameters [ "did" , Sql.string (string userId) ]
@ -141,7 +166,7 @@ let getInvitedUsers userId =
|> Sql.executeAsync (fun read -> read.string "discord_id" |> uint64) |> Sql.executeAsync (fun read -> read.string "discord_id" |> uint64)
|> Async.AwaitTask |> Async.AwaitTask
let createGuildInvite (ctx : IDiscordContext) showWhitelistReward = let private createGuildInvite (ctx : IDiscordContext) showWhitelistReward =
task { task {
let invitesRequired = 5 let invitesRequired = 5
let rewardMsg = let rewardMsg =
@ -168,7 +193,7 @@ let createGuildInvite (ctx : IDiscordContext) showWhitelistReward =
} :> Task } :> Task
let listServerInvites (ctx : IDiscordContext) = task { let private listServerInvites (ctx : IDiscordContext) = task {
let! invites = ctx.GetGuild().GetInvitesAsync() let! invites = ctx.GetGuild().GetInvitesAsync()
let sb = StringBuilder() let sb = StringBuilder()
for invite in invites do for invite in invites do
@ -180,7 +205,7 @@ let listServerInvites (ctx : IDiscordContext) = task {
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg)
} }
let getAttributions (ctx : IDiscordContext) userId = task { let private getAttributions (ctx : IDiscordContext) userId = task {
let! total = getInviteAttributions(userId) let! total = getInviteAttributions(userId)
let msg = let msg =
DiscordInteractionResponseBuilder() DiscordInteractionResponseBuilder()
@ -189,7 +214,7 @@ let getAttributions (ctx : IDiscordContext) userId = task {
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg)
} }
let getInvitedUsersForId (ctx : IDiscordContext) = task { let private getInvitedUsersForId (ctx : IDiscordContext) = task {
let! users = getInvitedUsers(ctx.GetDiscordMember().Id) let! users = getInvitedUsers(ctx.GetDiscordMember().Id)
let sb = StringBuilder() let sb = StringBuilder()
let mutable count = 0 let mutable count = 0
@ -213,33 +238,45 @@ let clearInvites (ctx : IDiscordContext) = task {
do! do!
invites invites
|> Seq.map (fun invite -> invite.DeleteAsync() |> Async.AwaitTask) |> Seq.map (fun invite -> invite.DeleteAsync() |> Async.AwaitTask)
|> Async.Parallel |> Async.Sequential
|> Async.Ignore |> Async.Ignore
} }
let processNewUser (eventArgs : GuildMemberAddEventArgs) = // Discord doesn't have any way to tell you if the user came via an invite, the only way to tell is to compare the
// cached invites in the DB to the ones in the guild and see if any has been incremented
let private processNewUser (eventArgs : GuildMemberAddEventArgs) =
task { task {
let! guildInvites = eventArgs.Guild.GetInvitesAsync() let! guildInvites = eventArgs.Guild.GetInvitesAsync()
let! cachedInvites = getInvites () let! cachedInvites = getInvites ()
for invite in guildInvites do for invite in guildInvites do
let result = cachedInvites.TryFind(invite.Code) let result = cachedInvites.TryFind(invite.Code)
match result with match result with
| Some (inviter,count) -> | Some (_,count) ->
if invite.Uses > count then if invite.Uses > count then
do! addInvitedUser eventArgs.Member.Id invite.Code invite.Uses |> Async.Ignore do! addInvitedUser eventArgs.Member.Id invite.Code invite.Uses |> Async.Ignore
let! _ = acceptInvite eventArgs.Member.Id | None -> ()
let! player = DbService.tryFindPlayer inviter } :> Task
let acceptInvite (ctx : IDiscordContext) (invitedPlayer : PlayerData) =
task {
match! checkInviteAccepted invitedPlayer.DiscordId with
| false ->
let! _ = markInvitedAccepted invitedPlayer.DiscordId |> Async.Ignore
try
let! inviter = getInviteFromInvitedUser invitedPlayer.DiscordId
let! player = DbService.tryFindPlayer inviter.Inviter
match player with match player with
| Some player -> | Some player ->
do! DbService.updatePlayerCurrency (int InviteRewardAmount) player |> Async.Ignore do! DbService.updatePlayerCurrency (int InviteRewardAmount) player |> Async.Ignore
let builder = DiscordMessageBuilder() let builder = DiscordMessageBuilder()
builder.WithContent($"{eventArgs.Member.DisplayName} was recruited to the server. <@{player.DiscordId}> just earned {InviteRewardAmount} 💰$GBT for their efforts!") |> ignore builder.WithContent($"{invitedPlayer.Name} was recruited to the server. <@{player.DiscordId}> just earned {InviteRewardAmount} 💰$GBT for their efforts!") |> ignore
let channel = eventArgs.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle) let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
do! channel.SendMessageAsync(builder) do! channel.SendMessageAsync(builder)
|> Async.AwaitTask |> Async.AwaitTask
|> Async.Ignore |> Async.Ignore
| None -> return () | None -> return ()
| None -> () with _ -> ()
| true -> return ()
} :> Task } :> Task
// If we do it like this then there's an obvious exploit where the user can come and go as many times and it will keep // If we do it like this then there's an obvious exploit where the user can come and go as many times and it will keep
@ -249,16 +286,30 @@ let processNewUser (eventArgs : GuildMemberAddEventArgs) =
// do! removeInvitedUser eventArgs.Member.Id // do! removeInvitedUser eventArgs.Member.Id
// } :> Task // } :> Task
//Degenz Game
//Mint Date: April 2022
//Supply: 3,333
//Price: 1.984 $SOL
//Your NFT will be your In-Game Character that provides you with unique traits, and abilities in game.
let sendInitialEmbed (client : DiscordClient) = let sendInitialEmbed (client : DiscordClient) =
async { async {
try try
let! channel = client.GetChannelAsync(GuildEnvironment.channelWhitelist) |> Async.AwaitTask let! channel = client.GetChannelAsync(GuildEnvironment.channelWhitelist) |> Async.AwaitTask
let builder = DiscordMessageBuilder() let builder = DiscordMessageBuilder()
let embed = DiscordEmbedBuilder() let embed = DiscordEmbedBuilder()
embed.ImageUrl <- "https://securitygladiators.com/wp-content/uploads/2020/09/Whitelist-Website-Featured-Image.jpg" embed.ImageUrl <- "https://s1.gifyu.com/images/whitelist-image-2.gif"
embed.Title <- "Degenz Game"
embed.Description <- """
Mint Date: **April 2022**
Supply: **3,333**
Price: **1.984 $SOL**
Your NFT will be your In-Game Character that provides you with unique traits, and abilities in game.
"""
builder.AddEmbed embed |> ignore builder.AddEmbed embed |> ignore
builder.Content <- "Click on the button to get whitelist!" let button = DiscordButtonComponent(ButtonStyle.Success, $"GimmeWhitelist", $"Give Me Whitelist") :> DiscordComponent
let button = DiscordButtonComponent(ButtonStyle.Success, $"GimmeWhitelist", $"Gimme") :> DiscordComponent
builder.AddComponents [| button |] |> ignore builder.AddComponents [| button |] |> ignore
do! channel.SendMessageAsync(builder) do! channel.SendMessageAsync(builder)
|> Async.AwaitTask |> Async.AwaitTask
@ -268,40 +319,107 @@ let sendInitialEmbed (client : DiscordClient) =
} |> Async.RunSynchronously } |> Async.RunSynchronously
type WhitelistResult = type WhitelistResult =
| NotEnoughInvites of currentAmount : int | NotInGame
| Granted of DiscordRole | NotEnoughGBT of currentAmount : int
| Granted of PlayerData
| AlreadyWhitelisted | AlreadyWhitelisted
let tryGrantWhitelist (ctx : IDiscordContext) = let tryGrantWhitelist (ctx : IDiscordContext) =
async { task {
let user = ctx.GetDiscordMember() let user = ctx.GetDiscordMember()
match! DbService.tryFindPlayer user.Id with
| Some player ->
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhitelist) let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhitelist)
if Seq.contains role user.Roles if player.Active then
then return AlreadyWhitelisted if Seq.contains role user.Roles then
return AlreadyWhitelisted
else else
let! total = getInviteAttributions user.Id if int player.Bank >= WhitelistPrice then
if total >= WhitelistInviteRequirement then return Granted player
return Granted role
else else
return NotEnoughInvites total return NotEnoughGBT (int player.Bank)
else
return NotInGame
| None -> return NotInGame
} }
let handleWhitelist (ctx : IDiscordContext) = let handleGimmeWhitelist (ctx : IDiscordContext) =
task { task {
let builder = DiscordInteractionResponseBuilder().AsEphemeral(true) let builder = DiscordInteractionResponseBuilder().AsEphemeral(true)
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder)
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
match! tryGrantWhitelist ctx with match! tryGrantWhitelist ctx with
| NotInGame ->
builder.Content <- $"""
Woah slow down buddy… Youre not even in the game yet!
To get Whitelisted you need to buy it with **$GBT** by playing the game.
Go to <#{GuildEnvironment.channelShelters}> NOW to get assigned a private bunk, and **JOIN THE GAME!**
"""
| AlreadyWhitelisted -> | AlreadyWhitelisted ->
builder.Content <- "You are already whitelisted" builder.Content <- $"""
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) 🎉 You're already WHITELISTED!
| NotEnoughInvites total ->
do! createGuildInvite ctx true Come hang with all the other VIP Degenz in the <#{GuildEnvironment.channelElite}>
// builder.Content <- "Testing" """
// do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) | NotEnoughGBT total ->
// do! async.Zero() builder.Content <- $"""
| Granted role -> You don't have enough **$GBT** to buy a WHITELIST spot!
WHITELIST aint cheap, and looks like you're `{WhitelistPrice - total} $GBT` short.
Go earn more $GBT, and come back when you have `{WhitelistPrice} $GBT`!
`/recruit` other Degenz and get `{InviteRewardAmount} 💰 $GBT` for every Degen you recruit!
`/hack` other Degenz in <#{GuildEnvironment.channelBattle}> to steal their **$GBT**
`/toss` against <@{GuildEnvironment.botIdTosserTed}> in <#{GuildEnvironment.channelTosserTed}> to try double up!
Good luck Degen
"""
| Granted _ ->
let button = DiscordButtonComponent(ButtonStyle.Success, $"BuyWhitelist", $"Buy Now") :> DiscordComponent
builder.AddComponents([ button ]) |> ignore
builder.Content <- """
Look at you Degen, you played Big Brothers games and made it out alive!
Now you can use your $GBT to pay for one of our coveted Whitelist spots.
Click buy now below and the role will be auto assigned to you.
"""
do! ctx.FollowUp(builder)
} :> Task
let handleBuyWhitelist (ctx : IDiscordContext) =
task {
let builder = DiscordInteractionResponseBuilder().AsEphemeral(true)
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder)
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
match! tryGrantWhitelist ctx with
| NotInGame -> builder.Content <- $"You somehow have left the game, what exactly are you doing?"
| AlreadyWhitelisted ->
builder.Content <- $"""
🎉 You're already WHITELISTED!
Come hang with all the other VIP Degenz in the <#{GuildEnvironment.channelElite}>
"""
| NotEnoughGBT _ -> builder.Content <- $"You somehow do not have enough $GBT, what exactly are you doing?"
| Granted player ->
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhitelist)
do! ctx.GetDiscordMember().GrantRoleAsync(role) do! ctx.GetDiscordMember().GrantRoleAsync(role)
builder.Content <- "You have been granted whitelist" let! _ = DbService.updatePlayerCurrency -WhitelistPrice player
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) builder.Content <- $"""
🎉 Congratulations youve been WHITELISTED!
Come hang with all the other VIP Degenz in the <#{GuildEnvironment.channelElite}>
`/recruit` other Degenz and get 💰 $GBT {InviteRewardAmount} for every Degen you recruit!
"""
do! ctx.FollowUp(builder)
} :> Task } :> Task
let handleCreateInvite (ctx : IDiscordContext) = let handleCreateInvite (ctx : IDiscordContext) =
@ -333,12 +451,13 @@ let handleCreateInvite (ctx : IDiscordContext) =
.AsEphemeral(true) .AsEphemeral(true)
do! ctx.FollowUp(msg) do! ctx.FollowUp(msg)
} } :> Task
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
let eventCtx = DiscordEventContext event :> IDiscordContext let eventCtx = DiscordEventContext event :> IDiscordContext
match event.Id with match event.Id with
| id when id.StartsWith("GimmeWhitelist") -> handleWhitelist eventCtx | id when id.StartsWith("GimmeWhitelist") -> handleGimmeWhitelist eventCtx
| id when id.StartsWith("BuyWhitelist") -> handleBuyWhitelist eventCtx
| id when id.StartsWith("CreateGuildInvite") -> handleCreateInvite eventCtx | id when id.StartsWith("CreateGuildInvite") -> handleCreateInvite eventCtx
| _ -> | _ ->
task { task {
@ -350,7 +469,7 @@ let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEv
let handleGuildMemberAdded _ (eventArgs : GuildMemberAddEventArgs) = let handleGuildMemberAdded _ (eventArgs : GuildMemberAddEventArgs) =
task { task {
let! exists = checkUserInvited eventArgs.Member.Id let! exists = checkUserAlreadyInvited eventArgs.Member.Id
if not exists then if not exists then
do! processNewUser eventArgs do! processNewUser eventArgs
} :> Task } :> Task