Browse Source

Bug fix, refactore code

Tigran 3 years ago
parent
commit
0289dde5af
41 changed files with 249 additions and 230 deletions
  1. 1 1
      CardCollector.sln.DotSettings.user
  2. 1 1
      CardCollector/Bot.cs
  3. 0 4
      CardCollector/Commands/CallbackQuery/BuyByCoins.cs
  4. 0 4
      CardCollector/Commands/CallbackQuery/BuyByGems.cs
  5. 9 1
      CardCollector/Commands/CallbackQuery/BuyGemsQuery.cs
  6. 0 4
      CardCollector/Commands/CallbackQuery/BuyStickerQuery.cs
  7. 11 15
      CardCollector/Commands/CallbackQuery/CallbackQuery.cs
  8. 0 6
      CardCollector/Commands/CallbackQuery/CombineStickers.cs
  9. 1 3
      CardCollector/Commands/CallbackQuery/ConfirmationSellingQuery.cs
  10. 0 4
      CardCollector/Commands/CallbackQuery/OpenPackCallback.cs
  11. 22 16
      CardCollector/Commands/ChosenInlineResult/ChosenInlineResult.cs
  12. 3 10
      CardCollector/Commands/ChosenInlineResult/GetUnlimitedStickerAndExecuteCommand.cs
  13. 3 4
      CardCollector/Commands/ChosenInlineResult/SelectStickerInlineResult.cs
  14. 1 3
      CardCollector/Commands/ChosenInlineResult/SendPrivateSticker.cs
  15. 4 1
      CardCollector/Commands/CommandNotFound.cs
  16. 3 0
      CardCollector/Commands/IgnoreUpdate.cs
  17. 11 11
      CardCollector/Commands/InlineQuery/InlineQuery.cs
  18. 6 10
      CardCollector/Commands/InlineQuery/ShowAuctionStickers.cs
  19. 5 11
      CardCollector/Commands/InlineQuery/ShowCollectionStickers.cs
  20. 4 9
      CardCollector/Commands/InlineQuery/ShowCombineStickers.cs
  21. 4 9
      CardCollector/Commands/InlineQuery/ShowStickersInBotChat.cs
  22. 5 8
      CardCollector/Commands/InlineQuery/ShowStickersInGroup.cs
  23. 6 9
      CardCollector/Commands/InlineQuery/ShowStickersInPrivate.cs
  24. 5 9
      CardCollector/Commands/InlineQuery/ShowTradersInBotChat.cs
  25. 2 4
      CardCollector/Commands/Message/DocumentMessage/UploadFileMessage.cs
  26. 16 17
      CardCollector/Commands/Message/Message.cs
  27. 2 4
      CardCollector/Commands/Message/TextMessage/DownloadStickerPackMessage.cs
  28. 5 5
      CardCollector/Commands/Message/TextMessage/EnterEmojiMessage.cs
  29. 5 8
      CardCollector/Commands/Message/TextMessage/EnterGemsPriceMessage.cs
  30. 2 2
      CardCollector/Commands/Message/TextMessage/ShowSampleMessage.cs
  31. 2 4
      CardCollector/Commands/Message/TextMessage/StopBot.cs
  32. 14 16
      CardCollector/Commands/MyChatMember/MyChatMember.cs
  33. 1 1
      CardCollector/Commands/PreCheckoutQuery/Gems50.cs
  34. 10 9
      CardCollector/Commands/PreCheckoutQuery/PreCheckoutQuery.cs
  35. 1 4
      CardCollector/Commands/UpdateModel.cs
  36. 6 0
      CardCollector/DailyTasks/CustomTasks/SendStickers.cs
  37. 1 0
      CardCollector/DailyTasks/DailyTask.cs
  38. 16 2
      CardCollector/Logs.cs
  39. 1 1
      CardCollector/Resources/Constants.cs
  40. 45 0
      CardCollector/Resources/Text.Designer.cs
  41. 15 0
      CardCollector/Resources/Text.resx

+ 1 - 1
CardCollector.sln.DotSettings.user

@@ -18,7 +18,7 @@
 	
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FMessages/@EntryIndexedValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FSortingTypes/@EntryIndexedValue">False</s:Boolean>
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FText/@EntryIndexedValue">False</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FText/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FStickerEffects_002FEffectTranslations/@EntryIndexedValue">True</s:Boolean>
 	
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>

+ 1 - 1
CardCollector/Bot.cs

