浏览代码

Show pack stickers. Show sticker info

Tigran 3 年之前
父节点
当前提交
f0fe9ab063
共有 51 个文件被更改,包括 220 次插入130 次删除
  1. 1 4
      CardCollector/Commands/CallbackQuery/AuthorsMenu.cs
  2. 1 4
      CardCollector/Commands/CallbackQuery/BuyAuthorPackMenu.cs
  3. 2 2
      CardCollector/Commands/CallbackQuery/BuyCoins.cs
  4. 1 2
      CardCollector/Commands/CallbackQuery/BuyPack.cs
  5. 2 2
      CardCollector/Commands/CallbackQuery/BuyShopItem.cs
  6. 1 2
      CardCollector/Commands/CallbackQuery/CombineMenu.cs
  7. 1 1
      CardCollector/Commands/CallbackQuery/ConfirmBuying.cs
  8. 1 1
      CardCollector/Commands/CallbackQuery/ConfirmExchange.cs
  9. 1 1
      CardCollector/Commands/CallbackQuery/ConfirmationSelling.cs
  10. 2 2
      CardCollector/Commands/CallbackQuery/DeleteCombine.cs
  11. 1 3
      CardCollector/Commands/CallbackQuery/EndUploadStickers.cs
  12. 1 7
      CardCollector/Commands/CallbackQuery/OpenAuthorPackMenu.cs
  13. 1 1
      CardCollector/Commands/CallbackQuery/PackInfo.cs
  14. 1 1
      CardCollector/Commands/CallbackQuery/PutForAuction.cs
  15. 2 2
      CardCollector/Commands/CallbackQuery/SelectEmoji.cs
  16. 1 0
      CardCollector/Commands/CallbackQuery/SelectOffer.cs
  17. 1 1
      CardCollector/Commands/CallbackQuery/SelectPrice.cs
  18. 1 1
      CardCollector/Commands/CallbackQuery/SelectShopPack.cs
  19. 1 1
      CardCollector/Commands/CallbackQuery/SelectSort.cs
  20. 1 1
      CardCollector/Commands/CallbackQuery/SelectTier.cs
  21. 1 1
      CardCollector/Commands/CallbackQuery/ShowInfo.cs
  22. 1 5
      CardCollector/Commands/CallbackQuery/SpecialOffers.cs
  23. 1 1
      CardCollector/Commands/ChosenInlineResult/GetUnlimitedStickerAndExecuteCommand.cs
  24. 1 1
      CardCollector/Commands/ChosenInlineResult/SelectStickerInline.cs
  25. 26 0
      CardCollector/Commands/ChosenInlineResult/StickerInfo.cs
  26. 1 0
      CardCollector/Commands/ChosenInlineResultCommand.cs
  27. 4 8
      CardCollector/Commands/InlineQuery/ShowAuctionStickers.cs
  28. 48 0
      CardCollector/Commands/InlineQuery/ShowStickersInShopPack.cs
  29. 1 0
      CardCollector/Commands/InlineQueryCommand.cs
  30. 0 1
      CardCollector/Commands/Message/DownloadStickerPack.cs
  31. 7 9
      CardCollector/Commands/Message/EnterEmoji.cs
  32. 8 9
      CardCollector/Commands/Message/EnterGemsExchange.cs
  33. 9 11
      CardCollector/Commands/Message/EnterGemsPrice.cs
  34. 6 6
      CardCollector/Commands/Message/UploadFile.cs
  35. 1 1
      CardCollector/Commands/Message/UploadSticker.cs
  36. 2 2
      CardCollector/Controllers/AuctionController.cs
  37. 13 3
      CardCollector/Controllers/MessageController.cs
  38. 11 1
      CardCollector/DataBase/Entity/StickerEntity.cs
  39. 4 7
      CardCollector/DataBase/Entity/UserEntity.cs
  40. 6 6
      CardCollector/DataBase/EntityDao/AuctionDao.cs
  41. 2 4
      CardCollector/DataBase/EntityDao/StickerDao.cs
  42. 1 0
      CardCollector/DataBase/EntityDao/UserPacksDao.cs
  43. 1 2
      CardCollector/Extensions.cs
  44. 9 0
      CardCollector/Resources/Command.Designer.cs
  45. 3 0
      CardCollector/Resources/Command.resx
  46. 1 1
      CardCollector/Resources/Constants.cs
  47. 18 7
      CardCollector/Resources/Keyboard.cs
  48. 4 0
      CardCollector/Session/MenuInformation.cs
  49. 4 2
      CardCollector/Session/Modules/FiltersModule.cs
  50. 0 2
      CardCollector/Session/Modules/UploadedStickersModule.cs
  51. 2 1
      CardCollector/Session/Session.cs

+ 1 - 4
CardCollector/Commands/CallbackQuery/AuthorsMenu.cs

@@ -22,13 +22,10 @@ namespace CardCollector.Commands.CallbackQuery
             var totalCount = list.Count;
             list = list.GetRange((page - 1) * 10, list.Count >= page * 10 ? 10 : list.Count % 10);
             if (list.Count == 0)
-            {
-                User.Session.UndoCurrentCommand();
                 await MessageController.AnswerCallbackQuery(User, CallbackQueryId, Messages.page_not_found);
-            }
             /* Заменяем сообщение меню на сообщение со списком */
             else
-                await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_author,
+                await MessageController.EditMessage(User, Messages.choose_author,
                     Keyboard.GetAuthorsKeyboard(list, Keyboard.GetPagePanel(page, totalCount, CommandText)));
         }
 

+ 1 - 4
CardCollector/Commands/CallbackQuery/BuyAuthorPackMenu.cs

@@ -20,12 +20,9 @@ namespace CardCollector.Commands.CallbackQuery
             var totalCount = packs.Count;
             packs = packs.GetRange((page - 1) * 10, packs.Count >= page * 10 ? 10 : packs.Count % 10);
             if (packs.Count == 0)
