443 lines
20 KiB
Forth
443 lines
20 KiB
Forth
module Degenz.SlotMachine
|
||
|
||
open System
|
||
open System.Threading.Tasks
|
||
open DSharpPlus
|
||
open DSharpPlus.Entities
|
||
open DSharpPlus.EventArgs
|
||
open Degenz
|
||
open Degenz.Messaging
|
||
open Degenz.Types
|
||
open Npgsql.FSharp
|
||
|
||
type SlotSymbol = {
|
||
index : int
|
||
emojiName : string
|
||
reel1Count : int
|
||
reel2Count : int
|
||
reel3Count : int
|
||
}
|
||
|
||
type Prize =
|
||
| Money of int<GBT>
|
||
| Jackpot
|
||
|
||
type Slot =
|
||
| Symbol of SlotSymbol
|
||
| Any
|
||
|
||
let BigBrother = { index = 0 ; reel1Count = 2 ; reel2Count = 2 ; reel3Count = 2 ; emojiName = "bigbrother" }
|
||
let Eye = { index = 1 ; reel1Count = 2 ; reel2Count = 3 ; reel3Count = 2 ; emojiName = "aneye" }
|
||
let Obey = { index = 2 ; reel1Count = 3 ; reel2Count = 3 ; reel3Count = 3 ; emojiName = "obey" }
|
||
let AnonMask = { index = 3 ; reel1Count = 2 ; reel2Count = 2 ; reel3Count = 4 ; emojiName = "anonmask" }
|
||
let Rat = { index = 4 ; reel1Count = 4 ; reel2Count = 4 ; reel3Count = 4 ; emojiName = "rat" }
|
||
let Ramen = { index = 5 ; reel1Count = 4 ; reel2Count = 5 ; reel3Count = 5 ; emojiName = "ramen" }
|
||
let Sushi = { index = 6 ; reel1Count = 5 ; reel2Count = 5 ; reel3Count = 4 ; emojiName = "sushi" }
|
||
let Pizza = { index = 7 ; reel1Count = 3 ; reel2Count = 3 ; reel3Count = 4 ; emojiName = "pizza" }
|
||
//let Alcohol = { index = 8 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 ; emojiName = "alcohol" }
|
||
//let Circuit = { index = 9 ; reel1Count = 0 ; reel2Count = 0 ; reel3Count = 2 ; emojiName = "circuitboard" }
|
||
//let OldTv = { index = 10 ; reel1Count = 1 ; reel2Count = 2 ; reel3Count = 2 ; emojiName = "oldtv" }
|
||
//let Pills = { index = 11 ; reel1Count = 2 ; reel2Count = 1 ; reel3Count = 2 ; emojiName = "pills" }
|
||
|
||
//let symbols = [ BigBrother ; Eye ; Obey ; AnonMask ; Sushi ; Ramen ; Pizza ; Alcohol ; Circuit ; OldTv ; Pills ; Rat ]
|
||
let symbols = [ BigBrother ; Eye ; Obey ; AnonMask ; Sushi ; Ramen ; Pizza ; Rat ]
|
||
|
||
type PrizeEntry = Slot * Slot * Slot * Prize
|
||
|
||
let prizeTable =
|
||
[| Symbol BigBrother , Symbol BigBrother , Symbol BigBrother , Jackpot
|
||
Symbol Eye , Symbol Eye , Symbol Eye , Money 500<GBT>
|
||
Symbol Eye , Symbol Eye , Symbol AnonMask , Money 500<GBT>
|
||
Symbol AnonMask , Symbol AnonMask , Symbol AnonMask , Money 250<GBT>
|
||
Symbol Obey , Symbol Obey , Symbol Obey , Money 250<GBT>
|
||
Symbol Obey , Symbol Obey , Symbol AnonMask , Money 200<GBT>
|
||
Symbol Sushi , Symbol Sushi , Symbol Sushi , Money 100<GBT>
|
||
Symbol Ramen , Symbol Ramen , Symbol Ramen , Money 100<GBT>
|
||
Symbol Pizza , Symbol Pizza , Symbol Pizza , Money 100<GBT>
|
||
// Symbol Alcohol , Symbol Alcohol , Symbol Alcohol , Money 100<GBT>
|
||
// Symbol OldTv , Symbol OldTv , Symbol OldTv , Money 100<GBT>
|
||
// Symbol Pills , Symbol Pills , Symbol Pills , Money 100<GBT>
|
||
Symbol Rat , Symbol Rat , Symbol Rat , Money 100<GBT>
|
||
Symbol Sushi , Symbol Sushi , Any , Money 50<GBT>
|
||
Any , Any , Symbol Pizza , Money 20<GBT> |]
|
||
|
||
|
||
let calculateOdds (prizeTable : PrizeEntry array) prizeIndex =
|
||
let totalPerReel (reel : SlotSymbol -> int) = List.sumBy reel symbols
|
||
let r1 s = s.reel1Count
|
||
let r2 s = s.reel2Count
|
||
let r3 s = s.reel3Count
|
||
let totalForReel1 = function Symbol sym -> r1 sym | Any -> totalPerReel (fun s -> s.reel1Count)
|
||
let totalForReel2 = function Symbol sym -> r2 sym | Any -> totalPerReel (fun s -> s.reel2Count)
|
||
let totalForReel3 = function Symbol sym -> r3 sym | Any -> totalPerReel (fun s -> s.reel3Count)
|
||
let s1 , s2 , s3 , _ = prizeTable.[prizeIndex]
|
||
totalForReel1 s1 * totalForReel2 s2 * totalForReel3 s3
|
||
|
||
let getTotalCombinations symbols =
|
||
(List.sumBy (fun s -> s.reel1Count) symbols)
|
||
* (List.sumBy (fun s -> s.reel2Count) symbols)
|
||
* (List.sumBy (fun s -> s.reel3Count) symbols)
|
||
|
||
let getOddsForPrize symbols prizeTable prizeIndex =
|
||
let odds = calculateOdds prizeTable prizeIndex
|
||
let total = getTotalCombinations symbols
|
||
$"{odds} in {total }"
|
||
|
||
let getTotalWaysOfWinning (prizeTable : PrizeEntry array) =
|
||
[0..prizeTable.Length - 1]
|
||
|> List.sumBy (calculateOdds prizeTable)
|
||
|
||
let printOddsTable symbols (prizeTable : PrizeEntry array) =
|
||
([0..prizeTable.Length - 1]
|
||
|> List.fold (fun acc elem ->
|
||
let name = function Symbol s -> s.emojiName | Any -> "Any"
|
||
let s1 , s2, s3, _ = prizeTable.[elem]
|
||
acc + $"{name s1} | {name s2} | {name s3} --- {getOddsForPrize symbols prizeTable elem}\n") "")
|
||
+ "-----------------------------\n"
|
||
+ $"Odds of winning something: {getTotalWaysOfWinning prizeTable} out of {getTotalCombinations symbols}"
|
||
|
||
//printOddsTable symbols prizeTable
|
||
|
||
let getReel fn = List.fold (fun acc elem -> (List.replicate (fn elem) elem) @ acc) [] symbols |> List.toArray
|
||
let reel1 = getReel (fun s -> s.reel1Count)
|
||
let reel2 = getReel (fun s -> s.reel2Count)
|
||
let reel3 = getReel (fun s -> s.reel3Count)
|
||
|
||
let slotEmojiNames =
|
||
[| "sushi"
|
||
"bigbrother"
|
||
"pizza"
|
||
"ramen"
|
||
"circuitboard"
|
||
"obey"
|
||
"pills"
|
||
"oldtv"
|
||
"rat"
|
||
"aneye"
|
||
"alcohol"
|
||
"anonmask" |]
|
||
|
||
let PlayPricex1 = 10<GBT>
|
||
let PlayPricex2 = 20<GBT>
|
||
let PlayPricex3 = 30<GBT>
|
||
let BaseJackpotAmount = 0<GBT>
|
||
let sleepTime = 1500
|
||
let mutable guildEmojis : Map<string, DiscordEmoji> option = None
|
||
let mutable anyEmoji : DiscordEmoji option = None
|
||
|
||
let getJackpotAmount () =
|
||
GuildEnvironment.connectionString
|
||
|> Sql.connect
|
||
|> Sql.query """
|
||
SELECT stock FROM store_item
|
||
WHERE store_item.item_id = (SELECT id FROM item WHERE symbol = 'JACKPOT')
|
||
"""
|
||
|> Sql.executeRowAsync (fun read -> (read.int "stock") * 1<GBT>)
|
||
|> Async.AwaitTask
|
||
|
||
let incrementJackpot amount =
|
||
GuildEnvironment.connectionString
|
||
|> Sql.connect
|
||
|> Sql.parameters [ ( "amount" , Sql.int (int amount) ) ]
|
||
|> Sql.query """
|
||
UPDATE store_item SET stock = stock + @amount
|
||
WHERE store_item.item_id = (SELECT id FROM item WHERE symbol = 'JACKPOT')
|
||
"""
|
||
|> Sql.executeNonQueryAsync
|
||
|> Async.AwaitTask
|
||
|
||
let resetJackpot amount =
|
||
GuildEnvironment.connectionString
|
||
|> Sql.connect
|
||
|> Sql.parameters [ ( "amount" , Sql.int (int amount) ) ]
|
||
|> Sql.query """
|
||
UPDATE store_item SET stock = @amount
|
||
WHERE store_item.item_id = (SELECT id FROM item WHERE symbol = 'JACKPOT')
|
||
"""
|
||
|> Sql.executeNonQueryAsync
|
||
|> Async.AwaitTask
|
||
|
||
let getLastPlayedSlotFromPlayer (did : uint64) = async {
|
||
let! events =
|
||
GuildEnvironment.connectionString
|
||
|> Sql.connect
|
||
|> Sql.parameters [ "did", Sql.string (string did) ]
|
||
|> Sql.query """
|
||
SELECT player_event.updated_at FROM player_event
|
||
JOIN "user" u on u.id = player_event.user_id
|
||
WHERE u.discord_id = @did AND event_type = 'PlayingSlot'
|
||
"""
|
||
|> Sql.executeAsync (fun read -> read.dateTime "updated_at" )
|
||
|> Async.AwaitTask
|
||
match events with
|
||
| [] -> return None
|
||
| es -> return Some (List.head es)
|
||
}
|
||
|
||
let updateSlotPlayedFromPlayer (did : uint64) =
|
||
GuildEnvironment.connectionString
|
||
|> Sql.connect
|
||
|> Sql.parameters [ "did", Sql.string (string did) ]
|
||
|> Sql.query """
|
||
WITH usr AS (SELECT id FROM "user" WHERE discord_id = @did)
|
||
UPDATE player_event SET updated_at = now() at time zone 'utc'
|
||
FROM usr WHERE usr.id = user_id AND player_event.event_type = 'PlayingSlot';
|
||
"""
|
||
|> Sql.executeNonQueryAsync
|
||
|> Async.AwaitTask
|
||
|> Async.Ignore
|
||
|
||
let handlePrizeTable (ctx : IDiscordContext) =
|
||
task {
|
||
do! Messaging.defer ctx
|
||
let embed = DiscordEmbedBuilder()
|
||
match guildEmojis , anyEmoji with
|
||
| Some emojis , Some any ->
|
||
let folder (i,acc) elem =
|
||
let s1,s2,s3,prize = elem
|
||
let prizeTxt = match prize with Money m -> $"**{m}** $GBT" | Jackpot -> $"**JACKPOT**"
|
||
let line =
|
||
let getEmoji = function Symbol s -> Formatter.Emoji(emojis.[s.emojiName]) | Any -> Formatter.Emoji(any)
|
||
$"{getEmoji s1}{getEmoji s2}{getEmoji s3}"
|
||
let text =
|
||
if prizeTxt.Contains("100") then
|
||
acc
|
||
else
|
||
$"{acc}\n{line} | {prizeTxt}"
|
||
(i + 1) , text
|
||
let! jackpot = getJackpotAmount ()
|
||
let _ , rows = Array.fold folder (0, "") prizeTable
|
||
embed.Color <- DiscordColor.Green
|
||
embed.Title <- $"CURRENT JACKPOT: `{jackpot} 💰 $GBT`"
|
||
embed.Description <- embed.Description + $"\n\n**PRIZE TABLE **\n{rows}\n\n**ANY SAME 3** | **100** $GBT"
|
||
do! ctx.FollowUp(DiscordFollowupMessageBuilder().AsEphemeral().AddEmbed(embed))
|
||
do! Analytics.prizeTableViewed (ctx.GetDiscordMember())
|
||
| _ , _ -> return ()
|
||
|
||
} :> Task
|
||
|
||
let spinEmojis (builder : DiscordFollowupMessageBuilder) (results : SlotSymbol array) (itx : DiscordInteraction) =
|
||
async {
|
||
builder.Content <- "**Spinning!**"
|
||
let! followUp = itx.CreateFollowupMessageAsync(builder) |> Async.AwaitTask
|
||
|
||
match guildEmojis with
|
||
| Some emojis ->
|
||
let e1 = Formatter.Emoji(emojis.[results.[0].emojiName])
|
||
let e2 = Formatter.Emoji(emojis.[results.[1].emojiName])
|
||
let e3 = Formatter.Emoji(emojis.[results.[2].emojiName])
|
||
do! Async.Sleep sleepTime
|
||
let content = $"{e1}"
|
||
let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask
|
||
do! Async.Sleep sleepTime
|
||
let content = $"{e1}{e2}"
|
||
let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask
|
||
do! Async.Sleep sleepTime
|
||
let content = $"{e1}{e2}{e3}"
|
||
let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask
|
||
return followUp , content
|
||
| None ->
|
||
let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent("An error occurred, please contact an Admin")) |> Async.AwaitTask
|
||
return followUp , ""
|
||
}
|
||
|
||
let spin multiplier (ctx : IDiscordContext) =
|
||
let playAmount =
|
||
match multiplier with
|
||
| 1 -> PlayPricex1
|
||
| 2 -> PlayPricex2
|
||
| _ -> PlayPricex3
|
||
let execute player = async {
|
||
do! DbService.updatePlayerCurrency -playAmount player |> Async.Ignore
|
||
let random = System.Random(System.Guid.NewGuid().GetHashCode())
|
||
let results = [| reel1.[random.Next(0, reel1.Length)] ; reel2.[random.Next(0, reel2.Length)] ; reel3.[random.Next(0, reel3.Length)] |]
|
||
|
||
// let results = [| BigBrother ; BigBrother ; BigBrother |]
|
||
let getPrize (results : SlotSymbol array) =
|
||
prizeTable
|
||
|> Array.tryPick (fun (s1,s2,s3,prize) ->
|
||
let getIndex = function Symbol s -> s.index | Any -> -1
|
||
let indices = [ s1 ; s2 ; s3 ] |> List.map getIndex
|
||
let compare i1 i2 = i1 = i2 || i1 = -1
|
||
let s1Result = compare indices.[0] results.[0].index
|
||
let s2Result = compare indices.[1] results.[1].index
|
||
let s3Result = compare indices.[2] results.[2].index
|
||
if s1Result && s2Result && s3Result
|
||
then Some prize
|
||
else None)
|
||
|
||
let prize = getPrize results
|
||
|
||
let builder = DiscordFollowupMessageBuilder()
|
||
builder.IsEphemeral <- true
|
||
|
||
let itx = ctx.GetInteraction()
|
||
let! followUpMessage , slotsContent = spinEmojis builder results itx
|
||
|
||
do! Async.Sleep 2000
|
||
let embed = DiscordEmbedBuilder()
|
||
embed.Author <- DiscordEmbedBuilder.EmbedAuthor()
|
||
embed.Author.Name <- player.Name
|
||
embed.Author.IconUrl <- ctx.GetDiscordMember().AvatarUrl
|
||
embed.Title <- "Slots Results"
|
||
let addGBTField (embed : DiscordEmbedBuilder) prize =
|
||
if prize > 0<GBT>
|
||
then embed.AddField("New $GBT Balance", $"`💰` {player.Bank} ⋙ `💰` {player.Bank - playAmount + prize} `(+{prize - playAmount} $GBT)`") |> ignore
|
||
else embed.AddField("New $GBT Balance", $"`💰` {player.Bank} ⋙ `💰` {player.Bank + prize} `({prize} $GBT)`") |> ignore
|
||
let! result , prizeAmount = async {
|
||
match prize with
|
||
| Some (Money amount) ->
|
||
let prizeWithMultiplier = amount * multiplier
|
||
do! DbService.updatePlayerCurrency prizeWithMultiplier player |> Async.Ignore
|
||
embed.Color <- DiscordColor.Green
|
||
embed.Description <- $"You WIN `💰` **{prizeWithMultiplier}** GBT 🎉"
|
||
embed.AddField("Bet", $"{playAmount}", true) |> ignore
|
||
// embed.AddField("Jackpot Rake", $"{multiplier}", true) |> ignore
|
||
embed.AddField("Prize", $"{prizeWithMultiplier}", true) |> ignore
|
||
addGBTField embed prizeWithMultiplier
|
||
// do! incrementJackpot multiplier |> Async.Ignore
|
||
return "WON" , prizeWithMultiplier
|
||
| Some (Jackpot) ->
|
||
let! jackpot = getJackpotAmount ()
|
||
embed.Color <- DiscordColor.Green
|
||
embed.Description <- $"🎉🎉 YOU HIT THE JACKPOT 🎉🎉"
|
||
embed.AddField("Bet", $"{playAmount}", true) |> ignore
|
||
embed.AddField("Prize", $"{jackpot}", true) |> ignore
|
||
addGBTField embed jackpot
|
||
do! DbService.updatePlayerCurrency jackpot player |> Async.Ignore
|
||
do! resetJackpot BaseJackpotAmount |> Async.Ignore
|
||
return "JACKPOT" , jackpot
|
||
| None ->
|
||
do! incrementJackpot 1 |> Async.Ignore
|
||
embed.Description <- $"You LOST `💰` **{playAmount}** $GBT 😭"
|
||
embed.Color <- DiscordColor.Red
|
||
embed.AddField("Bet", $"{playAmount}", true) |> ignore
|
||
embed.AddField("Jackpot Rake", $"{multiplier}", true) |> ignore
|
||
addGBTField embed -playAmount
|
||
return "LOST" , 0<GBT>
|
||
}
|
||
let dwb = DiscordWebhookBuilder()
|
||
let button = DiscordButtonComponent(ButtonStyle.Success, $"spin-{multiplier}x", $"🎰 Spin Again") :> DiscordComponent
|
||
dwb.AddComponents([| button |]).AddEmbed(embed).WithContent(slotsContent) |> ignore
|
||
do! itx.EditFollowupMessageAsync(followUpMessage.Id, dwb) |> Async.AwaitTask |> Async.Ignore
|
||
|
||
let hopMsg = DiscordMessageBuilder()
|
||
hopMsg.Content <-
|
||
let s1 = $"{slotsContent} | {player.Name}"
|
||
match result with
|
||
| "WON" -> s1 + $" **WON** {prizeAmount} $GBT playing slots!"
|
||
| "LOST" -> s1 + $" **LOST** playing slots"
|
||
| "JACKPOT" -> s1 + $" 🎉🎉🎉 **JUST HIT THE JACKPOT** and **WON** {prizeAmount}!!! 🎉🎉🎉"
|
||
| _ -> ""
|
||
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
|
||
do! channel.SendMessageAsync(hopMsg) |> Async.AwaitTask |> Async.Ignore
|
||
|
||
do! Analytics.slotPlayed (ctx.GetDiscordMember()) playAmount result prizeAmount
|
||
}
|
||
PlayerInteractions.executePlayerAction ctx (fun player -> async {
|
||
if player.Bank >= playAmount then
|
||
match! getLastPlayedSlotFromPlayer player.DiscordId with
|
||
| Some timestamp ->
|
||
if DateTime.UtcNow - timestamp > TimeSpan.FromSeconds(8) then
|
||
do! updateSlotPlayedFromPlayer player.DiscordId
|
||
do! execute player
|
||
else
|
||
do! Messaging.sendFollowUpMessage ctx "Wait till you finish the current spin!"
|
||
| None ->
|
||
let event = { Type = PlayingSlot ; Cooldown = 1<mins> ; Timestamp = DateTime.UtcNow }
|
||
do! DbService.addPlayerEvent player.DiscordId event |> Async.Ignore
|
||
do! execute player
|
||
else
|
||
do! Messaging.sendFollowUpMessage ctx "You do not have sufficient funds to play"
|
||
})
|
||
|
||
let handleButton (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||
let ctx = DiscordEventContext event
|
||
match event.Id with
|
||
| "spin-1x" -> spin 1 ctx
|
||
| "spin-2x" -> spin 2 ctx
|
||
| "spin-3x" -> spin 3 ctx
|
||
| "prizes" -> handlePrizeTable ctx
|
||
| _ ->
|
||
printfn "Wrong Spin ID"
|
||
Task.CompletedTask
|
||
|> Async.AwaitTask
|
||
|> Async.Start
|
||
Task.CompletedTask
|
||
|
||
let handleGuildDownloadCompleted (_ : DiscordClient) (event : GuildDownloadCompletedEventArgs) =
|
||
task {
|
||
let ( result , guild ) = event.Guilds.TryGetValue(GuildEnvironment.guildId)
|
||
guildEmojis <-
|
||
guild.Emojis
|
||
|> Seq.map (fun kvp -> kvp.Value) |> Seq.toArray
|
||
|> Seq.filter (fun de -> Array.contains de.Name slotEmojiNames)
|
||
|> Seq.distinctBy (fun de -> de.Name)
|
||
|> Seq.map (fun de -> ( de.Name , de ))
|
||
|> Map.ofSeq
|
||
|> Some
|
||
anyEmoji <- guild.Emojis |> Seq.tryPick (fun kvp -> if kvp.Value.Name = "any" then Some kvp.Value else None)
|
||
return ()
|
||
} :> Task
|
||
|
||
let handleMessageCreated (_ : DiscordClient) (event : MessageCreateEventArgs) =
|
||
task {
|
||
if event.Channel.Id = GuildEnvironment.channelSlots && event.Author.Id <> GuildEnvironment.botClientSlots.Value.CurrentUser.Id then
|
||
do! Async.Sleep 1000
|
||
do! event.Message.DeleteAsync()
|
||
} :> Task
|
||
|
||
let sendEmbed (jackpotNumChannel : DiscordChannel) slotsChannel (message : DiscordMessage option) = async {
|
||
let builder = DiscordMessageBuilder()
|
||
let embed = DiscordEmbedBuilder()
|
||
embed.Title <- "Degenz Slot Machine"
|
||
embed.ImageUrl <- "https://s7.gifyu.com/images/ezgif.com-gif-maker-268ecb6e4d28bd55a0.gif"
|
||
embed.Description <- "Try Your Hand at a Game of SLOTS!\nEvery Spin Adds to The JACKPOT!\nGood luck Degenz ✊"
|
||
let! jackpot = getJackpotAmount ()
|
||
embed.Title <- $"CURRENT JACKPOT: `{jackpot} 💰 $GBT`"
|
||
|
||
// Update Jackpot channel
|
||
// try
|
||
// do! jackpotNumChannel.ModifyAsync(fun channelEditModel -> channelEditModel.Name <- $"Jackpot: {jackpot} 💰 $GBT") |> Async.AwaitTask
|
||
// with ex -> printfn $"Error changing name: {ex.Message}"
|
||
|
||
builder.AddEmbed(embed) |> ignore
|
||
|
||
let button1 = DiscordButtonComponent(ButtonStyle.Success, $"spin-1x", $"🎰 Bet {PlayPricex1} $GBT") :> DiscordComponent
|
||
let button2 = DiscordButtonComponent(ButtonStyle.Success, $"spin-2x", $"🎰 Bet {PlayPricex2} $GBT") :> DiscordComponent
|
||
let button3 = DiscordButtonComponent(ButtonStyle.Success, $"spin-3x", $"🎰 Bet {PlayPricex3} $GBT") :> DiscordComponent
|
||
let button4 = DiscordButtonComponent(ButtonStyle.Primary, $"prizes", $"Prize Table") :> DiscordComponent
|
||
builder.AddComponents([| button1 ; button2 ; button3 ; button4 |]) |> ignore
|
||
match GuildEnvironment.botClientSlots, message with
|
||
| _ , Some m ->
|
||
let! _ = m.ModifyAsync(builder) |> Async.AwaitTask
|
||
return Some m
|
||
| Some bot , None ->
|
||
let! m = bot.SendMessageAsync(slotsChannel, builder) |> Async.AwaitTask
|
||
do! m.PinAsync() |> Async.AwaitTask
|
||
return Some m
|
||
| _ -> return None
|
||
}
|
||
|
||
let sendEmbedWithLoop (jackpotNumChannel : DiscordChannel) (slotsChannel : DiscordChannel) =
|
||
async {
|
||
let! pins = slotsChannel.GetPinnedMessagesAsync() |> Async.AwaitTask
|
||
let! message =
|
||
match pins |> Seq.toList with
|
||
| [] -> sendEmbed jackpotNumChannel slotsChannel None
|
||
| msg::_ -> async.Return (Some msg)
|
||
while true do
|
||
do! Async.Sleep 305000
|
||
do! sendEmbed jackpotNumChannel slotsChannel message |> Async.Ignore
|
||
} |> Async.Start
|
||
|
||
let sendInitialEmbedFromLaunch (client : DiscordClient) =
|
||
// let jackpotNumChannel = client.Guilds.[GuildEnvironment.guildId].GetChannel(GuildEnvironment.channelJackpotNum)
|
||
let slotsChannel = client.Guilds.[GuildEnvironment.guildId].GetChannel(GuildEnvironment.channelSlots)
|
||
sendEmbedWithLoop slotsChannel slotsChannel
|
||
|
||
let sendInitialEmbedFromSlashCommand (ctx : IDiscordContext) =
|
||
// let jackpotNumChannel = ctx.GetGuild().GetChannel(GuildEnvironment.channelJackpotNum)
|
||
let slotsChannel = ctx.GetGuild().GetChannel(GuildEnvironment.channelSlots)
|
||
sendEmbedWithLoop slotsChannel slotsChannel
|