@@ -37,6 +37,7 @@ namespace CardCollector
 
         public static void Main(string[] args)
         {
+            Logs.LogOut("Bot started");
             var cts = new CancellationTokenSource();
             Client.StartReceiving(HandleUpdateAsync, HandleErrorAsync, cancellationToken: cts.Token);
             Client.SetMyCommandsAsync(_commands, BotCommandScope.AllPrivateChats(), cancellationToken: cts.Token);
@@ -60,7 +61,6 @@ namespace CardCollector
         public static void StopProgram()
         {
             _timer.Elapsed += OnTimerOnElapsed;
-
             static async void OnTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
             {
                 _timer.Stop();

+ 0 - 4
CardCollector/Commands/CallbackQuery/BuyByCoins.cs

@@ -66,11 +66,7 @@ namespace CardCollector.Commands.CallbackQuery
                 if (!User.Stickers.ContainsKey(sticker.Md5Hash))
                     await UserStickerRelationDao.AddNew(User, sticker, 1);
                 else
-                {
-                    await MessageController.AnswerCallbackQuery(User, CallbackQueryId,
-                        $"{Messages.you_collected} {await User.Cash.Payout(User.Stickers)}{Text.coin}");
                     User.Stickers[sticker.Md5Hash].Count ++;
-                }
                 var stickerMessage = await MessageController.SendSticker(User, sticker.Id);
                 var message = await MessageController.SendMessage(User, $"{Messages.congratulation}\n{sticker}");
                 User.Session.Messages.Add(stickerMessage.MessageId);

+ 0 - 4
CardCollector/Commands/CallbackQuery/BuyByGems.cs

@@ -66,11 +66,7 @@ namespace CardCollector.Commands.CallbackQuery
                 if (!User.Stickers.ContainsKey(sticker.Md5Hash))
                     await UserStickerRelationDao.AddNew(User, sticker, 1);
                 else
-                {
-                    await MessageController.AnswerCallbackQuery(User, CallbackQueryId,
-                        $"{Messages.you_collected} {await User.Cash.Payout(User.Stickers)}{Text.coin}");
                     User.Stickers[sticker.Md5Hash].Count ++;
-                }
                 var stickerMessage = await MessageController.SendSticker(User, sticker.Id);
                 var message = await MessageController.SendMessage(User, $"{Messages.congratulation}\n{sticker}");
                 User.Session.Messages.Add(stickerMessage.MessageId);

+ 9 - 1
CardCollector/Commands/CallbackQuery/BuyGemsQuery.cs

@@ -14,7 +14,15 @@ namespace CardCollector.Commands.CallbackQuery
         {
             await User.ClearChat();
             var messages = await MessageController.SendInvoice(User, Text.gems_title, Text.gems_description, 
-                Command.gems50, new[] {new LabeledPrice(Text.gems_label50, 100)});
+                Command.gems50, new[]
+                {
+                    new LabeledPrice(Text.gems_label50, 100),
+                    new LabeledPrice(Text.gems_label100, 200),
+                    new LabeledPrice(Text.gems_label250, 500),
+                    new LabeledPrice(Text.gems_label500, 1000),
+                    new LabeledPrice(Text.gems_label1000, 2000),
+                    new LabeledPrice(Text.gems_label2500, 5000),
+                });
             User.Session.Messages.Add(messages.MessageId);
         }
 

+ 0 - 4
CardCollector/Commands/CallbackQuery/BuyStickerQuery.cs

@@ -30,11 +30,7 @@ namespace CardCollector.Commands.CallbackQuery
                 if (!User.Stickers.ContainsKey(auctionModule.SelectedSticker.Md5Hash))
                     await UserStickerRelationDao.AddNew(User, auctionModule.SelectedSticker, auctionModule.Count);
                 else
-                {
-                    await MessageController.AnswerCallbackQuery(User, CallbackQueryId,
-                        $"{Messages.you_collected} {await User.Cash.Payout(User.Stickers)}{Text.coin}");
                     User.Stickers[auctionModule.SelectedSticker.Md5Hash].Count += auctionModule.Count;
-                }
                 User.Session.ResetModule<AuctionModule>();
                 await User.ClearChat();
             }

+ 11 - 15
CardCollector/Commands/CallbackQuery/CallbackQuery.cs

@@ -66,34 +66,30 @@ namespace CardCollector.Commands.CallbackQuery
         /* Метод, создающий объекты команд исходя из полученного обновления */
         public static async Task<UpdateModel> Factory(Update update)
         {
-            // Текст команды
-            var command = update.CallbackQuery!.Data;
-
             // Объект пользователя
-            var user = await UserDao.GetUser(update.CallbackQuery.From);
+            var user = await UserDao.GetUser(update.CallbackQuery!.From);
+            
+            // Если пользователь заблокирован игонрируем
+            if (user.IsBlocked) return new IgnoreUpdate();
 
             // Возвращаем объект, если команда совпала
-            foreach (var item in List.Where(item => item.IsMatches(command)))
-                if (Activator.CreateInstance(item.GetType(), user, update) is CallbackQuery executor && executor.IsMatches(command))
-                    return executor;
-
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, command);
+            return List.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, update.CallbackQuery!.Data);
         }
 
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            var query = command.Split('=')[0];
-            return base.IsMatches(query);
+            var query = update.CallbackQuery!.Data!.Split('=')[0];
+            return query == CommandText;
         }
 
+        protected CallbackQuery() { }
         protected CallbackQuery(UserEntity user, Update update) : base(user, update)
         {
             CallbackData = update.CallbackQuery!.Data;
             CallbackMessageId = update.CallbackQuery!.Message!.MessageId;
             CallbackQueryId = update.CallbackQuery!.Id;
         }
-
-        protected CallbackQuery() { }
     }
 }

+ 0 - 6
CardCollector/Commands/CallbackQuery/CombineStickers.cs