-            {
-                User.Session.UndoCurrentCommand();
                 await MessageController.AnswerCallbackQuery(User, CallbackQueryId, Messages.page_not_found);
-            }
             else
-                await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_author,
+                await MessageController.EditMessage(User, Messages.choose_author,
                     Keyboard.GetShopPacksKeyboard(packs, Keyboard.GetPagePanel(page, totalCount, CommandText)));
         }
 

+ 2 - 2
CardCollector/Commands/CallbackQuery/BuyCoins.cs

@@ -16,9 +16,9 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            EnterGemsExchange.AddToQueue(User.Id, CallbackMessageId);
+            EnterGemsExchange.AddToQueue(User.Id);
             var module = User.Session.GetModule<ShopModule>();
-            await MessageController.EditMessage(User, CallbackMessageId,
+            await MessageController.EditMessage(User,
                 $"{Messages.exchange_mesage}" +
                 $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
                 $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +

+ 1 - 2
CardCollector/Commands/CallbackQuery/BuyPack.cs

@@ -14,8 +14,7 @@ namespace CardCollector.Commands.CallbackQuery
         
         public override async Task Execute()
         {
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_option,
-                Keyboard.ShopPacksKeyboard);
+            await MessageController.EditMessage(User, Messages.choose_option, Keyboard.ShopPacksKeyboard);
         }
 
         public BuyPack() { }

+ 2 - 2
CardCollector/Commands/CallbackQuery/BuyShopItem.cs

@@ -12,7 +12,7 @@ namespace CardCollector.Commands.CallbackQuery
     public class BuyShopItem : CallbackQueryCommand
     {
         protected override string CommandText => Command.buy_shop_item;
-        protected override bool ClearMenu => false;
+        protected override bool ClearMenu => true;
         protected override bool AddToStack => false;
 
         public override async Task Execute()
@@ -70,7 +70,7 @@ namespace CardCollector.Commands.CallbackQuery
                     sticker = stickers[rnd.Next(stickers.Count)];
                     break;
                 case "sticker":
-                    sticker = await StickerDao.GetStickerByHash(data[1]);
+                    sticker = await StickerDao.GetByHash(data[1]);
                     break;
             }
             if (sticker != null)

+ 1 - 2
CardCollector/Commands/CallbackQuery/CombineMenu.cs

@@ -17,8 +17,7 @@ namespace CardCollector.Commands.CallbackQuery
         {
             var combineModule = User.Session.GetModule<CombineModule>();
             await User.ClearChat();
-            await MessageController.EditMessage(User, CallbackMessageId, combineModule.ToString(), 
-                Keyboard.GetCombineKeyboard(combineModule));
+            await MessageController.EditMessage(User, combineModule.ToString(), Keyboard.GetCombineKeyboard(combineModule));
         }
 
         protected internal override bool IsMatches(UserEntity user, Update update) => false;

+ 1 - 1
CardCollector/Commands/CallbackQuery/ConfirmBuying.cs

@@ -22,7 +22,7 @@ namespace CardCollector.Commands.CallbackQuery
             else
             {
                 var text = $"{Messages.confirm_buying}\n{auctionModule.Count}{Text.items} {Text.per} {price}{Text.gem}\n{Messages.are_you_sure}";
-                await MessageController.EditMessage(User, CallbackMessageId, text, Keyboard.GetConfirmationKeyboard(Command.buy_sticker));
+                await MessageController.EditMessage(User, text, Keyboard.GetConfirmationKeyboard(Command.buy_sticker));
             }
         }
 

+ 1 - 1
CardCollector/Commands/CallbackQuery/ConfirmExchange.cs

@@ -22,7 +22,7 @@ namespace CardCollector.Commands.CallbackQuery
             {
                 User.Cash.Gems -= module.EnteredExchangeSum;
                 User.Cash.Coins += module.EnteredExchangeSum * 150;
-                await MessageController.EditMessage(User, CallbackMessageId,
+                await MessageController.EditMessage(User,
                     $"{Messages.you_got} {module.EnteredExchangeSum * 150}{Text.coin} {Text.per} {module.EnteredExchangeSum}{Text.gem}");
             }
         }

+ 1 - 1
CardCollector/Commands/CallbackQuery/ConfirmationSelling.cs

@@ -25,7 +25,7 @@ namespace CardCollector.Commands.CallbackQuery
                 User.Stickers[collectionModule.SelectedSticker.Md5Hash].Count -= collectionModule.Count;
                 AuctionController.SellCard(User.Id, collectionModule.SelectedSticker.Id, collectionModule.SellPrice,
                     collectionModule.Count);
-                await MessageController.EditMessage(User, CallbackMessageId, Messages.successfully_selling);
+                await MessageController.EditMessage(User, Messages.successfully_selling);
             }
         }
         

+ 2 - 2
CardCollector/Commands/CallbackQuery/DeleteCombine.cs

@@ -16,12 +16,12 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            var sticker = await StickerDao.GetStickerByHash(CallbackData.Split('=')[1]);
+            var sticker = await StickerDao.GetByHash(CallbackData.Split('=')[1]);
             var module = User.Session.GetModule<CombineModule>();
             module.CombineList.Remove(sticker);
             if (module.CombineList.Count == 0)
                 await new Back(User, Update).PrepareAndExecute();
-            else await MessageController.EditMessage(User, CallbackMessageId, module.ToString(), Keyboard.GetCombineKeyboard(module));
+            else await MessageController.EditMessage(User, module.ToString(), Keyboard.GetCombineKeyboard(module));
         }
 
         public DeleteCombine() { }

+ 1 - 3
CardCollector/Commands/CallbackQuery/EndUploadStickers.cs

