Set things up for the NFT store

This commit is contained in:
Joseph Ferano 2022-04-29 11:06:24 +07:00
parent 6dda9dd8a3
commit f21d4df854
13 changed files with 169 additions and 389 deletions

View File

@ -2,6 +2,7 @@ module Degenz.Admin
open System
open System.IO
open System.Reflection
open System.Threading.Tasks
open DSharpPlus
open DSharpPlus.Entities
@ -14,6 +15,7 @@ type InitEmbeds =
| Dojo = 0
| Whitelist = 1
| Slots = 2
| JpegStore = 3
let handleGuildDownloadReady (_ : DiscordClient) (event : GuildDownloadCompletedEventArgs) =
task {
@ -24,6 +26,7 @@ let handleGuildDownloadReady (_ : DiscordClient) (event : GuildDownloadCompleted
let permission = DiscordApplicationCommandPermission(adminRole, true)
let commands = commands |> Seq.map (fun com -> DiscordGuildApplicationCommandPermissions(com.Id, [ permission ]))
do! guild.BatchEditApplicationCommandPermissionsAsync(commands) |> Async.AwaitTask |> Async.Ignore
return ()
} :> Task
let sendEmbed embed (ctx : IDiscordContext) =
@ -32,6 +35,7 @@ let sendEmbed embed (ctx : IDiscordContext) =
| InitEmbeds.Dojo -> Trainer.sendInitialEmbed ctx
| InitEmbeds.Whitelist -> InviteTracker.sendInitialEmbed ctx
| InitEmbeds.Slots -> SlotMachine.sendInitialEmbedFromSlashCommand ctx
| InitEmbeds.JpegStore -> Store.sendInitialEmbed ctx
| _ -> ()
do! Messaging.sendSimpleResponse ctx "Sent!"
} :> Task
@ -137,24 +141,29 @@ type AdminBot() =
else
Messaging.sendSimpleResponse ctx $"You are not admin" |> Async.StartAsTask :> Task
[<SlashCommandPermissions(Permissions.Administrator)>]
[<SlashCommand("admin-invites", "Get total invites from a specific user", false)>]
member this.GetAttributions (ctx : InteractionContext, [<Option("player", "The player you want to check")>] user : DiscordUser) =
enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getInvitedUsersForId user)
[<SlashCommandPermissions(Permissions.Administrator)>]
[<SlashCommand("admin-whitelist-stock", "Set whitelist stock", false)>]
member this.SetStock (ctx : InteractionContext, [<Option("amount", "Set the amount of WL available for purchase")>] amount : int64) =
enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.setCurrentWhitelistStock (int amount))
[<SlashCommandPermissions(Permissions.Administrator)>]
[<SlashCommand("admin-send-embed", "Set whitelist stock", false)>]
member this.SendEmbedToChannel (ctx : InteractionContext, [<Option("embed", "Which embed to send")>] embed : InitEmbeds) =
enforceAdmin (DiscordInteractionContext ctx) (sendEmbed embed)
[<SlashCommandPermissions(Permissions.Administrator)>]
[<SlashCommand("admin-get-msg-reactions", "Set whitelist stock", false)>]
member this.GetMessageReactions (ctx : InteractionContext,
[<Option("channel", "The channel where the message is")>] channel : DiscordChannel,
[<Option("message-id", "The ID of the message with all the reactions")>] messageId : string) =
enforceAdmin (DiscordInteractionContext ctx) (getUsersFromMessageReactions channel messageId)
[<SlashCommandPermissions(Permissions.Administrator)>]
[<SlashCommand("admin-get-invites-table", "Invites Table", false)>]
member this.GetInvitesFromReactedMessages (ctx : InteractionContext,
[<Option("channel", "The channel where the message is")>] channel : DiscordChannel,

View File

@ -94,19 +94,19 @@ let arsenalCommand (discordMember : DiscordMember) =
]
track "Arsenal Command Invoked" discordMember.Id data
let buyWeaponCommand (discordMember : DiscordMember) weaponType =
let buyItemCommand (discordMember : DiscordMember) store =
let data = [
"user_display_name" , discordMember.Username
"weapon_type" , string weaponType
"store_symbol" , store
]
track "Buy Weapon Command Invoked" discordMember.Id data
track "Buy Item Command Invoked" discordMember.Id data
let sellWeaponCommand (discordMember : DiscordMember) weaponType =
let sellItemCommand (discordMember : DiscordMember) store =
let data = [
"user_display_name" , discordMember.Username
"weapon_type" , string weaponType
"store_symbol" , store
]
track "Sell Weapon Command Invoked" discordMember.Id data
track "Sell Item Command Invoked" discordMember.Id data
let buyWeaponButton (discordMember : DiscordMember) itemName itemPrice =
let data = [

View File

@ -77,7 +77,6 @@ inviterBot.add_ComponentInteractionCreated(AsyncEventHandler(InviteTracker.handl
slotsBot.add_ComponentInteractionCreated(AsyncEventHandler(SlotMachine.handleButton))
slotsBot.add_GuildDownloadCompleted(AsyncEventHandler(SlotMachine.handleGuildDownloadCompleted))
slotsBot.add_MessageCreated(AsyncEventHandler(SlotMachine.handleMessageCreated))
adminBot.add_GuildDownloadCompleted(AsyncEventHandler(Admin.handleGuildDownloadReady))
let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEventArgs) =
async {
@ -95,15 +94,15 @@ let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEven
:> Task
//hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf))
storeBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botClientStore <- Some storeBot
slotsBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botClientSlots <- Some slotsBot
hackerBattleBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botClientHacker <- Some hackerBattleBot
storeBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
//GuildEnvironment.botClient <- Some storeBot.CurrentUser
inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously
GuildEnvironment.botClientRecruit <- Some inviterBot

View File

@ -7,9 +7,6 @@
<RootNamespace>Degenz</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Content Include="Items.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="paket.references" />
<Compile Include="Prelude.fs" />
<Compile Include="GuildEnvironment.fs" />

View File

@ -23,12 +23,15 @@ let readItem (reader : RowReader) =
{ TargetStat = stat ; Effect = fx }
{ Item.Id = reader.int "id"
Item.Name = reader.string "name"
Item.IconUrl = reader.string "icon"
Item.Symbol = reader.string "symbol"
Item.Type =
match reader.string "category" with
| "Hack" -> ItemType.Hack
| "Shield" -> ItemType.Shield
| "Food" -> ItemType.Food
| "Accessory" -> ItemType.Accessory
| "Jpeg" -> ItemType.Jpeg
| _ -> ItemType.Misc
Item.Attributes = [
reader.intOrNone "buy_price" |> Option.map (fun a -> Buyable (a * 1<GBT>))
@ -53,7 +56,7 @@ let getPlayerInventory (did : uint64) =
|> Sql.connect
|> Sql.parameters [ "did", Sql.string (string did) ]
|> Sql.query """
SELECT ii.id,name,category,buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,
SELECT ii.id,ii.symbol,name,icon,category,buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,
attack_power,defense_power,class_name,max_stack,mods
FROM inventory_item
JOIN item ii on inventory_item.item_id = ii.id
@ -74,12 +77,22 @@ let addToPlayerInventory (did : uint64) (item : Item) =
|> Sql.executeNonQueryAsync
|> Async.AwaitTask
let getStoreSymbol (channelId : uint64) =
connStr
|> Sql.connect
|> Sql.parameters [ "cid", Sql.string (string channelId) ]
|> Sql.query """
SELECT symbol FROM store WHERE channel_id = @cid
"""
|> Sql.executeRowAsync (fun read -> read.string "symbol")
|> Async.AwaitTask
let getStoreItems (channelId : uint64) =
connStr
|> Sql.connect
|> Sql.parameters [ "cid", Sql.string (string channelId) ]
|> Sql.query """
SELECT i.id,name,category,buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,
SELECT i.id,i.symbol,name,icon,category,buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,
attack_power,defense_power,class_name,max_stack,mods
FROM store_item
JOIN store st on store_item.store_id = st.id
@ -89,6 +102,30 @@ let getStoreItems (channelId : uint64) =
|> Sql.executeAsync readItem
|> Async.AwaitTask
let getWeapons () =
connStr
|> Sql.connect
|> Sql.query """
SELECT i.id,i.symbol,name,icon,category,buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,
attack_power,defense_power,class_name,max_stack,mods
FROM item WHERE category = 'Hack' OR symbol = 'Shield'
"""
|> Sql.executeAsync readItem
|> Async.AwaitTask
let consumeItem (did : uint64) (item : Item) =
connStr
|> Sql.connect
|> Sql.parameters [ ( "@did" , Sql.string (string did) ) ; ( "iid" , Sql.int item.Id )]
|> Sql.query """
DELETE FROM inventory_item
WHERE id IN (SELECT id FROM inventory_item
WHERE user_id = (SELECT id FROM "user" WHERE discord_id = @did)
AND item_id = @iid LIMIT 1)
"""
|> Sql.executeNonQueryAsync
|> Async.AwaitTask
let getPlayerEvents (did : uint64) =
connStr
|> Sql.connect

View File

@ -6,12 +6,6 @@ open DSharpPlus.Entities
open Degenz
open Newtonsoft.Json
module Armory =
let weapons : Inventory =
let file = System.IO.File.ReadAllText("Items.json")
// let file = System.IO.File.ReadAllText("Bot/Items.json")
JsonConvert.DeserializeObject<Inventory>(file)
module Inventory =
let getItemsByType itemType inventory =
match itemType with
@ -19,6 +13,7 @@ module Inventory =
| ItemType.Shield -> inventory |> List.filter (fun item -> match item.Type with ItemType.Shield _ -> true | _ -> false)
| ItemType.Food -> inventory |> List.filter (fun item -> match item.Type with ItemType.Food _ -> true | _ -> false)
| ItemType.Accessory -> inventory |> List.filter (fun item -> match item.Type with ItemType.Accessory _ -> true | _ -> false)
| ItemType.Jpeg -> inventory |> List.filter (fun item -> match item.Type with ItemType.Jpeg _ -> true | _ -> false)
| ItemType.Misc -> inventory |> List.filter (fun item -> match item.Type with ItemType.Misc _ -> true | _ -> false)
let findItemById id (inventory : Inventory) = inventory |> List.find (fun item -> item.Id = id)
@ -143,7 +138,7 @@ module Arsenal =
| [] -> "None"
| _ -> items |> List.map (fun item -> item.Name) |> String.concat ", "
let actionFormat (actions : PlayerEvent List) =
let actionFormat items (actions : PlayerEvent List) =
match actions with
| [] -> "None"
| acts ->
@ -151,11 +146,11 @@ module Arsenal =
|> List.map (fun event ->
match event.Type with
| Hacking h ->
let item = Armory.weapons |> Inventory.findItemById h.HackId
let item = items |> Inventory.findItemById h.HackId
let cooldown = Messaging.getTimeText false WeaponClass.SameTargetAttackCooldown event.Timestamp
$"Hacked {h.Adversary.Name} with {item.Name} {cooldown} ago"
| Shielding id ->
let item = Armory.weapons |> Inventory.findItemById id
let item = items |> Inventory.findItemById id
let cooldown = Messaging.getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
$"{item.Name} Shield active for {cooldown}"
| _ -> "")
@ -166,5 +161,5 @@ module Arsenal =
let hacks = Player.getHackEvents p
$"**Hacks:** {Inventory.getItemsByType ItemType.Hack p.Inventory |> battleItemFormat}\n
**Shields:** {Inventory.getItemsByType ItemType.Shield p.Inventory |> battleItemFormat}\n
**Hack Attacks:**\n{hacks |> List.take (min hacks.Length 10) |> actionFormat}\n
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat}"
**Hack Attacks:**\n{hacks |> List.take (min hacks.Length 10) |> actionFormat p.Inventory}\n
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat p.Inventory}"

View File

@ -88,6 +88,7 @@ type ItemType =
| Shield
| Food
| Accessory
| Jpeg
| Misc
type Effect =
@ -132,6 +133,8 @@ type Item = {
Id : int
Name : string
Type : ItemType
Symbol : string
IconUrl : string
Attributes : ItemAttribute list
}

View File

@ -83,7 +83,7 @@ let runHackerBattle defender (hack : HackItem) =
|> List.exists (fun event ->
match event.Type with
| Shielding id ->
let item = Inventory.findItemById id Armory.weapons
let item = Inventory.findItemById id Trainer.weapons
match item.Attributes with
| CanClass c -> hack.Class = c
| _ -> false
@ -165,7 +165,8 @@ let handleAttack (ctx : IDiscordContext) =
executePlayerAction ctx (fun attacker -> async {
let tokens = ctx.GetInteractionId().Split("-")
let hackId = int tokens.[1]
let item = Armory.weapons |> Inventory.findItemById hackId
// TODO: This sucks
let item = Trainer.weapons |> Inventory.findItemById hackId
let hackItem = (Inventory.getHackItem item).Value
let resultId , targetId = UInt64.TryParse tokens.[2]
let! resultTarget = DbService.tryFindPlayer targetId
@ -206,7 +207,7 @@ let handleDefense (ctx : IDiscordContext) =
executePlayerAction ctx (fun player -> async {
let tokens = ctx.GetInteractionId().Split("-")
let shieldId = int tokens.[1]
let item = Armory.weapons |> Inventory.findItemById shieldId
let item = Trainer.weapons |> Inventory.findItemById shieldId
let shieldItem = (Inventory.getShieldItem item).Value
do! player

View File

@ -52,7 +52,7 @@ let getItemEmbeds owned (items : Inventory) =
|> ignore
match Embeds.getItemIcon item.Id with
| Some url -> embed.WithThumbnail(url)
| None -> embed)
| None -> if String.IsNullOrWhiteSpace(item.IconUrl) then embed else embed.WithThumbnail(item.IconUrl))
|> List.map (fun e -> e.Build())
|> Seq.ofList
@ -66,10 +66,15 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
else DiscordButtonComponent(WeaponClass.getClassButtonColor item, $"Buy-{item.Id}", $"Buy {item.Name}")
:> DiscordComponent)
DiscordFollowupMessageBuilder()
.AddEmbeds(embeds)
.AddComponents(buttons)
.AsEphemeral(true)
let builder =
DiscordFollowupMessageBuilder()
.AddEmbeds(embeds)
.AsEphemeral(true)
buttons
|> List.chunkBySize 5
|> List.iter (fun btns -> builder.AddComponents(btns) |> ignore)
builder
let getSellEmbed (items : Inventory) =
let embeds , buttons =
@ -126,15 +131,16 @@ let checkHasItemsInArsenal itemType items player =
then Ok player
else Error $"You currently have no {itemType} in your arsenal to sell!"
let buy itemType (ctx : IDiscordContext) =
let buy (ctx : IDiscordContext) =
executePlayerAction ctx (fun player -> async {
let playerItems = Inventory.getItemsByType itemType player.Inventory
try
let! armoryItems = DbService.getStoreItems (ctx.GetChannel().Id)
if armoryItems.Length > 0 then
let itemStore = getBuyItemsEmbed playerItems armoryItems
let channelId = ctx.GetChannel().Id
let! items = DbService.getStoreItems channelId
if items.Length > 0 then
let itemStore = getBuyItemsEmbed player.Inventory items
do! ctx.FollowUp itemStore |> Async.AwaitTask
do! Analytics.buyWeaponCommand (ctx.GetDiscordMember()) itemType
let! storeSymbol = DbService.getStoreSymbol channelId
do! Analytics.buyItemCommand (ctx.GetDiscordMember()) storeSymbol
else
do! Messaging.sendFollowUpMessage ctx "This channel doesn't have anything to sell"
with ex -> printfn $"{ex.Message}"
@ -147,9 +153,22 @@ let sell itemType getItems (ctx : IDiscordContext) =
| Ok _ -> let itemStore = getSellEmbed items
do! ctx.FollowUp(itemStore) |> Async.AwaitTask
| Error e -> do! sendFollowUpMessage ctx e
do! Analytics.sellWeaponCommand (ctx.GetDiscordMember()) itemType
do! Analytics.buyItemCommand (ctx.GetDiscordMember()) itemType
})
let purchaseItemEmbed (item : Item) =
let embed = DiscordEmbedBuilder()
embed.ImageUrl <- item.IconUrl
embed.Title <- $"Purchased {item.Name}"
match item.Type with
| ItemType.Jpeg ->
if item.Symbol = "RAFFLE" then
embed.Description <- $"Congratulations! You are in the draw for the {item.Name}. The winner will be announced shortly"
else
embed.Description <- $"Congratulations! You own the rights to the {item.Name} NFT. Please create a ticket in the support channel and we will transfer to your wallet"
| _ -> embed.Description <- $"Purchased {item.Name}"
embed
// TODO: When you buy a shield, prompt the user to activate it
let handleBuyItem (ctx : IDiscordContext) itemId =
executePlayerAction ctx (fun player -> async {
@ -162,14 +181,17 @@ let handleBuyItem (ctx : IDiscordContext) itemId =
let price = match item.Attributes with CanBuy price -> price | _ -> 0<GBT>
do! DbService.updatePlayerCurrency -price player |> Async.Ignore
do! DbService.addToPlayerInventory player.DiscordId item |> Async.Ignore
do! sendFollowUpMessage ctx $"Successfully purchased {item.Name}! You now have {player.Bank - price} 💰$GBT remaining"
// do! ctx.FollowUp $"Successfully purchased {item.Name}! You now have {player.Bank - price} 💰$GBT remaining"
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
builder.AddEmbed(purchaseItemEmbed (item)) |> ignore
do! ctx.FollowUp builder |> Async.AwaitTask
do! Analytics.buyWeaponButton (ctx.GetDiscordMember()) item.Name price
})
})
let handleSell (ctx : IDiscordContext) itemId =
executePlayerAction ctx (fun player -> async {
let item = Armory.weapons |> Inventory.findItemById itemId
let item = player.Inventory |> Inventory.findItemById itemId
do!
player
|> checkSoldItemAlready item
@ -201,8 +223,19 @@ let consume (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx
do! ctx.FollowUp builder |> Async.AwaitTask
})
let showInventoryEmbed (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async {
let embeds = getItemEmbeds true player.Inventory
let handleConsume (ctx : IDiscordContext) itemId = PlayerInteractions.executePlayerAction ctx (fun player -> async {
let item = player.Inventory |> Inventory.findItemById itemId
match player.Inventory |> Inventory.getFoods with
| [] -> do! Messaging.sendFollowUpMessage ctx "You do not have any items to consume"
| items ->
let embeds = getItemEmbeds true items
let builder = DiscordFollowupMessageBuilder().AddEmbeds(embeds).AsEphemeral(true)
do! ctx.FollowUp builder |> Async.AwaitTask
})
let showJpegsEmbed (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async {
let jpegs = player.Inventory |> Inventory.getItemsByType ItemType.Jpeg
let embeds = getItemEmbeds true jpegs
let builder = DiscordFollowupMessageBuilder().AddEmbeds(embeds).AsEphemeral(true)
do! ctx.FollowUp builder |> Async.AwaitTask
})
@ -236,6 +269,8 @@ let handleStoreEvents (_ : DiscordClient) (event : ComponentInteractionCreateEve
match id with
| id when id.StartsWith("Buy") -> handleBuyItem ctx itemId
| id when id.StartsWith("Sell") -> handleSell ctx itemId
| id when id.StartsWith("Consume") -> handleConsume ctx itemId
| id when id.StartsWith("ShowJpegInventory") -> buy ctx
| _ ->
task {
let builder = DiscordInteractionResponseBuilder()
@ -244,6 +279,27 @@ let handleStoreEvents (_ : DiscordClient) (event : ComponentInteractionCreateEve
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
}
let sendInitialEmbed (ctx : IDiscordContext) =
async {
try
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelBackAlley)
let builder = DiscordMessageBuilder()
let embed = DiscordEmbedBuilder()
embed.ImageUrl <- "https://s7.gifyu.com/images/ezgif.com-gif-maker-23203b9dca779ba7cf.gif"
embed.Title <- "Degenz Game"
embed.Color <- DiscordColor.Black
embed.Description <- "Hey, what do you want kid? Did you come alone?"
builder.AddEmbed embed |> ignore
let button = DiscordButtonComponent(ButtonStyle.Success, $"ShowJpegInventory-0", $"Show me your stash") :> DiscordComponent
builder.AddComponents [| button |] |> ignore
do! GuildEnvironment.botClientStore.Value.SendMessageAsync(channel, builder)
|> Async.AwaitTask
|> Async.Ignore
with e ->
printfn $"Error trying to get channel Jpeg Alley\n\n{e.Message}"
} |> Async.RunSynchronously
type Store() =
inherit ApplicationCommandModule ()
@ -257,28 +313,28 @@ type Store() =
}
// let checkChannel (ctx : IDiscordContext) (storeFn : IDiscordContext -> Task) =
let checkChannel (ctx : IDiscordContext) =
match ctx.GetChannel().Id with
| id when id = GuildEnvironment.channelBackAlley -> buy ItemType.Hack ctx
| id when id = GuildEnvironment.channelArmory -> buy ItemType.Shield ctx
| id when id = GuildEnvironment.channelMarket -> buy ItemType.Food ctx
| id when id = GuildEnvironment.channelAccessoryShop -> buy ItemType.Accessory ctx
| _ ->
task {
let msg = $"This channel doesn't have any items to sell. Try <#{GuildEnvironment.channelArmory}>"
do! Messaging.sendSimpleResponse ctx msg
}
// let checkChannel (ctx : IDiscordContext) =
// match ctx.GetChannel().Id with
// | id when id = GuildEnvironment.channelBackAlley -> buy ItemType.Hack ctx
// | id when id = GuildEnvironment.channelArmory -> buy ItemType.Shield ctx
// | id when id = GuildEnvironment.channelMarket -> buy ItemType.Food ctx
// | id when id = GuildEnvironment.channelAccessoryShop -> buy ItemType.Accessory ctx
// | _ ->
// task {
// let msg = $"This channel doesn't have any items to sell. Try <#{GuildEnvironment.channelArmory}>"
// do! Messaging.sendSimpleResponse ctx msg
// }
[<SlashCommand("buy-item", "Purchase an item")>]
member _.BuyItem (ctx : InteractionContext) = checkChannel (DiscordInteractionContext ctx)
member _.BuyItem (ctx : InteractionContext) = buy (DiscordInteractionContext ctx)
[<SlashCommand("buy-hack", "Purchase a hack so you can take money from other Degenz")>]
member _.BuyHack (ctx : InteractionContext) =
enforceChannel (DiscordInteractionContext(ctx)) (buy ItemType.Hack)
enforceChannel (DiscordInteractionContext(ctx)) buy
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GBT")>]
member this.BuyShield (ctx : InteractionContext) =
enforceChannel (DiscordInteractionContext(ctx)) (buy ItemType.Shield)
enforceChannel (DiscordInteractionContext(ctx)) buy
[<SlashCommand("sell-hack", "Sell a hack for GoodBoyTokenz")>]
member this.SellHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Hacks" (Inventory.getItemsByType ItemType.Hack))
@ -289,9 +345,9 @@ type Store() =
[<SlashCommand("consume", "Consume a food item")>]
member this.Consume (ctx : InteractionContext) = consume (DiscordInteractionContext ctx)
[<SlashCommand("inventory", "Check your inventory")>]
[<SlashCommand("jpegs", "Check your inventory")>]
member this.Inventory (ctx : InteractionContext) =
showInventoryEmbed (DiscordInteractionContext ctx)
showJpegsEmbed (DiscordInteractionContext ctx)
[<SlashCommand("stats", "Check your stats")>]
member this.Stats (ctx : InteractionContext) =

View File

@ -9,8 +9,9 @@ open Degenz.Messaging
let TrainerAchievement = "FINISHED_TRAINER"
let Sensei = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
let hackItem = Armory.weapons |> Inventory.findItemById (int ItemId.Virus)
let shieldItem = Armory.weapons |> Inventory.findItemById (int ItemId.Firewall)
let weapons = DbService.getWeapons () |> Async.RunSynchronously
let hackItem = weapons |> Inventory.findItemById (int ItemId.Virus)
let shieldItem = weapons |> Inventory.findItemById (int ItemId.Firewall)
let defaultHack = (Inventory.getHackItem hackItem).Value
let defaultShield = (Inventory.getShieldItem shieldItem ).Value
let CurrencyGift = 250<GBT>

View File

@ -1,318 +0,0 @@
[
{
"Case": "Hack",
"Fields": [
{
"Power": 20,
"Class": 0,
"Cooldown": 2,
"Item": {
"Id": 0,
"Name": "Virus",
"Price": 250,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Hack",
"Fields": [
{
"Power": 20,
"Class": 1,
"Cooldown": 2,
"Item": {
"Id": 1,
"Name": "Remote Access",
"Price": 250,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Hack",
"Fields": [
{
"Power": 20,
"Class": 2,
"Cooldown": 2,
"Item": {
"Id": 2,
"Name": "Worm",
"Price": 250,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Shield",
"Fields": [
{
"Class": 0,
"Cooldown": 300,
"Item": {
"Id": 6,
"Name": "Firewall",
"Price": 100,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Shield",
"Fields": [
{
"Class": 1,
"Cooldown": 300,
"Item": {
"Id": 7,
"Name": "Encryption",
"Price": 100,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Shield",
"Fields": [
{
"Class": 2,
"Cooldown": 300,
"Item": {
"Id": 8,
"Name": "Cypher",
"Price": 100,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Food",
"Fields": [
{
"TargetStat" : 0,
"BoostAmount" : 30,
"Item": {
"Id": 12,
"Name": "Protein Powder",
"Price": 50,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : false,
"CanConsume" : true,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Food",
"Fields": [
{
"TargetStat" : 1,
"BoostAmount" : 30,
"Item": {
"Id": 13,
"Name": "Toro Loco",
"Price": 50,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : false,
"CanConsume" : true,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Food",
"Fields": [
{
"TargetStat" : 2,
"BoostAmount" : 30,
"Item": {
"Id": 14,
"Name": "Oldports Cigs",
"Price": 50,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : false,
"CanConsume" : true,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Food",
"Fields": [
{
"TargetStat" : 3,
"BoostAmount" : 30,
"Item": {
"Id": 15,
"Name": "Moon Pie",
"Price": 50,
"MaxAllowed": 1,
"Attributes": {
"CanBuy" : true,
"CanSell" : false,
"CanConsume" : true,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Accessory",
"Fields": [
{
"TargetStat" : 0,
"FloorBoost" : 25,
"CeilBoost" : 0,
"Item": {
"Id": 20,
"Name": "Kettlebell",
"MaxAllowed": 1,
"Price": 250,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Accessory",
"Fields": [
{
"TargetStat" : 1,
"FloorBoost" : 25,
"CeilBoost" : 0,
"Item": {
"Id": 21,
"Name": "Headphones",
"MaxAllowed": 1,
"Price": 250,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Accessory",
"Fields": [
{
"TargetStat" : 2,
"FloorBoost" : 0,
"CeilBoost" : 25,
"Item": {
"Id": 22,
"Name": "Rolox Watch",
"MaxAllowed": 1,
"Price": 250,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
},
{
"Case": "Accessory",
"Fields": [
{
"TargetStat" : 3,
"FloorBoost" : 0,
"CeilBoost" : 25,
"Item": {
"Id": 23,
"Name": "Buddha Keychain",
"MaxAllowed": 1,
"Price": 250,
"Attributes": {
"CanBuy" : true,
"CanSell" : true,
"CanConsume" : false,
"CanTrade" : false,
"CanDrop" : false
}
}
}
]
}
]

View File

@ -5,9 +5,9 @@ framework: net6.0, netstandard2.0, netstandard2.1
nuget FSharp.Core >= 6.0.0
nuget DSharpPlus >= 4.2.0-nightly-01105
nuget DSharpPlus.Interactivity >= 4.2.0-nightly-01105
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01105
nuget DSharpPlus >= 4.2.0-nightly-01125
nuget DSharpPlus.Interactivity >= 4.2.0-nightly-01125
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01125
nuget MongoDB.Driver
nuget dotenv.net 3.1.1

View File

@ -8,7 +8,7 @@ NUGET
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0))
dotenv.net (3.1.1)
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0))
DSharpPlus (4.2.0-nightly-01105)
DSharpPlus (4.3.0-nightly-01125)
Emzi0767.Common (>= 2.6.2)
Microsoft.Extensions.Logging.Abstractions (>= 5.0)
Newtonsoft.Json (>= 13.0.1)
@ -18,11 +18,11 @@ NUGET
System.Net.WebSockets.Client (>= 4.3.2)
System.Runtime.InteropServices.RuntimeInformation (>= 4.3)
System.Threading.Channels (>= 5.0)
DSharpPlus.Interactivity (4.2.0-nightly-01105)
DSharpPlus.Interactivity (4.3.0-nightly-01125)
ConcurrentHashSet (>= 1.1)
DSharpPlus (>= 4.2.0-nightly-01105)
DSharpPlus.SlashCommands (4.2.0-nightly-01105)
DSharpPlus (>= 4.2.0-nightly-01105)
DSharpPlus (>= 4.3.0-nightly-01125)
DSharpPlus.SlashCommands (4.3.0-nightly-01125)
DSharpPlus (>= 4.3.0-nightly-01125)
Microsoft.Extensions.DependencyInjection (>= 5.0.1)
Emzi0767.Common (2.6.2)
System.Collections.Immutable (>= 5.0)