@@ -23,20 +23,14 @@ namespace CardCollector.Commands.CallbackQuery
             {
                 await User.ClearChat();
                 User.Cash.Coins -= price;
-                var result = 0;
                 foreach (var (item, count) in combineModule.CombineList)
-                {
-                    result += await User.Cash.Payout(User.Stickers);
                     User.Stickers[item.Md5Hash].Count -= count;
-                }
-                await MessageController.AnswerCallbackQuery(User, CallbackQueryId, $"{Messages.you_collected} {result}{Text.coin}");
                 var authors = combineModule.CombineList.Select(i => i.Key.Author).ToList();
                 var tier = combineModule.Tier;
                 var rnd = new Random();
                 var author = authors[rnd.Next(authors.Count)];
                 var stickers = await StickerDao.GetListWhere(i => i.Author == author && i.Tier == tier + 1);
                 var sticker = stickers[rnd.Next(stickers.Count)];
-                if (User.Stickers.ContainsKey(sticker.Md5Hash)) await User.Cash.Payout(User.Stickers);
                 await UserStickerRelationDao.AddNew(User, sticker, 1);
                 var text = $"{Messages.combined_sticker}:\n" + sticker;
                 var stickerMessage = await MessageController.SendSticker(User, sticker.Id);

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

@@ -19,15 +19,13 @@ namespace CardCollector.Commands.CallbackQuery
             else
             {
                 EnterGemsPriceMessage.RemoveFromQueue(User.Id);
-                var income = await User.Cash.Payout(User.Stickers);
-                await MessageController.AnswerCallbackQuery(User, CallbackQueryId,
-                    $"{Messages.you_collected} {income}{Text.coin}");
                 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);
             }
         }
+        
         public ConfirmationSellingQuery(){}
         public ConfirmationSellingQuery(UserEntity user, Update update) : base(user, update){}
     }

+ 0 - 4
CardCollector/Commands/CallbackQuery/OpenPackCallback.cs

@@ -42,11 +42,7 @@ namespace CardCollector.Commands.CallbackQuery
                 await User.ClearChat();
                 var sticker = stickers[rnd.Next(stickers.Count)];
                 if (User.Stickers.ContainsKey(sticker.Md5Hash))
-                {
-                    await MessageController.AnswerCallbackQuery(User, CallbackQueryId,
-                        $"{Messages.you_collected} {await User.Cash.Payout(User.Stickers)}");
                     User.Stickers[sticker.Md5Hash].Count++;
-                }
                 else
                     await UserStickerRelationDao.AddNew(User, sticker, 1);
                 var stickerMessage = await MessageController.SendSticker(User, sticker.Id);

+ 22 - 16
CardCollector/Commands/ChosenInlineResult/ChosenInlineResult.cs

@@ -22,47 +22,53 @@ namespace CardCollector.Commands.ChosenInlineResult
     public abstract class ChosenInlineResult : UpdateModel
     {
         /* Результат запроса (id выбранного пользователем элемента) */
-        protected readonly string InlineResult = "";
-        
+        protected readonly string InlineResult;
+
+        /* Команда запроса */
+        protected readonly string InlineQuery;
+
         /* Список команд */
         protected static readonly List<ChosenInlineResult> List = new()
         {
             /* Этот объект должен быть всегда в начале списка, так как он должен быть вызван
              вперед других, если в коде включен режим бесконечных стикеров */
             new GetUnlimitedStickerAndExecuteCommand(),
-        
+
             // Обработка результата при отправке стикера
             new SendStickerResult(),
             new SendPrivateSticker(),
             // Обработка результата при выборе продавца
             new SelectTraderResult(),
-            
+
             new SelectStickerInlineResult(),
         };
-        
+
         /* Метод, создающий объекты команд исходя из полученного обновления */
         public static async Task<UpdateModel> Factory(Update update)
         {
-            // Текст команды
-            var command = update.ChosenInlineResult!.ResultId;
-            
             // Объект пользователя
             var user = await UserDao.GetUser(update.ChosenInlineResult!.From);
             
+            // Если пользователь заблокирован игонрируем
+            if (user.IsBlocked) return new IgnoreUpdate();
+
             // Возвращаем объект, если команда совпала
-            foreach (var item in List.Where(item => item.IsMatches(command)))
-                if(Activator.CreateInstance(item.GetType(), user, update) is ChosenInlineResult executor)
-                    if (executor.IsMatches(command)) return executor;
-        
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, command);
+            return List.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, update.ChosenInlineResult.ResultId);
         }
 
-        protected ChosenInlineResult(UserEntity user, Update update) : base(user, update)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            InlineResult = update.ChosenInlineResult!.ResultId;
+            var query = update.ChosenInlineResult!.ResultId.Split("=")[0];
+            return CommandText == query;
         }
 
         protected ChosenInlineResult() { }
+        protected ChosenInlineResult(UserEntity user, Update update) : base(user, update)
+        {
+            InlineResult = update.ChosenInlineResult!.ResultId;
+            InlineQuery = update.ChosenInlineResult.Query;
+        }
     }
 }

+ 3 - 10
CardCollector/Commands/ChosenInlineResult/GetUnlimitedStickerAndExecuteCommand.cs

@@ -28,23 +28,16 @@ namespace CardCollector.Commands.ChosenInlineResult
         public GetUnlimitedStickerAndExecuteCommand() { }
         public GetUnlimitedStickerAndExecuteCommand(UserEntity user, Update update) : base(user, update) { }
         
-        
         /* Список команд, аналогичный родительскому, только не включает эту команду (unlimited) */
         private static readonly List<ChosenInlineResult> PrivateList = List.GetRange(1, List.Count - 1);
         
         /* Метод, создающий объекты команд исходя из полученного обновления */
         private static UpdateModel PrivateFactory(Update update, UserEntity user)
         {
-            // Текст команды
-            var command = update.ChosenInlineResult!.ResultId;
-            
             // Возвращаем объект, если команда совпала
-            foreach (var item in PrivateList.Where(item => item.IsMatches(command)))
-                if(Activator.CreateInstance(item.GetType(), user, update) is ChosenInlineResult executor)
-                    if (executor.IsMatches(command)) return executor;
-        
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, command);
+            return PrivateList.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, update.ChosenInlineResult!.ResultId);
         }
     }
 }