@@ -16,9 +16,7 @@ namespace CardCollector.Commands.CallbackQuery
         public override async Task Execute()
         {
             User.Session.State = UserState.UploadFile;
-            var module = User.Session.GetModule<UploadedStickersModule>();
-            await MessageController.EditMessage(User, module.MessageId, Messages.upload_your_file, 
-                Keyboard.BackKeyboard);
+            await MessageController.EditMessage(User, Messages.upload_your_file, Keyboard.BackKeyboard);
         }
 
         public EndUploadStickers() { }

+ 1 - 7
CardCollector/Commands/CallbackQuery/OpenAuthorPackMenu.cs

@@ -19,22 +19,16 @@ namespace CardCollector.Commands.CallbackQuery
             var packs = (await UserPacksDao.GetUserPacks(User.Id))
                 .Where(item => item.Count > 0 && item.PackId != 1).ToList();
             if (packs.Count == 0)
-            {
-                User.Session.UndoCurrentCommand();
                 await MessageController.AnswerCallbackQuery(User, CallbackQueryId, Messages.packs_count_zero, true);
-            }
             else
             {
                 var page = int.Parse(CallbackData.Split('=')[1]);
                 var totalCount = packs.Count;
                 packs = packs.GetRange((page - 1) * 10, packs.Count >= page * 10 ? 10 : packs.Count % 10);
                 if (packs.Count == 0)
-                {
-                    User.Session.UndoCurrentCommand();
                     await MessageController.AnswerCallbackQuery(User, CallbackQueryId, Messages.page_not_found);
-                }
                 else
-                    await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_author,
+                    await MessageController.EditMessage(User, Messages.choose_author,
                         await Keyboard.GetUserPacksKeyboard(packs, Keyboard.GetPagePanel(page, totalCount, CommandText)));
             }
         }

+ 1 - 1
CardCollector/Commands/CallbackQuery/PackInfo.cs

@@ -14,7 +14,7 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.pack_info, Keyboard.BackKeyboard);
+            await MessageController.EditMessage(User, Messages.pack_info, Keyboard.BackKeyboard);
         }
 
         public PackInfo() { }

+ 1 - 1
CardCollector/Commands/CallbackQuery/PutForAuction.cs

@@ -26,7 +26,7 @@ namespace CardCollector.Commands.CallbackQuery
                 $"{Messages.current_price} {module.SellPrice}{Text.gem}" +
                 $"\n{Messages.lower_price} {lowerPrice}{Text.gem}" +
                 $"\n{Messages.enter_your_gems_price} {Text.gem}:", Keyboard.AuctionPutCancelKeyboard);
-            EnterGemsPrice.AddToQueue(User.Id, message.MessageId);
+            EnterGemsPrice.AddToQueue(User.Id);
             User.Session.Messages.Add(message.MessageId);
         }
 

+ 2 - 2
CardCollector/Commands/CallbackQuery/SelectEmoji.cs

@@ -15,8 +15,8 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            EnterEmoji.AddToQueue(User.Id, CallbackMessageId);
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.enter_emoji, Keyboard.EmojiOptions);
+            EnterEmoji.AddToQueue(User.Id);
+            await MessageController.EditMessage(User, Messages.enter_emoji, Keyboard.EmojiOptions);
         }
 
         public SelectEmoji() { }

+ 1 - 0
CardCollector/Commands/CallbackQuery/SelectOffer.cs

@@ -16,6 +16,7 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
+            Logs.LogOut("here");
             await User.ClearChat();
             var offerId = int.Parse(CallbackData.Split('=')[1]);
             var offerInfo = await ShopDao.GetById(offerId);

+ 1 - 1
CardCollector/Commands/CallbackQuery/SelectPrice.cs

@@ -14,7 +14,7 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_price, 
+            await MessageController.EditMessage(User, Messages.choose_price, 
                 User.Session.State == UserState.AuctionMenu ? Keyboard.GemsPriceOptions : Keyboard.CoinsPriceOptions);
         }
 

+ 1 - 1
CardCollector/Commands/CallbackQuery/SelectShopPack.cs

@@ -12,7 +12,7 @@ namespace CardCollector.Commands.CallbackQuery
     {
         protected override string CommandText => Command.select_shop_pack;
         protected override bool ClearMenu => false;
-        protected override bool AddToStack => false;
+        protected override bool AddToStack => true;
 
         public override async  Task Execute()
         {

+ 1 - 1
CardCollector/Commands/CallbackQuery/SelectSort.cs

@@ -14,7 +14,7 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_sort, Keyboard.SortOptions);
+            await MessageController.EditMessage(User, Messages.choose_sort, Keyboard.SortOptions);
         }
 
         public SelectSort() { }

+ 1 - 1
CardCollector/Commands/CallbackQuery/SelectTier.cs

@@ -14,7 +14,7 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            await MessageController.EditMessage(User, CallbackMessageId, Messages.choose_tier, Keyboard.TierOptions);
+            await MessageController.EditMessage(User, Messages.choose_tier, Keyboard.TierOptions);
         }
         
         public SelectTier() { }

+ 1 - 1
CardCollector/Commands/CallbackQuery/ShowInfo.cs

@@ -37,7 +37,7 @@ namespace CardCollector.Commands.CallbackQuery
             return data[0] switch
             {
                 "tier" => $"{Text.sticker} {data[1]} {Text.tier2}",
-                "sticker" => $"{Text.sticker} {(await StickerDao.GetStickerByHash(data[1])).Title}",
+                "sticker" => $"{Text.sticker} {(await StickerDao.GetByHash(data[1])).Title}",
                 _ => ""
             };
         }

+ 1 - 5
CardCollector/Commands/CallbackQuery/SpecialOffers.cs

@@ -20,13 +20,9 @@ namespace CardCollector.Commands.CallbackQuery
                 .WhereAsync(async offer => offer.IsInfinite || !await SpecialOfferUsersDao.NowUsed(User.Id, offer.Id));
             var shopEntities = specialOffers.ToList();
             if (shopEntities.Count < 1)
