diff --git a/Bot/DbService.fs b/Bot/DbService.fs index e8ac9bc..93f85cd 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -105,7 +105,7 @@ let getStoreItems (storeId : string) = |> Sql.connect |> Sql.parameters [ "sid", Sql.string storeId ] |> Sql.query """ - SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, + SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end, 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 item i on store_item.item_id = i.id @@ -116,6 +116,7 @@ let getStoreItems (storeId : string) = Stock = reader.int "stock" LimitStock = reader.bool "limit_stock" Available = reader.bool "available" + SaleEnd = reader.int64OrNone "sale_end" TotalSold = None RequiresInvites = reader.intOrNone "require_invites" RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 @@ -127,7 +128,7 @@ let getAllActiveStoreItems () = connStr |> Sql.connect |> Sql.query """ - SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, + SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end, 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 item i on store_item.item_id = i.id @@ -138,6 +139,7 @@ let getAllActiveStoreItems () = Stock = reader.int "stock" LimitStock = reader.bool "limit_stock" Available = reader.bool "available" + SaleEnd = reader.int64OrNone "sale_end" TotalSold = None RequiresInvites = reader.intOrNone "require_invites" RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 @@ -151,7 +153,7 @@ let getRafflesWithPurchases storeId = |> Sql.parameters [ "sid" , Sql.string storeId ] |> Sql.query """ WITH raffles AS - (SELECT store_id,stock,available,limit_stock,i.id AS raffle_id,name,description,icon_url,image_url,category,require_role,require_invites, + (SELECT store_id,stock,available,limit_stock,i.id AS raffle_id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end, 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 item i on store_item.item_id = i.id @@ -166,6 +168,7 @@ FULL JOIN (SELECT item_id, count(*) AS total FROM inventory_item Stock = reader.int "stock" LimitStock = reader.bool "limit_stock" Available = reader.bool "available" + SaleEnd = reader.int64OrNone "sale_end" TotalSold = reader.intOrNone "total" RequiresInvites = reader.intOrNone "require_invites" RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 @@ -178,7 +181,7 @@ let getStoreItemBySymbol (itemSymbol : string) = |> Sql.connect |> Sql.parameters [ "iid", Sql.string itemSymbol ] |> Sql.query """ - SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, + SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end, 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 item i on store_item.item_id = i.id @@ -189,6 +192,7 @@ let getStoreItemBySymbol (itemSymbol : string) = Stock = reader.int "stock" LimitStock = reader.bool "limit_stock" Available = reader.bool "available" + SaleEnd = reader.int64OrNone "sale_end" TotalSold = None RequiresInvites = reader.intOrNone "require_invites" RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 diff --git a/Bot/GameTypes.fs b/Bot/GameTypes.fs index 30afbce..0299f56 100644 --- a/Bot/GameTypes.fs +++ b/Bot/GameTypes.fs @@ -142,6 +142,7 @@ type StoreItem = { LimitStock : bool Available : bool TotalSold : int option + SaleEnd : int64 option RequiresRole : uint64 option RequiresInvites : int option Item : Item diff --git a/Bot/Games/Store.fs b/Bot/Games/Store.fs index e5a5f95..c49720f 100644 --- a/Bot/Games/Store.fs +++ b/Bot/Games/Store.fs @@ -53,13 +53,20 @@ let checkDoesntExceedStackCap (item : Item) player = | _ , Some _ -> "You already own this item" |> embedWithError | _ -> Ok () +let checkItemSaleStillActive (item : StoreItem) = + match item.SaleEnd with + | Some time -> + let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime() + if DateTime.UtcNow < date then Ok () else $"Sale for {item.Item.Name} has already ended!" |> embedWithError + | None -> Ok () + let checkSoldItemAlready (item : Item) player = if player.Inventory |> List.exists (fun i -> item.Id = i.Id) then Ok () else $"{item.Name} not found in your inventory! Looks like you sold it already." |> embedWithError -let checkHasItemsInArsenal itemType items player = +let checkHasItemsInArsenal itemType items = if List.isEmpty items |> not then Ok () else $"You currently have no {itemType} in your arsenal to sell!" @@ -125,6 +132,13 @@ let getItemEmbeds owned (items : StoreItem list) = | _ -> ()) // if item.Item.Type = ItemType.Whitelist then // embed.AddField("Mint Allowance", (if item.Item.Id = "WHITEOG" then 2 else 1) |> string, true) |> ignore + item.SaleEnd |> Option.iter (fun time -> + let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime() + if DateTime.UtcNow < date then + embed.AddField("⏰ Closes", $"", true) |> ignore + else + embed.AddField("🚫 Closed", $"", true) |> ignore) + item.TotalSold |> Option.iter (fun total -> embed.AddField("Total Sold", string total, true) |> ignore) embed.Color <- WeaponClass.getClassEmbedColor item.Item embed.Title <- titleText @@ -142,12 +156,19 @@ let getBuyItemsEmbed storeId player (storeInventory : StoreItem list) = storeInventory |> List.map (fun item -> let owned = player.Inventory |> List.exists (fun i -> i.Id = item.Item.Id) + let saleStillOngoing = + match item.SaleEnd with + | Some time -> + let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime() + DateTime.UtcNow < date + | None -> true let inStock = item.Available && (item.Stock > 0 || item.LimitStock = false) - match owned , inStock with - | _ , false -> + match owned , inStock , saleStillOngoing with + | _ , false , _ -> let msg = if item.Available then "Out of Stock" else "Unavailable" DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"{item.Item.Name} ({msg})", true) - | false , true -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}") + | false , true , true -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}") + | _ , _ , false -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Closed {item.Item.Name}", true) | _ -> match checkDoesntExceedStackCap item.Item player with | Ok _ -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}") @@ -261,7 +282,7 @@ let buyForPlayer storeId player (filterBy : ItemType option) (ctx : IDiscordCont let sell itemType getItems (ctx : IDiscordContext) = executePlayerAction ctx (fun player -> async { let items = getItems player.Inventory - match checkHasItemsInArsenal itemType items player with + match checkHasItemsInArsenal itemType items with | Ok _ -> let itemStore = getSellEmbed items do! ctx.FollowUp(itemStore) |> Async.AwaitTask | Error e -> do! ctx.FollowUp e |> Async.AwaitTask @@ -335,6 +356,7 @@ let handleBuyItem (dispatch : IDiscordContext -> Task) (ctx : IDiscordContext) i let storeItem = storeInventory |> List.find (fun si -> si.Item.Id = itemId) do! checkHasSufficientFunds storeItem.Item player do! checkHasStock storeItem + do! checkItemSaleStillActive storeItem do! checkDoesntExceedStackCap storeItem.Item player do! checkHasRequiredRole storeItem (ctx.GetDiscordMember()) do! checkHasRequiredInvites storeItem player diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index c5a31b0..700f71c 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -507,7 +507,6 @@ let submitAddress (address : string) (ctx : IDiscordContext) = do! user.GrantRoleAsync(role) |> Async.AwaitTask let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhiteOGPending) do! user.RevokeRoleAsync(role) |> Async.AwaitTask - do! Messaging.sendFollowUpMessage ctx $""" 🚀 __Mint Date:__ June 20th