+ 3 - 4
CardCollector/Commands/ChosenInlineResult/SelectStickerInlineResult.cs

@@ -46,11 +46,10 @@ namespace CardCollector.Commands.ChosenInlineResult
             User.Session.Messages.Add(infoMessage.MessageId);
         }
 
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? base.IsMatches(command)
-                : User.Session.State is UserState.CollectionMenu or UserState.AuctionMenu or UserState.CombineMenu or UserState.Default;
+            return base.IsMatches(user, update) && 
+                   User.Session.State is UserState.CollectionMenu or UserState.AuctionMenu or UserState.CombineMenu or UserState.Default;
         }
 
         public SelectStickerInlineResult() { }

+ 1 - 3
CardCollector/Commands/ChosenInlineResult/SendPrivateSticker.cs

@@ -2,7 +2,6 @@
 using CardCollector.Controllers;
 using CardCollector.DailyTasks;
 using CardCollector.DataBase.Entity;
-using CardCollector.DataBase.EntityDao;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
 
@@ -17,8 +16,7 @@ namespace CardCollector.Commands.ChosenInlineResult
             var dailyTask = DailyTask.List[DailyTaskKeys.SendStickersToUsers];
             if (await dailyTask.Execute(User.Id))
             {
-                var userPacks = await UsersPacksDao.GetUserPacks(User.Id);
-                userPacks.RandomCount++;
+                await dailyTask.GiveReward(User.Id);
                 var message = await MessageController.SendMessage(User, Messages.pack_prize);
                 User.Session.Messages.Add(message.MessageId);
             }

+ 4 - 1
CardCollector/Commands/CommandNotFound.cs

@@ -13,9 +13,12 @@ namespace CardCollector.Commands
 
         public override async Task Execute()
         {
-            await MessageController.SendMessage(User, "Команда не найдена " + _command);
+            var message = await MessageController.SendMessage(User, "Команда не найдена " + _command);
+            User.Session.Messages.Add(message.MessageId);
         }
 
+        protected internal override bool IsMatches(UserEntity user, Update update) => true;
+
         public CommandNotFound(UserEntity user, Update update, string command) : base(user, update)
         {
             _command = command;

+ 3 - 0
CardCollector/Commands/IgnoreUpdate.cs

@@ -1,4 +1,6 @@
 using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using Telegram.Bot.Types;
 
 namespace CardCollector.Commands
 {
@@ -7,5 +9,6 @@ namespace CardCollector.Commands
     {
         protected override string CommandText => "";
         public override Task Execute() { return  Task.CompletedTask; }
+        protected internal override bool IsMatches(UserEntity user, Update update) => true;
     }
 }

+ 11 - 11
CardCollector/Commands/InlineQuery/InlineQuery.cs

@@ -21,7 +21,9 @@ namespace CardCollector.Commands.InlineQuery
     public abstract class InlineQuery : UpdateModel
     {
         /* Id входящего запроса */
-        protected readonly string InlineQueryId = "";
+        protected readonly string InlineQueryId;
+        /* Запрос */
+        protected readonly string Query;
         
         /* Список команд */
         private static readonly List<InlineQuery> List = new()
@@ -45,24 +47,22 @@ namespace CardCollector.Commands.InlineQuery
         /* Метод, создающий объекты команд исходя из полученного обновления */
         public static async Task<UpdateModel> Factory(Update update)
         {
-            // Текст команды
-            var command = $"{update.InlineQuery!.ChatType}={update.InlineQuery!.Query}";
-            
             // Объект пользователя
             var user = await UserDao.GetUser(update.InlineQuery!.From);
             
-            // Возвращаем объект, если команда совпала
-            foreach (var item in List.Where(item => item.IsMatches(command)))
-                if(Activator.CreateInstance(item.GetType(), user, update) is InlineQuery executor)
-                    if (executor.IsMatches(command)) return executor;
-        
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, command);
+            // Если пользователь заблокирован игонрируем
+            if (user.IsBlocked) return new IgnoreUpdate();
+            
+            /* Возвращаем первую подходящую команду */
+            return List.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, $"{update.InlineQuery!.ChatType}={update.InlineQuery!.Query}");
         }
 
         protected InlineQuery(UserEntity user, Update update) : base(user, update)
         {
             InlineQueryId = update.InlineQuery!.Id;
+            Query = update.InlineQuery!.Query;
         }
         
         protected InlineQuery() { }

+ 6 - 10
CardCollector/Commands/InlineQuery/ShowAuctionStickers.cs

@@ -5,18 +5,18 @@ using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
     public class ShowAuctionStickers : InlineQuery
     {
         protected override string CommandText => "";
+        
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             // Получаем список стикеров
-            var stickersList = (await AuctionController.GetStickers(filter)).AsEnumerable();
+            var stickersList = (await AuctionController.GetStickers(Query)).AsEnumerable();
             stickersList = User.Session.GetModule<FiltersModule>()
                 .ApplyTo(stickersList);
             var results = User.Session.GetModule<FiltersModule>()
@@ -25,14 +25,10 @@ namespace CardCollector.Commands.InlineQuery
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
-        
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и пользователь в меню аукциона и он не выбрал стикер */
-        protected internal override bool IsMatches(string command)
+
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.AuctionMenu;
+            return update.InlineQuery?.ChatType is ChatType.Sender && User.Session.State == UserState.AuctionMenu;
         }
 
         public ShowAuctionStickers() { }