-            {
-                User.Session.UndoCurrentCommand();
                 await MessageController.AnswerCallbackQuery(User, CallbackQueryId, Messages.offers_not_found, true);
-            }
             else
-                await MessageController.EditMessage(User, CallbackMessageId, Messages.available_offers,
-                    Keyboard.SpecialOffersKeyboard(shopEntities));
+                await MessageController.EditMessage(User, Messages.available_offers, Keyboard.SpecialOffersKeyboard(shopEntities));
         }
 
         public SpecialOffers() { }

+ 1 - 1
CardCollector/Commands/ChosenInlineResult/GetUnlimitedStickerAndExecuteCommand.cs

@@ -20,7 +20,7 @@ namespace CardCollector.Commands.ChosenInlineResult
             /* Получаем хеш стикера */
             var hash = InlineResult.Split('=')[1];
             /* Получаем объект стикера */
-            var sticker = await StickerDao.GetStickerByHash(hash);
+            var sticker = await StickerDao.GetByHash(hash);
             /* Выдаем пользователю 1 стикер */
             await UserStickerRelationDao.AddNew(User, sticker, 1);
             /* Выполняем стандартный сценарий команды */

+ 1 - 1
CardCollector/Commands/ChosenInlineResult/SelectStickerInline.cs

@@ -18,7 +18,7 @@ namespace CardCollector.Commands.ChosenInlineResult
         {
             await User.ClearChat();
             var hash = InlineResult.Split('=')[1];
-            var sticker = await StickerDao.GetStickerByHash(hash);
+            var sticker = await StickerDao.GetByHash(hash);
             var stickerCount = User.Session.State switch
             {
                 UserState.AuctionMenu => await AuctionController.GetStickerCount(sticker.Id, User.Session.GetModule<FiltersModule>()),

+ 26 - 0
CardCollector/Commands/ChosenInlineResult/StickerInfo.cs

@@ -0,0 +1,26 @@
+using System.Threading.Tasks;
+using CardCollector.Controllers;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+using CardCollector.Resources;
+using Telegram.Bot.Types;
+
+namespace CardCollector.Commands.ChosenInlineResult
+{
+    public class StickerInfo : ChosenInlineResultCommand
+    {
+        protected override string CommandText => Command.sticker_info;
+        protected override bool ClearMenu => false;
+        protected override bool AddToStack => false;
+        
+        public override async Task Execute()
+        {
+            var hash = InlineResult.Split('=')[1];
+            var sticker = await StickerDao.GetByHash(hash);
+            await MessageController.EditMessage(User, sticker.ToString(), Keyboard.StickerInfoKeyboard);
+        }
+
+        public StickerInfo() { }
+        public StickerInfo(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 1 - 0
CardCollector/Commands/ChosenInlineResultCommand.cs

@@ -40,6 +40,7 @@ namespace CardCollector.Commands
             new SendPrivateSticker(),
             // Обработка результата при выборе продавца
             new SelectTrader(),
+            new StickerInfo(),
             
             new SelectStickerInline(),
         };

+ 4 - 8
CardCollector/Commands/InlineQuery/ShowAuctionStickers.cs

@@ -1,5 +1,4 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
@@ -18,12 +17,9 @@ namespace CardCollector.Commands.InlineQuery
         public override async Task Execute()
         {
             // Получаем список стикеров
-            var stickersList = (await AuctionController.GetStickers(Query)).AsEnumerable();
-            stickersList = User.Session.GetModule<FiltersModule>()
-                .ApplyTo(stickersList);
-            var results = User.Session.GetModule<FiltersModule>()
-                .ApplyPriceTo(stickersList)
-                .ToTelegramResults(Command.select_sticker);
+            var stickersList = await AuctionController.GetStickers(Query);
+            var filters = User.Session.GetModule<FiltersModule>();
+            var results = filters.ApplyTo(stickersList, true).ToTelegramResults(Command.select_sticker);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }

+ 48 - 0
CardCollector/Commands/InlineQuery/ShowStickersInShopPack.cs

@@ -0,0 +1,48 @@
+#nullable enable
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using CardCollector.Controllers;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+using CardCollector.Resources;
+using CardCollector.Session.Modules;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace CardCollector.Commands.InlineQuery
+{
+    public class ShowStickersInShopPack : InlineQueryCommand
+    {
+        protected override string CommandText => "";
+        protected override bool ClearMenu => false;
+        protected override bool AddToStack => false;
+        
+        public override async Task Execute()
+        {
+            var packId = User.Session.GetModule<ShopModule>().SelectedPack.Id;
+            var stickers = await StickerDao.GetListWhere(item => item.PackId == packId && item.Contains(Query));
+            stickers.Sort(new TierComparer());
+            await MessageController.AnswerInlineQuery(InlineQueryId, stickers.ToTelegramResults(Command.sticker_info));
+        }
+
+        private class TierComparer : IComparer<StickerEntity>
+        {
+            public int Compare(StickerEntity? x, StickerEntity? y)
+            {
+                return x?.Tier - y?.Tier ?? 0;
+            }
+        }
+
+        protected internal override bool IsMatches(UserEntity user, Update update)
+        {
+            var shopModule = user.Session.GetModule<ShopModule>();
+            return user.Session.State == UserState.ShopMenu &&
+                   update.InlineQuery?.ChatType is ChatType.Sender && 
+                   shopModule.SelectedPack != null && 
+                   shopModule.SelectedPack.Id != 1;
+        }
+
+        public ShowStickersInShopPack() { }
+        public ShowStickersInShopPack(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 1 - 0
CardCollector/Commands/InlineQueryCommand.cs

@@ -39,6 +39,7 @@ namespace CardCollector.Commands
             new ShowCombineStickers(),
             // Показать список продавцов
             new ShowTradersInBotChat(),
+            new ShowStickersInShopPack(),
             // Показать стикеры в личных сообщениях с ботом для выбора или просмотра информации
             new ShowStickersInBotChat(),
             new ShowStickersInPrivate(),

+ 0 - 1
CardCollector/Commands/Message/DownloadStickerPack.cs

@@ -19,7 +19,6 @@ namespace CardCollector.Commands.Message
             User.Session.State = UserState.UploadSticker;
             var result = await MessageController.SendMessage(User, Messages.upload_your_stickers, Keyboard.BackKeyboard);
             User.Session.Messages.Add(result.MessageId);
-            User.Session.GetModule<UploadedStickersModule>().MessageId = result.MessageId;
         }
 
         protected internal override bool IsMatches(UserEntity user, Update update)

+ 7 - 9
CardCollector/Commands/Message/EnterEmoji.cs

@@ -21,18 +21,16 @@ namespace CardCollector.Commands.Message
         private const string onlyEmojiPattern =
             "\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff]";
         
-        /* Список пользователей, от которых ожидается ввод эмоджи ключ - id пользователя, значение - сообщение с меню */
-        private static readonly Dictionary<long, int> Queue = new ();
+        private static readonly List<long> Queue = new ();
         public override async Task Execute()
         {
             var input = Update.Message!.Text;
             /* если пользователь ввел что-то кроме эмодзи */
             if (!Regex.IsMatch(input!, onlyEmojiPattern))
-                await MessageController.EditMessage(User, Queue[User.Id], Messages.please_enter_emoji,
-                    Keyboard.EmojiOptions);
+                await MessageController.EditMessage(User, Messages.please_enter_emoji, Keyboard.EmojiOptions);
             /* если пользователь ввел несколько эмодзи или эмодзи и текст */
             else if (!Regex.IsMatch(input, oneEmojiPattern))
-                await MessageController.EditMessage(User, Queue[User.Id], Messages.enter_only_one_emoji,
+                await MessageController.EditMessage(User, Messages.enter_only_one_emoji,
                     Keyboard.EmojiOptions);
             else
             {
@@ -41,15 +39,15 @@ namespace CardCollector.Commands.Message
                 /* Формируем сообщение с имеющимися фильтрами у пользователя */
                 var text = filtersModule.ToString(User.Session.State);
                 /* Редактируем сообщение */
-                await MessageController.EditMessage(User, Queue[User.Id], text, Keyboard.GetSortingMenu(User.Session.State));
+                await MessageController.EditMessage(User, text, Keyboard.GetSortingMenu(User.Session.State));
                 Queue.Remove(User.Id);
             }
         }
 
         /* Добавляем пользователя в очередь */
-        public static void AddToQueue(long userId, int messageId)
+        public static void AddToQueue(long userId)
         {
-            Queue.TryAdd(userId, messageId);
+            if (!Queue.Contains(userId)) Queue.Add(userId);
         }
 
         /* Удаляем пользователя из очереди */
@@ -60,7 +58,7 @@ namespace CardCollector.Commands.Message
 
         protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return Queue.ContainsKey(user.Id) && update.Message!.Type == MessageType.Text;
+            return Queue.Contains(user.Id) && update.Message!.Type == MessageType.Text;
         }
 
         public EnterEmoji() { }

+ 8 - 9
CardCollector/Commands/Message/EnterGemsExchange.cs

@@ -15,12 +15,12 @@ namespace CardCollector.Commands.Message
         protected override bool ClearMenu => false;
         protected override bool AddToStack => false;
 
-        private static readonly Dictionary<long, int> Queue = new ();
+        private static readonly List<long> Queue = new ();
         public override async Task Execute()
         {
             var module = User.Session.GetModule<ShopModule>();
             if (!int.TryParse(Update.Message!.Text, out var sum) || sum < 0)
-                await MessageController.EditMessage(User, Queue[User.Id],
+                await MessageController.EditMessage(User,
                     $"{Messages.exchange_mesage}" +
                     $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
                     $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +
@@ -29,7 +29,7 @@ namespace CardCollector.Commands.Message
             else
             {
                 module.EnteredExchangeSum = sum; 
-                await MessageController.EditMessage(User, Queue[User.Id], 
+                await MessageController.EditMessage(User,
                     $"{Messages.exchange_mesage}" +
                     $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
                     $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +
@@ -39,22 +39,21 @@ namespace CardCollector.Commands.Message
             }
         }
 
-        //Добавляем пользователя в очередь #1#
-        public static void AddToQueue(long userId, int messageId)
+        /* Добавляем пользователя в очередь */
+        public static void AddToQueue(long userId)
         {
-            Queue.TryAdd(userId, messageId);
+            if (!Queue.Contains(userId)) Queue.Add(userId);
         }
 
-        //Удаляем пользователя из очереди #1#
+        /* Удаляем пользователя из очереди */
         public static void RemoveFromQueue(long userId)
         {
             Queue.Remove(userId);
         }
 
-        // Переопределяем метод, так как команда удовлетворяет условию, если пользователь находится в очереди #1#
         protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return Queue.ContainsKey(user.Id) && update.Message!.Type == MessageType.Text;
+            return Queue.Contains(user.Id) && update.Message!.Type == MessageType.Text;
         }
 
         public EnterGemsExchange() { }

+ 9 - 11
CardCollector/Commands/Message/EnterGemsPrice.cs

@@ -14,47 +14,45 @@ namespace CardCollector.Commands.Message
         protected override string CommandText => "";
         protected override bool ClearMenu => false;
         protected override bool AddToStack => false;
-
-        private static readonly Dictionary<long, int> Queue = new ();
+        
+        private static readonly List<long> Queue = new ();
         public override async Task Execute()
         {
             /* если пользователь ввел что-то кроме эмодзи */
             var module = User.Session.GetModule<CollectionModule>();
             if (!int.TryParse(Update.Message!.Text, out var price) || price < 0)
             {
-                await MessageController.EditMessage(User, Queue[User.Id],
+                await MessageController.EditMessage(User,
                     $"{Messages.current_price} {module.SellPrice}{Text.gem}\n{Messages.please_enter_integer}",
                     Keyboard.AuctionPutCancelKeyboard);
             }
             else
             {
                 module.SellPrice = price;
-                await MessageController.EditMessage(User, Queue[User.Id],
+                await MessageController.EditMessage(User,
                     $"{Messages.confirm_selling} {module.SellPrice}{Text.gem}:", Keyboard.AuctionPutCancelKeyboard);
                 Queue.Remove(User.Id);
             }
         }
 
-        //Добавляем пользователя в очередь #1#
-        public static void AddToQueue(long userId, int messageId)
+        /* Добавляем пользователя в очередь */
+        public static void AddToQueue(long userId)
         {
-            Queue.TryAdd(userId, messageId);
+            if (!Queue.Contains(userId)) Queue.Add(userId);
         }
 
-        //Удаляем пользователя из очереди #1#
+        /* Удаляем пользователя из очереди */
         public static void RemoveFromQueue(long userId)
         {
             Queue.Remove(userId);
         }
 
-        // Переопределяем метод, так как команда удовлетворяет условию, если пользователь находится в очереди #1#
         protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return Queue.ContainsKey(user.Id) && update.Message!.Type == MessageType.Text;
+            return Queue.Contains(user.Id) && update.Message!.Type == MessageType.Text;
         }
 
         public EnterGemsPrice() { }
-
         public EnterGemsPrice(UserEntity user, Update update) : base(user, update) { }
     }
 }

+ 6 - 6
CardCollector/Commands/Message/UploadFile.cs

@@ -28,27 +28,27 @@ namespace CardCollector.Commands.Message
             try
             {
                 /* Соообщаем, что начали загрузку файла */
-                await MessageController.EditMessage(User, module.MessageId, Messages.downloading_file);
+                await MessageController.EditMessage(User, Messages.downloading_file);
                 /* Загружаем файл */
                 var fileName = await Utilities.DownloadFile(Update.Message?.Document);
                 /* Сообщаем пользователю, что читаем документ */
-                await MessageController.EditMessage(User, module.MessageId, Messages.reading_document);
+                await MessageController.EditMessage(User, Messages.reading_document);
                 /* Парсим файл */
                 var stickersList = await ParseExcelFile(fileName, module.StickersList);
                 /* Сообщаем пользователю, что удаляем файлы */
-                await MessageController.EditMessage(User, module.MessageId, Messages.deleting_files);
+                await MessageController.EditMessage(User, Messages.deleting_files);
                 File.Delete(fileName);
                 /* Сообщаем пользователю, что загружаем стикеры */
-                await MessageController.EditMessage(User, module.MessageId, Messages.uploading_stickers);
+                await MessageController.EditMessage(User, Messages.uploading_stickers);
                 var packInfo = await PacksDao.AddNew(stickersList.First().Author);
                 await StickerDao.AddRange(stickersList, packInfo.Id);
                 /* Сообщаем пользователю, что стикеры загружены */
-                await MessageController.EditMessage(User, module.MessageId, Messages.stickers_succesfully_uploaded);
+                await MessageController.EditMessage(User, Messages.stickers_succesfully_uploaded);
             }
             catch (Exception e)
             {
                 /* Сообщаем пользователю, что произошла ошибка */
-                await MessageController.EditMessage(User, module.MessageId, $"{Messages.unexpected_exception}: {e.Message}");
+                await MessageController.EditMessage(User, $"{Messages.unexpected_exception}: {e.Message}");
             }
         }
         

+ 1 - 1
CardCollector/Commands/Message/UploadSticker.cs

@@ -23,7 +23,7 @@ namespace CardCollector.Commands.Message
                           $"\n{Messages.uploaded_count} {module.Count}";
             foreach (var (stickerEntity, i) in module.StickersList.WithIndex())
                 message += $"\n{Text.sticker} {i + 1}: {stickerEntity.Id}";
-            await MessageController.EditMessage(User, module.MessageId, message, Keyboard.EndStickerUpload);
+            await MessageController.EditMessage(User, message, Keyboard.EndStickerUpload);
         }
 
         protected internal override bool IsMatches(UserEntity user, Update update)

+ 2 - 2
CardCollector/Controllers/AuctionController.cs

@@ -33,9 +33,9 @@ namespace CardCollector.Controllers
             return await AuctionDao.GetTotalQuantity(stickerId);
         }
 
-        public static async Task<List<StickerEntity>> GetStickers(string filter)
+        public static async Task<IEnumerable<StickerEntity>> GetStickers(string filter)
         {
-            return (await AuctionDao.GetStickers(filter)).ToList();
+            return await AuctionDao.GetStickers(filter);
         }
 
         public static async Task<IEnumerable<AuctionEntity>> GetTradersList(string filter, string stickerId)

+ 13 - 3
CardCollector/Controllers/MessageController.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using CardCollector.Commands;
@@ -89,7 +90,12 @@ namespace CardCollector.Controllers
             try
             {
                 if (!user.IsBlocked)
-                    return await Bot.Client.SendTextMessageAsync(user.ChatId, message, replyMarkup: keyboard, disableNotification: true);
+                {
+                    if (user.Session.Messages.Count > 0 && keyboard is InlineKeyboardMarkup k)
+                        return await EditMessage(user, message, k, user.Session.Messages.Last());
+                    return await Bot.Client.SendTextMessageAsync(user.ChatId, message, replyMarkup: keyboard,
+                        disableNotification: true);
+                }
             }
             catch (Exception e)
             {
@@ -138,12 +144,15 @@ namespace CardCollector.Controllers
          messageId - id сообщения
          message - текст сообщения
          keyboard - клавиатура, которую надо добавить к сообщению */
-        public static async Task<Message> EditMessage(UserEntity user, int messageId, string message, InlineKeyboardMarkup keyboard = null)
+        public static async Task<Message> EditMessage(UserEntity user, string message, InlineKeyboardMarkup keyboard = null, int messageId = -1)
         {
             try
             {
                 if (!user.IsBlocked)
-                    return await Bot.Client.EditMessageTextAsync(user.ChatId, messageId, message, replyMarkup: keyboard);
+                {
+                    var msgId = messageId != -1 ? messageId : user.Session.Messages.Last();
+                    return await Bot.Client.EditMessageTextAsync(user.ChatId, msgId, message, replyMarkup: keyboard);
+                }
             }
             catch (Exception)
             {
@@ -177,6 +186,7 @@ namespace CardCollector.Controllers
         {
             try
             {
+                user.Session.UndoCurrentCommand();
                 if (!user.IsBlocked)
                     await Bot.Client.AnswerCallbackQueryAsync(callbackQueryId, text, showAlert);
             }

+ 11 - 1
CardCollector/DataBase/Entity/StickerEntity.cs

@@ -1,4 +1,5 @@
-using System.ComponentModel.DataAnnotations;
+using System;
+using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
 using System.Linq;
 using CardCollector.Resources;
@@ -68,5 +69,14 @@ namespace CardCollector.DataBase.Entity
             if (Description != "") str += $"\n\n{Text.description}: {Description}";
             return str;
         }
+
+        public bool Contains(string value)
+        {
+            return value != ""
+                ? Title.Contains(value, StringComparison.CurrentCultureIgnoreCase) ||
+                  Author.Contains(value, StringComparison.CurrentCultureIgnoreCase) ||
+                  Emoji.Equals(value)
+                : true;
+        }
     }
 }

+ 4 - 7
CardCollector/DataBase/Entity/UserEntity.cs

@@ -1,4 +1,3 @@
-using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
@@ -50,12 +49,10 @@ namespace CardCollector.DataBase.Entity
         public async Task<IEnumerable<StickerEntity>> GetStickersList(string filter, int tier = -1)
         {
             if (Constants.UNLIMITED_ALL_STICKERS) return await StickerDao.GetAll(filter);
-            var result = Stickers.Values
-                .Where(relation => relation.Count > 0)
-                .Select(rel => StickerDao.GetStickerByHash(rel.ShortHash).Result)
-                .Where(sticker => sticker.Title.Contains(filter, StringComparison.CurrentCultureIgnoreCase));
-            if (tier != -1) result = result.Where(sticker => sticker.Tier == tier);
-            return result;
+            var relationStickers = Stickers.Values.Where(relation => relation.Count > 0);
+            var stickerList = await Task.WhenAll(relationStickers
+                .Select(async rel => await StickerDao.GetByHash(rel.ShortHash)));
+            return stickerList.Where(sticker => sticker.Contains(filter) && (tier == -1 || sticker.Tier == tier));
         }
 
         public async Task<int> AuctionDiscount()

+ 6 - 6
CardCollector/DataBase/EntityDao/AuctionDao.cs

@@ -30,12 +30,12 @@ namespace CardCollector.DataBase.EntityDao
 
         public static async Task<IEnumerable<StickerEntity>> GetStickers(string filter)
         {
-            var entityList = Table
-                .Select(e => e.StickerId)
-                .Distinct()
-                .ToHashSet();
-            var stickersList = await StickerDao.GetAll(filter);
-            return stickersList.Where(e => entityList.Contains(e.Id));
+            var entityList = (await Table.ToListAsync()).Select(async e => await StickerDao.GetById(e.StickerId));
+            var stickersList = await Task.WhenAll(entityList);
+            return stickersList
+                .Where(item => item.Contains(filter))
+                .GroupBy(item => item.Id)
+                .Select(item => item.First());
         }
         //добавляем объект в аукцион
         public static async void AddNew(AuctionEntity product)

+ 2 - 4
CardCollector/DataBase/EntityDao/StickerDao.cs

@@ -15,7 +15,7 @@ namespace CardCollector.DataBase.EntityDao
         private static readonly DbSet<StickerEntity> Table = Instance.Stickers;
         
         /* Получение информации о стикере по его хешу, возвращает Null, если стикера не существует */
-        public static async Task<StickerEntity> GetStickerByHash(string hash)
+        public static async Task<StickerEntity> GetByHash(string hash)
         {
             return await Table.FirstOrDefaultAsync(item => item.Md5Hash == hash);
         }
@@ -29,9 +29,7 @@ namespace CardCollector.DataBase.EntityDao
 
         public static async Task<List<StickerEntity>> GetAll(string filter = "")
         {
-            var list = await Table.ToListAsync();
-            return filter == "" ? list : list.Where
-                (item => item.Title.Contains(filter, StringComparison.CurrentCultureIgnoreCase)).ToList();
+            return (await Table.WhereAsync(item => item.Contains(filter))).ToList();
         }
 
         public static async Task AddNew(StickerEntity sticker)

+ 1 - 0
CardCollector/DataBase/EntityDao/UserPacksDao.cs

@@ -20,6 +20,7 @@ namespace CardCollector.DataBase.EntityDao
         {
             var newPack = new UserPacks() { UserId = userId, PackId = packId };
             var result = await Table.AddAsync(newPack);
+            await Instance.SaveChangesAsync();
             return result.Entity;
         }
 

+ 1 - 2
CardCollector/Extensions.cs

@@ -8,7 +8,6 @@ using System.Threading.Tasks;
 using CardCollector.DataBase.Entity;
 using CardCollector.DataBase.EntityDao;
 using CardCollector.Resources;
-using CardCollector.Session;
 using Microsoft.EntityFrameworkCore;
 using Telegram.Bot.Types.InlineQueryResults;
 
@@ -59,7 +58,7 @@ namespace CardCollector
             var result = new List<StickerEntity>();
             foreach (var relation in dict.Values.Where(i => i.Count > 0))
             {
-                var sticker = await StickerDao.GetStickerByHash(relation.StickerId);
+                var sticker = await StickerDao.GetByHash(relation.StickerId);
                 if (sticker.Title.Contains(filter, StringComparison.CurrentCultureIgnoreCase)) result.Add(sticker);
             }
             return result;

+ 9 - 0
CardCollector/Resources/Command.Designer.cs

@@ -420,6 +420,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to ABV.
+        /// </summary>
+        internal static string sticker_info {
+            get {
+                return ResourceManager.GetString("sticker_info", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to ABC.
         /// </summary>

+ 3 - 0
CardCollector/Resources/Command.resx

@@ -144,4 +144,7 @@
     <data name="select_shop_pack" xml:space="preserve">
         <value>ABU</value>
     </data>
+    <data name="sticker_info" xml:space="preserve">
+        <value>ABV</value>
+    </data>
 </root>

+ 1 - 1
CardCollector/Resources/Constants.cs

@@ -7,7 +7,7 @@ namespace CardCollector.Resources
     public static class Constants
     {
         /* Переключить данный флаг при сборке на сервер */
-        public const bool DEBUG = false;
+        public const bool DEBUG = true;
 
         /* Интервал сохранения изменений */
         public const double SAVING_CHANGES_INTERVAL = DEBUG ? 10 * 1000 : 5 * 60 * 1000;

+ 18 - 7
CardCollector/Resources/Keyboard.cs

@@ -96,6 +96,14 @@ namespace CardCollector.Resources
             new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
         });
 
+
+        /* Клавиатура с одной кнопкой отмены */
+        public static readonly InlineKeyboardMarkup StickerInfoKeyboard = new (new[]
+        {
+            new[] {InlineKeyboardButton.WithSwitchInlineQueryCurrentChat(Text.show_stickers)},
+            new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
+        });
+
         /* Клавиатура для покупок */
         public static readonly InlineKeyboardMarkup BuyGemsKeyboard = new (new[]
         {
@@ -360,13 +368,13 @@ namespace CardCollector.Resources
             return new InlineKeyboardMarkup(keyboard);
         }
 
-        public static InlineKeyboardMarkup ShopPacksKeyboard = new (new[]
-        {
-            new[] {InlineKeyboardButton.WithCallbackData(Text.buy_random, $"{Command.select_shop_pack}=1")},
-            new[] {InlineKeyboardButton.WithCallbackData(Text.buy_author, $"{Command.buy_author_pack_menu}=1")},
-            new[] {InlineKeyboardButton.WithCallbackData(Text.info, Command.pack_info)},
-            new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
-        });
+        public static InlineKeyboardMarkup ShopPacksKeyboard = new( new[]
+            {
+                new[] {InlineKeyboardButton.WithCallbackData(Text.buy_random, $"{Command.select_shop_pack}=1")},
+                new[] {InlineKeyboardButton.WithCallbackData(Text.buy_author, $"{Command.buy_author_pack_menu}=1")},
+                new[] {InlineKeyboardButton.WithCallbackData(Text.info, Command.pack_info)},
+                new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
+            });
 
         public static InlineKeyboardMarkup OfferKeyboard(ShopModule module)
         {
@@ -390,6 +398,9 @@ namespace CardCollector.Resources
                 });
             keyboard.Add(new [] {InlineKeyboardButton.WithCallbackData(Text.info, Command.show_offer_info)});
             keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(Text.back, Command.back)});
+            if (module.SelectedPack is { } a && a.Id != 1) keyboard.Insert(0, new [] {
+                InlineKeyboardButton.WithSwitchInlineQueryCurrentChat(Text.show_stickers)
+            });
             return new InlineKeyboardMarkup(keyboard);
         }
 

+ 4 - 0
CardCollector/Session/MenuInformation.cs

@@ -19,6 +19,10 @@ namespace CardCollector.Session
                 case UserState.ShopMenu:
                     session.ResetModule<ShopModule>();
                     break;
+                case UserState.CollectionMenu:
+                    session.ResetModule<CollectionModule>();
+                    session.ResetModule<CombineModule>();
+                    break;
             }
             await Parent.PrepareAndExecute();
         }

+ 4 - 2
CardCollector/Session/Modules/FiltersModule.cs

@@ -43,7 +43,7 @@ namespace CardCollector.Session.Modules
             return text;
         }
         
-        public IEnumerable<StickerEntity> ApplyTo(IEnumerable<StickerEntity> list)
+        public IEnumerable<StickerEntity> ApplyTo(IEnumerable<StickerEntity> list, bool applyPrice = false)
         {
             /* Фильтруем по автору */
             if (Filters[Command.authors_menu] is string author && author != "")
@@ -70,7 +70,9 @@ namespace CardCollector.Session.Modules
                 if (sort == SortingTypes.ByTierDecrease)
                     list = list.OrderByDescending(item => item.Tier);
             }
-            return list;
+            return applyPrice 
+                ? ApplyPriceTo(list)
+                : list;
         }
         
         public IEnumerable<StickerEntity> ApplyPriceTo(IEnumerable<StickerEntity> list)

+ 0 - 2
CardCollector/Session/Modules/UploadedStickersModule.cs

@@ -6,13 +6,11 @@ namespace CardCollector.Session.Modules
     public class UploadedStickersModule : Module
     {
         public List<StickerEntity> StickersList = new();
-        public int MessageId = 0;
         public int Count => StickersList.Count;
         
         public void Reset()
         {
             StickersList.Clear();
-            MessageId = 0;
         }
     }
 }

+ 2 - 1
CardCollector/Session/Session.cs

@@ -49,7 +49,8 @@ namespace CardCollector.Session
 
         public void ResetModule<T>() where T : Module
         {
-            Modules[typeof(T)].Reset();
+            try { Modules[typeof(T)].Reset(); }
+            catch (Exception) { /**/ }
         }
 
         public void DeleteModule<T>() where T : Module