+ 5 - 11
CardCollector/Commands/InlineQuery/ShowCollectionStickers.cs

@@ -1,10 +1,10 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
@@ -13,23 +13,17 @@ namespace CardCollector.Commands.InlineQuery
         protected override string CommandText => "";
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             // Получаем список стикеров
-            var stickersList = await User.GetStickersList(filter);
+            var stickersList = await User.GetStickersList(Query);
             var results = User.Session.GetModule<FiltersModule>()
                 .ApplyTo(stickersList).ToTelegramResults(Command.select_sticker);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
         
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и пользователь в меню коллекции */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.CollectionMenu;
+            return update.InlineQuery?.ChatType is ChatType.Sender && User.Session.State == UserState.CollectionMenu;
         }
 
         public ShowCollectionStickers() { }

+ 4 - 9
CardCollector/Commands/InlineQuery/ShowCombineStickers.cs

@@ -4,6 +4,7 @@ using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
@@ -12,23 +13,17 @@ namespace CardCollector.Commands.InlineQuery
         protected override string CommandText => "";
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             var module = User.Session.GetModule<CombineModule>();
             // Получаем список стикеров
-            var stickersList = await User.GetStickersList(filter, module.Tier);
+            var stickersList = await User.GetStickersList(Query, module.Tier);
             var results = stickersList.ToTelegramResults(Command.select_sticker);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
         
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и пользователь в меню коллекции */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.CombineMenu;
+            return update.InlineQuery?.ChatType is ChatType.Sender && User.Session.State == UserState.CombineMenu;
         }
 
         public ShowCombineStickers() { }

+ 4 - 9
CardCollector/Commands/InlineQuery/ShowStickersInBotChat.cs

@@ -3,6 +3,7 @@ using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
@@ -15,22 +16,16 @@ namespace CardCollector.Commands.InlineQuery
         
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             // Получаем список стикеров
-            var stickersList = await User.GetStickersList(filter);
+            var stickersList = await User.GetStickersList(Query);
             var results = stickersList.ToTelegramResults(Command.select_sticker);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
 
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и у пользователя нет выбранного стикера */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.Default;
+            return update.InlineQuery?.ChatType is ChatType.Sender && User.Session.State == UserState.Default;
         }
 
         public ShowStickersInBotChat() { }

+ 5 - 8
CardCollector/Commands/InlineQuery/ShowStickersInGroup.cs

@@ -3,6 +3,7 @@ using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
@@ -15,20 +16,16 @@ namespace CardCollector.Commands.InlineQuery
         
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             // Получаем список стикеров
-            var stickersList = await User.GetStickersList(filter);
+            var stickersList = await User.GetStickersList(Query);
             var results = stickersList.ToTelegramResults(Command.send_sticker, false);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
-
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в беседе/канале */
-        protected internal override bool IsMatches(string command)
+        
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return command.Contains("Group") || command.Contains("Supergroup");
+            return update.InlineQuery?.ChatType is ChatType.Group or ChatType.Supergroup;
         }
 
         public ShowStickersInGroup() { }

+ 6 - 9
CardCollector/Commands/InlineQuery/ShowStickersInPrivate.cs

@@ -3,6 +3,7 @@ using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
@@ -14,22 +15,18 @@ namespace CardCollector.Commands.InlineQuery
         
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             // Получаем список стикеров
-            var stickersList = await User.GetStickersList(filter);
+            var stickersList = await User.GetStickersList(Query);
             var results = stickersList.ToTelegramResults(Command.send_private_sticker, false);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);
         }
-
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях (кроме личных сообщений с ботом) */
-        protected internal override bool IsMatches(string command)
+        
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return command.Contains("Private");
+            return update.InlineQuery?.ChatType is ChatType.Private;
         }
-
+        
         public ShowStickersInPrivate() { }
         public ShowStickersInPrivate(UserEntity user, Update update) : base(user, update) { }
     }

+ 5 - 9
CardCollector/Commands/InlineQuery/ShowTradersInBotChat.cs

@@ -4,19 +4,19 @@ using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.InlineQuery
 {
     public class ShowTradersInBotChat : InlineQuery
     {
         protected override string CommandText => "";
+        
         public override async Task Execute()
         {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
             var module = User.Session.GetModule<AuctionModule>();
             // Получаем список продавцов
-            var traders = await AuctionController.GetTradersList(filter, module.SelectedSticker.Id);
+            var traders = await AuctionController.GetTradersList(Query, module.SelectedSticker.Id);
             var results = User.Session.GetModule<FiltersModule>()
                 .ApplyPriceTo(traders)
                 .ToTelegramResults(Command.buy_sticker, 1.0 - await User.AuctionDiscount()/100.0);
@@ -24,13 +24,9 @@ namespace CardCollector.Commands.InlineQuery
             await MessageController.AnswerInlineQuery(InlineQueryId, await results);
         }
         
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и пользователь выбрал стикер в меню аукциона */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.ProductMenu;
+            return update.InlineQuery?.ChatType is ChatType.Sender && User.Session.State == UserState.ProductMenu;
         }
 
         public ShowTradersInBotChat() { }

+ 2 - 4
CardCollector/Commands/Message/DocumentMessage/UploadFileMessage.cs

@@ -175,11 +175,9 @@ namespace CardCollector.Commands.Message.DocumentMessage
             fileStream.Close();
         }
 
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User != null 
-                ? User.Session.State == UserState.UploadFile
-                : base.IsMatches(command);
+            return User.Session.State == UserState.UploadFile;
         }
 
         public UploadFileMessage() { }

+ 16 - 17
CardCollector/Commands/Message/Message.cs

@@ -70,6 +70,9 @@ namespace CardCollector.Commands.Message
                     await Bot.Client.DeleteMessageAsync(update.Message.Chat.Id, update.Message.MessageId);
                 return new IgnoreUpdate();
             }
+            
+            // Если сообщение - это команда, полученная от бота, то мы игнорируем, так как получим ее через ChosenInlineResult
+            if (update.Message.ViaBot is { }) return new IgnoreUpdate();
 
             /* Список команд определяем исходя из типа сообщения */
             var list = update.Message.Type switch
@@ -79,14 +82,6 @@ namespace CardCollector.Commands.Message
                 _ => new List<Message>()
             };
             
-            /* Данные определяем исходя из типа сообщения */
-            var data = update.Message.Type switch
-            {
-                MessageType.Text => update.Message.Text,
-                MessageType.Document => update.Message.Document!.FileId,
-                _ => "Unknown"
-            };
-            
             // Объект пользователя
             var user = await UserDao.GetUser(update.Message!.From);
             
@@ -96,16 +91,20 @@ namespace CardCollector.Commands.Message
             // Удаляем сообщение пользователя в лс, оно нам больше не нужно
             await MessageController.DeleteMessage(user, update.Message.MessageId);
             
-            // Если сообщение - это команда, полученная от бота, то мы игнорируем, так как получим ее через ChosenInlineResult
-            if (update.Message.ViaBot is { }) return new IgnoreUpdate();
-            
             // Возвращаем объект, если команда совпала
-            foreach (var item in list.Where(item => item.IsMatches(data)))
-                if(Activator.CreateInstance(item.GetType(), user, update) is Message executor)
-                    if (executor.IsMatches(data)) return executor;
-        
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, data);
+            /* Возвращаем первую подходящую команду */
+            return list.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, update.Message.Type switch {
+                    MessageType.Text => update.Message.Text,
+                    MessageType.Document => update.Message.Document!.FileId,
+                    _ => "Unknown"
+                });
+        }
+
+        protected internal override bool IsMatches(UserEntity user, Update update)
+        {
+            return update.Message!.Text == CommandText;
         }
 
         protected Message(UserEntity user, Update update) : base(user, update) { }

+ 2 - 4
CardCollector/Commands/Message/TextMessage/DownloadStickerPackMessage.cs

@@ -17,11 +17,9 @@ namespace CardCollector.Commands.Message.TextMessage
             User.Session.Messages.Add(result.MessageId);
         }
 
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User != null 
-                ? base.IsMatches(command) && User.PrivilegeLevel >= Constants.ARTIST_PRIVILEGE_LEVEL
-                : base.IsMatches(command);
+            return base.IsMatches(user, update) && User.PrivilegeLevel >= Constants.ARTIST_PRIVILEGE_LEVEL;
         }
 
         public DownloadStickerPackMessage() { }

+ 5 - 5
CardCollector/Commands/Message/TextMessage/EnterEmojiMessage.cs

@@ -6,6 +6,7 @@ using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.Message.TextMessage
 {
@@ -22,9 +23,9 @@ namespace CardCollector.Commands.Message.TextMessage
         private static readonly Dictionary<long, int> Queue = new ();
         public override async Task Execute()
         {
-            var input = "" + Update.Message!.Text; // это чтоб варн не показывлся, тут никогда не null, так как в Factory все уже проверено
+            var input = Update.Message!.Text;
             /* если пользователь ввел что-то кроме эмодзи */
-            if (!Regex.IsMatch(input, onlyEmojiPattern))
+            if (!Regex.IsMatch(input!, onlyEmojiPattern))
                 await MessageController.EditMessage(User, Queue[User.Id], Messages.please_enter_emoji, Keyboard.EmojiOptions);
             /* если пользователь ввел несколько эмодзи или эмодзи и текст */
             else if (!Regex.IsMatch(input, oneEmojiPattern))
@@ -53,10 +54,9 @@ namespace CardCollector.Commands.Message.TextMessage
             Queue.Remove(userId);
         }
 
-        /* Переопределяем метод, так как команда удовлетворяет условию, если пользователь находится в очереди */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null ? base.IsMatches(command) : Queue.ContainsKey(User.Id);
+            return Queue.ContainsKey(User.Id) && update.Message!.Type == MessageType.Text;
         }
 
         public EnterEmojiMessage() { }

+ 5 - 8
CardCollector/Commands/Message/TextMessage/EnterGemsPriceMessage.cs

@@ -5,6 +5,7 @@ using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
 
 namespace CardCollector.Commands.Message.TextMessage
 {
@@ -43,17 +44,13 @@ namespace CardCollector.Commands.Message.TextMessage
         }
 
         // Переопределяем метод, так как команда удовлетворяет условию, если пользователь находится в очереди #1#
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null ? base.IsMatches(command) : Queue.ContainsKey(User.Id);
+            return Queue.ContainsKey(User.Id) && update.Message!.Type == MessageType.Text;
         }
 
-        public EnterGemsPriceMessage()
-        {
-        }
+        public EnterGemsPriceMessage() { }
 
-        public EnterGemsPriceMessage(UserEntity user, Update update) : base(user, update)
-        {
-        }
+        public EnterGemsPriceMessage(UserEntity user, Update update) : base(user, update) { }
     }
 }

+ 2 - 2
CardCollector/Commands/Message/TextMessage/ShowSampleMessage.cs

@@ -23,9 +23,9 @@ namespace CardCollector.Commands.Message.TextMessage
         }
 
         /* Нужно помимо совпадения текста проверить пользователя на уровень привилегий */
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return base.IsMatches(command) && User is not {PrivilegeLevel: < Constants.PROGRAMMER_PRIVILEGE_LEVEL};
+            return base.IsMatches(user, update) && User.PrivilegeLevel >= Constants.PROGRAMMER_PRIVILEGE_LEVEL;
         }
         
         public ShowSampleMessage(UserEntity user, Update update) : base(user, update) { }

+ 2 - 4
CardCollector/Commands/Message/TextMessage/StopBot.cs

@@ -17,11 +17,9 @@ namespace CardCollector.Commands.Message.TextMessage
             Bot.StopProgram();
         }
 
-        protected internal override bool IsMatches(string command)
+        protected internal override bool IsMatches(UserEntity user, Update update)
         {
-            return User == null 
-                ? base.IsMatches(command)
-                : User.PrivilegeLevel >= Constants.PROGRAMMER_PRIVILEGE_LEVEL || Constants.DEBUG;
+            return base.IsMatches(user, update) && User.PrivilegeLevel >= Constants.PROGRAMMER_PRIVILEGE_LEVEL;
         }
 
         public StopBot() { }

+ 14 - 16
CardCollector/Commands/MyChatMember/MyChatMember.cs

@@ -13,37 +13,35 @@ namespace CardCollector.Commands.MyChatMember
     {
         protected override string CommandText => "";
         private readonly ChatMemberStatus _status;
-        public override async Task Execute()
+        public override Task Execute()
         {
             switch (_status)
             {
-                case ChatMemberStatus.Creator:
-                    await UserDao.GetUser(ChatToUser(Update.MyChatMember!.Chat));
-                    break;
-                case ChatMemberStatus.Administrator:
-                    await UserDao.GetUser(ChatToUser(Update.MyChatMember!.Chat));
-                    break;
                 case ChatMemberStatus.Member:
                     User.IsBlocked = false;
                     break;
                 case ChatMemberStatus.Kicked:
-                    User.IsBlocked = false;
+                    User.IsBlocked = true;
                     break;
                 case ChatMemberStatus.Restricted or ChatMemberStatus.Left:
                     break;
-                default:
-                    await new CommandNotFound(User, Update, _status.ToString()).Execute();
-                    break;
             }
+            return Task.CompletedTask;
         }
+
+        protected internal override bool IsMatches(UserEntity user, Update update)
+        {
+            return true;
+        }
+
         public static async Task<UpdateModel> Factory(Update update)
         {
             // Объект пользователя
             var user = await UserDao.GetUser(update.MyChatMember!.From);
-            return new MyChatMember(user, update, update.MyChatMember.NewChatMember.Status);
+            return new MyChatMember(user, update);
         }
 
-        private static User ChatToUser(Chat chat)
+        /*private static User ChatToUser(Chat chat)
         {
             return new User
             {
@@ -53,11 +51,11 @@ namespace CardCollector.Commands.MyChatMember
                 Id = chat.Id,
                 IsBot = chat.Id < 0
             };
-        }
+        }*/
 
-        private MyChatMember(UserEntity user, Update update, ChatMemberStatus status) : base(user, update)
+        private MyChatMember(UserEntity user, Update update) : base(user, update)
         {
-            _status = status;
+            _status = update.MyChatMember!.NewChatMember.Status;
         }
     }
 }

+ 1 - 1
CardCollector/Commands/PreCheckoutQuery/Gems50.cs

@@ -13,7 +13,7 @@ namespace CardCollector.Commands.PreCheckoutQuery
         public override async Task Execute()
         {
             await Bot.Client.AnswerPreCheckoutQueryAsync(PreCheckoutQueryId);
-            User.Cash.Gems += 50;
+            User.Cash.Gems += 50 * Amount / 100;
             await User.ClearChat();
             var message = await MessageController.SendMessage(User, Messages.thanks_for_buying);
             User.Session.Messages.Add(message.MessageId);

+ 10 - 9
CardCollector/Commands/PreCheckoutQuery/PreCheckoutQuery.cs

@@ -11,6 +11,7 @@ namespace CardCollector.Commands.PreCheckoutQuery
     public abstract class PreCheckoutQuery : UpdateModel
     {
         protected readonly string PreCheckoutQueryId;
+        protected readonly int Amount;
         
         private static readonly List<PreCheckoutQuery> List = new()
             {
@@ -23,9 +24,6 @@ namespace CardCollector.Commands.PreCheckoutQuery
         /* Метод, создающий объекты команд исходя из полученного обновления */
         public static async Task<UpdateModel> Factory(Update update)
         {
-            /* Данные определяем исходя из указанного нами продукта */
-            var data = update.PreCheckoutQuery!.InvoicePayload;
-            
             // Объект пользователя
             var user = await UserDao.GetUser(update.PreCheckoutQuery!.From);
             
@@ -33,18 +31,21 @@ namespace CardCollector.Commands.PreCheckoutQuery
             if (user.IsBlocked) return new IgnoreUpdate();
             
             // Возвращаем объект, если команда совпала
-            foreach (var item in List.Where(item => item.IsMatches(data)))
-                if(Activator.CreateInstance(item.GetType(), user, update) is PreCheckoutQuery executor)
-                    if (executor.IsMatches(data)) return executor;
-        
-            // Возвращаем команда не найдена, если код дошел до сюда
-            return new CommandNotFound(user, update, data);
+            return List.FirstOrDefault(item => item.IsMatches(user, update)) is { } executor
+                ? (UpdateModel) Activator.CreateInstance(executor.GetType(), user, update)
+                : new CommandNotFound(user, update, update.PreCheckoutQuery!.InvoicePayload);
+        }
+
+        protected internal override bool IsMatches(UserEntity user, Update update)
+        {
+            return CommandText == update.PreCheckoutQuery!.InvoicePayload;
         }
 
         protected PreCheckoutQuery() { }
         protected PreCheckoutQuery(UserEntity user, Update update) : base(user, update)
         {
             PreCheckoutQueryId = update.PreCheckoutQuery!.Id;
+            Amount = update.PreCheckoutQuery.TotalAmount;
         }
     }
 }

+ 1 - 4
CardCollector/Commands/UpdateModel.cs

@@ -19,10 +19,7 @@ namespace CardCollector.Commands
 
         public abstract Task Execute();
 
-        protected internal virtual bool IsMatches(string command)
-        {
-            return command.Contains(CommandText);
-        }
+        protected internal abstract bool IsMatches(UserEntity user, Update update);
 
         protected UpdateModel()
         {

+ 6 - 0
CardCollector/DailyTasks/CustomTasks/SendStickers.cs

@@ -17,5 +17,11 @@ namespace CardCollector.DailyTasks.CustomTasks
             task.Progress--;
             return task.Progress == 0;
         }
+
+        public override async Task GiveReward(long userId, object[] args = null)
+        {
+            var userPacks = await UsersPacksDao.GetUserPacks(userId);
+            userPacks.RandomCount++;
+        }
     }
 }

+ 1 - 0
CardCollector/DailyTasks/DailyTask.cs

@@ -25,6 +25,7 @@ namespace CardCollector.DailyTasks
         public abstract string Description { get; }
 
         public abstract Task<bool> Execute(long userId, object[] args = null);
+        public abstract Task GiveReward(long userId, object[] args = null);
 
         public static async void ResetTasks(object o, ElapsedEventArgs e)
         {

+ 16 - 2
CardCollector/Logs.cs

@@ -1,5 +1,6 @@
 using System;
 using System.IO;
+using System.Reflection;
 using CardCollector.Resources;
 // ReSharper disable ConditionIsAlwaysTrueOrFalse
 // ReSharper disable LocalizableElement
@@ -9,11 +10,24 @@ namespace CardCollector
 {
     public static class Logs
     {
-        private static void Print(string message)
+        private static readonly string path;
+
+        static Logs()
+        {
+            path = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location) + @"\Logs";
+            if (!Directory.Exists(path))
+                Directory.CreateDirectory(path);
+        }
+        
+        private static async void Print(string message)
         {
             var today = DateTime.Today;
             if (Constants.DEBUG) Console.WriteLine(message);
-            else File.AppendAllText($"Log {today.Day}-{today.Month}-{today.Year}.txt", message + Environment.NewLine);
+            else
+            {
+                using(var sw = File.AppendText($@"{path}\{today.Day}-{today.Month}-{today.Year}.log"))
+                    await sw.WriteLineAsync(message);
+            }
         }
         
         public static void LogOut(object message)

+ 1 - 1
CardCollector/Resources/Constants.cs

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

+ 45 - 0
CardCollector/Resources/Text.Designer.cs

@@ -330,6 +330,42 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to 100💎.
+        /// </summary>
+        internal static string gems_label100 {
+            get {
+                return ResourceManager.GetString("gems_label100", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to 1000💎.
+        /// </summary>
+        internal static string gems_label1000 {
+            get {
+                return ResourceManager.GetString("gems_label1000", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to 250💎.
+        /// </summary>
+        internal static string gems_label250 {
+            get {
+                return ResourceManager.GetString("gems_label250", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to 2500💎.
+        /// </summary>
+        internal static string gems_label2500 {
+            get {
+                return ResourceManager.GetString("gems_label2500", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to 50💎.
         /// </summary>
@@ -339,6 +375,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to 500💎.
+        /// </summary>
+        internal static string gems_label500 {
+            get {
+                return ResourceManager.GetString("gems_label500", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to 50 алмазов.
         /// </summary>

+ 15 - 0
CardCollector/Resources/Text.resx

@@ -228,4 +228,19 @@
     <data name="effect" xml:space="preserve">
         <value>Эффект</value>
     </data>
+    <data name="gems_label100" xml:space="preserve">
+        <value>100💎</value>
+    </data>
+    <data name="gems_label250" xml:space="preserve">
+        <value>250💎</value>
+    </data>
+    <data name="gems_label500" xml:space="preserve">
+        <value>500💎</value>
+    </data>
+    <data name="gems_label1000" xml:space="preserve">
+        <value>1000💎</value>
+    </data>
+    <data name="gems_label2500" xml:space="preserve">
+        <value>2500💎</value>
+    </data>
 </root>