2 Commits 01a97b3df8 ... df46d2f02d

Author SHA1 Message Date
  Tigran df46d2f02d Hide profile buttons back and collect income (when income equals zero). After collecting income profile message not deleted. Add gift emoji to my packs in profile menu. Edit menu and daily task messeges instead of send new. Help command realese. Return stickers from auction. String fixes 3 years ago
  Tigran aafa9ff1ac Combine sum change and hide added stickers 3 years ago
37 changed files with 429 additions and 125 deletions
  1. 1 1
      CardCollector.sln.DotSettings.user
  2. 6 5
      CardCollector/Bot.cs
  3. 4 8
      CardCollector/Commands/CallbackQuery/BuyCoins.cs
  4. 3 5
      CardCollector/Commands/CallbackQuery/BuyGems.cs
  5. 2 1
      CardCollector/Commands/CallbackQuery/BuyPack.cs
  6. 1 1
      CardCollector/Commands/CallbackQuery/BuyShopItem.cs
  7. 12 1
      CardCollector/Commands/CallbackQuery/CollectIncome.cs
  8. 30 0
      CardCollector/Commands/CallbackQuery/ReturnFromAuction.cs
  9. 9 3
      CardCollector/Commands/CallbackQuery/SelectShopPack.cs
  10. 29 0
      CardCollector/Commands/CallbackQuery/SetExchangeSum.cs
  11. 26 0
      CardCollector/Commands/CallbackQuery/SetGemsSum.cs
  12. 3 0
      CardCollector/Commands/CallbackQueryCommand.cs
  13. 1 1
      CardCollector/Commands/ChosenInlineResult/SelectTrader.cs
  14. 1 1
      CardCollector/Commands/ChosenInlineResult/SendPrivateSticker.cs
  15. 3 1
      CardCollector/Commands/InlineQuery/ShowCombineStickers.cs
  16. 2 2
      CardCollector/Commands/Message/EnterGemsExchange.cs
  17. 20 0
      CardCollector/Commands/Message/Help.cs
  18. 2 1
      CardCollector/Commands/Message/Menu.cs
  19. 2 1
      CardCollector/Commands/Message/Profile.cs
  20. 1 0
      CardCollector/Commands/MessageCommand.cs
  21. 1 1
      CardCollector/Commands/PreCheckoutQuery/BuyGems.cs
  22. 4 4
      CardCollector/Controllers/MessageController.cs
  23. 2 2
      CardCollector/DailyTasks/CustomTasks/SendStickers.cs
  24. 3 0
      CardCollector/DataBase/BotDatabase.cs
  25. 1 1
      CardCollector/DataBase/Entity/UserEntity.cs
  26. 13 0
      CardCollector/DataBase/EntityDao/UserPacksDao.cs
  27. 27 0
      CardCollector/Resources/Command.Designer.cs
  28. 9 0
      CardCollector/Resources/Command.resx
  29. 78 25
      CardCollector/Resources/Keyboard.cs
  30. 50 5
      CardCollector/Resources/Messages.Designer.cs
  31. 27 6
      CardCollector/Resources/Messages.resx
  32. 28 28
      CardCollector/Resources/Text.Designer.cs
  33. 16 16
      CardCollector/Resources/Text.resx
  34. 9 2
      CardCollector/Session/Modules/CombineModule.cs
  35. 1 1
      CardCollector/StickerEffects/EffectTranslations.Designer.cs
  36. 1 1
      CardCollector/StickerEffects/EffectTranslations.resx
  37. 1 1
      CardCollector/TimerTasks/PiggyBankAlert.cs

+ 1 - 1
CardCollector.sln.DotSettings.user

@@ -17,7 +17,7 @@
 	
 	
 	
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FMessages/@EntryIndexedValue">False</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FMessages/@EntryIndexedValue">True</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_002FStickerEffects_002FEffectTranslations/@EntryIndexedValue">False</s:Boolean>

+ 6 - 5
CardCollector/Bot.cs

@@ -28,12 +28,13 @@ namespace CardCollector
 
         private static readonly IEnumerable<BotCommand> _commands = new[]
         {
-            new BotCommand {Command = "/menu", Description = "Показать меню"},/*
-            new BotCommand {Command = "/help", Description = "Показать информацию"},
-            new BotCommand {Command = "/error", Description = "Сообщить об ошибке"},*/
+            new BotCommand {Command = Text.start, Description = "Запуск бота"},
+            new BotCommand {Command = Text.menu, Description = "Показать меню"},
+            new BotCommand {Command = Text.help, Description = "Показать информацию"},
+            /*new BotCommand {Command = "/error", Description = "Сообщить об ошибке"},*/
         };
 
-        public static void Main(string[] args)
+        public static async Task Main(string[] args)
         {
             Logs.LogOut("Bot started");
             
@@ -42,8 +43,8 @@ namespace CardCollector
             TimerTask.SetupAll();
             
             var cts = new CancellationTokenSource();
+            await Client.SetMyCommandsAsync(_commands, BotCommandScope.AllPrivateChats(), cancellationToken: cts.Token);
             Client.StartReceiving(HandleUpdateAsync, HandleErrorAsync, cancellationToken: cts.Token);
-            Client.SetMyCommandsAsync(_commands, BotCommandScope.AllPrivateChats(), cancellationToken: cts.Token);
 
             _end.WaitOne();
             Logs.LogOut("Stopping program");

+ 4 - 8
CardCollector/Commands/CallbackQuery/BuyCoins.cs

@@ -1,9 +1,7 @@
 using System.Threading.Tasks;
-using CardCollector.Commands.Message;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
-using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
 
 namespace CardCollector.Commands.CallbackQuery
@@ -14,14 +12,12 @@ namespace CardCollector.Commands.CallbackQuery
 
         public override async Task Execute()
         {
-            EnterGemsExchange.AddToQueue(User.Id);
-            var module = User.Session.GetModule<ShopModule>();
             await MessageController.EditMessage(User,
-                $"{Messages.exchange_mesage}" +
+                $"{Messages.exchange_mesage}" +/*
                 $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
-                $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +
-                $"\n\n{Messages.enter_exchange_sum}",
-                Keyboard.BuyCoinsKeyboard);
+                $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +*/
+                $"\n\n{Messages.choose_exchange_sum}",
+                Keyboard.BuyCoinsKeyboard());
         }
 
         public BuyCoins() { }

+ 3 - 5
CardCollector/Commands/CallbackQuery/BuyGems.cs

@@ -3,19 +3,17 @@ using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
-using Telegram.Bot.Types.Payments;
 
 namespace CardCollector.Commands.CallbackQuery
 {
     public class BuyGems : CallbackQueryCommand
     {
         protected override string CommandText => Command.buy_gems;
-        
+        protected override bool AddToStack => true;
+
         public override async Task Execute()
         {
-            await MessageController.SendInvoice(User, Text.gems_title, Text.gems_description, 
-                Command.buy_gems_item, new[] {new LabeledPrice(Text.gems_label50, 100)},
-                900000, new [] {400, 900, 2400, 4900}, Keyboard.BuyGemsKeyboard);
+            await MessageController.EditMessage(User, Messages.buy_gems, Keyboard.BuyGems);
         }
 
         public BuyGems() { }

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

@@ -10,7 +10,8 @@ namespace CardCollector.Commands.CallbackQuery
     {
         protected override string CommandText => Command.buy_pack;
         protected override bool AddToStack => true;
-        
+        protected override bool ClearStickers => true;
+
         public override async Task Execute()
         {
             await MessageController.EditMessage(User, Messages.choose_option, Keyboard.ShopPacksKeyboard);

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

@@ -52,7 +52,7 @@ namespace CardCollector.Commands.CallbackQuery
                 await MessageController.EditMessage(User, $"{Messages.thanks_for_buying} {userPack.Count} {Text.packs} {packInfo.Author}", 
                     offerSpecial && !offerInfinite || (module.SelectedPosition?.Expired ?? false) || !canBuy
                     ? Keyboard.BackKeyboard
-                    : Keyboard.RepeatCommand(Text.buy_more, CallbackData));
+                    : Keyboard.BuyShopItem(CallbackData));
             }
         }
 

+ 12 - 1
CardCollector/Commands/CallbackQuery/CollectIncome.cs

@@ -1,6 +1,7 @@
 using System.Threading.Tasks;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
 using CardCollector.Resources;
 using Telegram.Bot.Types;
 
@@ -16,7 +17,17 @@ namespace CardCollector.Commands.CallbackQuery
             await MessageController.AnswerCallbackQuery(User, CallbackQueryId, 
                 $"{Messages.you_collected} {result}{Text.coin} " +
                 $"\n\n{Messages.your_cash}: {User.Cash.Coins}{Text.coin} {User.Cash.Gems}{Text.gem}", true);
-            await MessageController.DeleteMessage(User, Update.CallbackQuery!.Message!.MessageId);
+            var expGoal = (await LevelDao.GetLevel(User.CurrentLevel.Level + 1))?.LevelExpGoal.ToString() ?? "∞";
+            var packsCount = await UserPacksDao.GetCount(User.Id);
+            /* Отправляем сообщение */
+            await MessageController.EditMessage(User, 
+                $"{User.Username}" +
+                $"\n{Messages.coins}: {User.Cash.Coins}{Text.coin}" +
+                $"\n{Messages.gems}: {User.Cash.Gems}{Text.gem}" +
+                $"\n{Messages.level}: {User.CurrentLevel.Level}" +
+                $"\n{Messages.current_exp}: {User.CurrentLevel.CurrentExp} / {expGoal}" +
+                $"\n{Messages.cash_capacity}: {User.Cash.MaxCapacity}{Text.coin}",
+                Keyboard.GetProfileKeyboard(User.PrivilegeLevel, packsCount));
         }
 
         public CollectIncome() { }

+ 30 - 0
CardCollector/Commands/CallbackQuery/ReturnFromAuction.cs

@@ -0,0 +1,30 @@
+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;
+
+namespace CardCollector.Commands.CallbackQuery
+{
+    public class ReturnFromAuction : CallbackQueryCommand
+    {
+        protected override string CommandText => Command.return_from_auction;
+        protected override bool ClearStickers => true;
+
+        public override async Task Execute()
+        {
+            var module = User.Session.GetModule<AuctionModule>();
+            var productInfo = await AuctionDao.GetProduct(module.SelectedPosition.Id);
+            await AuctionDao.DeleteRow(productInfo.Id);
+            await UserStickerRelationDao.AddSticker(User, module.SelectedSticker, productInfo.Count);
+            await MessageController.EditMessage(User,
+                string.Format(Messages.successfully_returned, productInfo.Count, module.SelectedSticker.Title),
+                Keyboard.BackKeyboard);
+        }
+
+        public ReturnFromAuction() { }
+        public ReturnFromAuction(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 9 - 3
CardCollector/Commands/CallbackQuery/SelectShopPack.cs

@@ -14,15 +14,21 @@ namespace CardCollector.Commands.CallbackQuery
         protected override bool AddToStack => true;
         protected override bool ClearStickers => true;
 
+        private const string PackStickerId = "CAACAgIAAxkBAAIWs2DuY4vB50ARmyRwsgABs_7o5weDaAAC-g4AAmq4cUtH6M1FoN4bxSAE";
+
         public override async  Task Execute()
         {
             var packId = int.Parse(CallbackData.Split('=')[1]);
             var packInfo = await PacksDao.GetById(packId);
             var module = User.Session.GetModule<ShopModule>();
             module.SelectedPack = packInfo;
-            var stickers = await StickerDao.GetListWhere(item => packId == 1 || item.PackId == packId);
-            var sticker = stickers[Utilities.rnd.Next(stickers.Count)];
-            await MessageController.SendSticker(User, sticker.Id, Keyboard.OfferKeyboard(module));
+            var stickerId = PackStickerId;
+            if (packId != 1)
+            {
+                var stickers = await StickerDao.GetListWhere(item => item.PackId == packId);
+                stickerId = stickers[Utilities.rnd.Next(stickers.Count)].Id;
+            }
+            await MessageController.SendSticker(User, stickerId, Keyboard.OfferKeyboard(module));
         }
 
         public SelectShopPack() { }

+ 29 - 0
CardCollector/Commands/CallbackQuery/SetExchangeSum.cs

@@ -0,0 +1,29 @@
+using System.Threading.Tasks;
+using CardCollector.Controllers;
+using CardCollector.DataBase.Entity;
+using CardCollector.Resources;
+using CardCollector.Session.Modules;
+using Telegram.Bot.Types;
+
+namespace CardCollector.Commands.CallbackQuery
+{
+    public class SetExchangeSum : CallbackQueryCommand
+    {
+        protected override string CommandText => Command.set_exchange_sum;
+
+        public override async Task Execute()
+        {
+            var module = User.Session.GetModule<ShopModule>();
+            module.EnteredExchangeSum = int.Parse(CallbackData.Split('=')[1]); 
+            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}" +
+                $"\n\n{Messages.confirm_exchange}",
+                Keyboard.BuyCoinsKeyboard(true));
+        }
+
+        public SetExchangeSum() { }
+        public SetExchangeSum(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 26 - 0
CardCollector/Commands/CallbackQuery/SetGemsSum.cs

@@ -0,0 +1,26 @@
+using System.Threading.Tasks;
+using CardCollector.Controllers;
+using CardCollector.DataBase.Entity;
+using CardCollector.Resources;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Payments;
+
+namespace CardCollector.Commands.CallbackQuery
+{
+    public class SetGemsSum : CallbackQueryCommand
+    {
+        protected override string CommandText => Command.set_gems_sum;
+        
+        public override async Task Execute()
+        {
+            var count = int.Parse(CallbackData.Split('=')[1]);
+            var label = string.Format(Text.gems_title, count, count/50);
+            var description = string.Format(Text.gems_description, count);
+            await MessageController.SendInvoice(User, label, description, Command.buy_gems_item, 
+                new[] {new LabeledPrice(label, count*2)}, Keyboard.BuyGemsKeyboard(count));
+        }
+
+        public SetGemsSum() { }
+        public SetGemsSum(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 3 - 0
CardCollector/Commands/CallbackQueryCommand.cs

@@ -62,6 +62,9 @@ namespace CardCollector.Commands
             new SelectShopPack(),
             new Alerts(),
             new Settings(),
+            new SetExchangeSum(),
+            new SetGemsSum(),
+            new ReturnFromAuction(),
         };
 
         /* Метод, создающий объекты команд исходя из полученного обновления */

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

@@ -21,7 +21,7 @@ namespace CardCollector.Commands.ChosenInlineResult
             module.SelectedPosition = product;
             var discount = 1.0 - await User.AuctionDiscount() / 100.0;
             await MessageController.EditMessage(User, sticker.ToString(module.MaxCount), 
-                Keyboard.GetStickerKeyboard(User.Session, discount));
+                Keyboard.GetAuctionProductKeyboard(module, discount, User.Id == product.Trader));
         }
 
         public SelectTrader() { }

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

@@ -17,7 +17,7 @@ namespace CardCollector.Commands.ChosenInlineResult
             if (await dailyTask.Execute(User))
             {
                 await dailyTask.GiveReward(User);
-                await MessageController.EditMessage(User, Messages.pack_prize);
+                await MessageController.EditMessage(User, Messages.pack_prize, Keyboard.MyPacks);
             }
         }
 

+ 3 - 1
CardCollector/Commands/InlineQuery/ShowCombineStickers.cs

@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System.Linq;
+using System.Threading.Tasks;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
@@ -17,6 +18,7 @@ namespace CardCollector.Commands.InlineQuery
             var module = User.Session.GetModule<CombineModule>();
             // Получаем список стикеров
             var stickersList = await User.GetStickersList(Query, module.Tier);
+            stickersList = stickersList.Except(module.CombineList.Keys);
             var results = stickersList.ToTelegramResults(Command.select_sticker);
             // Посылаем пользователю ответ на его запрос
             await MessageController.AnswerInlineQuery(InlineQueryId, results);

+ 2 - 2
CardCollector/Commands/Message/EnterGemsExchange.cs

@@ -23,7 +23,7 @@ namespace CardCollector.Commands.Message
                     $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
                     $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +
                     $"\n\n{Messages.please_enter_integer}",
-                    Keyboard.BuyCoinsKeyboard);
+                    Keyboard.BuyCoinsKeyboard());
             else
             {
                 module.EnteredExchangeSum = sum; 
@@ -32,7 +32,7 @@ namespace CardCollector.Commands.Message
                     $"\n{Messages.gems_exchange_count} {module.EnteredExchangeSum}{Text.gem}" +
                     $"\n{Messages.coins_exchange_count} {module.EnteredExchangeSum * 150}{Text.coin}" +
                     $"\n\n{Messages.confirm_exchange}",
-                    Keyboard.BuyCoinsKeyboard);
+                    Keyboard.BuyCoinsKeyboard());
                 Queue.Remove(User.Id);
             }
         }

+ 20 - 0
CardCollector/Commands/Message/Help.cs

@@ -0,0 +1,20 @@
+using System.Threading.Tasks;
+using CardCollector.Controllers;
+using CardCollector.DataBase.Entity;
+using CardCollector.Resources;
+using Telegram.Bot.Types;
+
+namespace CardCollector.Commands.Message
+{
+    public class Help : MessageCommand
+    {
+        protected override string CommandText => Text.help;
+        public override async Task Execute()
+        {
+            await MessageController.EditMessage(User, Messages.help);
+        }
+
+        public Help() { }
+        public Help(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 2 - 1
CardCollector/Commands/Message/Menu.cs

@@ -13,8 +13,9 @@ namespace CardCollector.Commands.Message
 
         public override async Task Execute()
         {
+            await User.ClearChat();
             /* Отправляем пользователю сообщение со стандартной клавиатурой */
-            await MessageController.SendMessage(User, Messages.main_menu, Keyboard.Menu, ParseMode.Html, false);
+            await MessageController.SendMessage(User, Messages.main_menu, Keyboard.Menu, ParseMode.Html);
         }
 
         public Menu() { }

+ 2 - 1
CardCollector/Commands/Message/Profile.cs

@@ -21,6 +21,7 @@ namespace CardCollector.Commands.Message
             /* Подсчитываем прибыль */
             var income = await User.Cash.CalculateIncome(User.Stickers);
             var expGoal = (await LevelDao.GetLevel(User.CurrentLevel.Level + 1))?.LevelExpGoal.ToString() ?? "∞";
+            var packsCount = await UserPacksDao.GetCount(User.Id);
             /* Отправляем сообщение */
             await MessageController.EditMessage(User, 
                 $"{User.Username}" +
@@ -29,7 +30,7 @@ namespace CardCollector.Commands.Message
                 $"\n{Messages.level}: {User.CurrentLevel.Level}" +
                 $"\n{Messages.current_exp}: {User.CurrentLevel.CurrentExp} / {expGoal}" +
                 $"\n{Messages.cash_capacity}: {User.Cash.MaxCapacity}{Text.coin}",
-                Keyboard.GetProfileKeyboard(income, User.PrivilegeLevel));
+                Keyboard.GetProfileKeyboard(User.PrivilegeLevel, packsCount, income));
         }
         
         public Profile() { }

+ 1 - 0
CardCollector/Commands/MessageCommand.cs

@@ -32,6 +32,7 @@ namespace CardCollector.Commands
             new Start(),
             // Команда "/menu"
             new Menu(),
+            new Help(),
             // Команда "Коллекция"
             new Collection(),
             // Команда "Магазин"

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

@@ -19,7 +19,7 @@ namespace CardCollector.Commands.PreCheckoutQuery
             await MessageController.EditMessage(User, Messages.thanks_for_buying_gems);
             if (User.Settings[UserSettingsEnum.ExpGain])
                 await MessageController.SendMessage(User, 
-                    $"{Messages.you_gained} {gemsCount * 2} {Text.exp} {Messages.buy_gems}");
+                    $"{Messages.you_gained} {gemsCount * 2} {Text.exp} {Messages.for_buy_gems}");
             await User.GiveExp(gemsCount * 2);
         }
 

+ 4 - 4
CardCollector/Controllers/MessageController.cs

@@ -190,16 +190,16 @@ namespace CardCollector.Controllers
         }
 
         public static async Task<Message> SendInvoice(UserEntity user, string title, string description, 
-            string payload, IEnumerable<LabeledPrice> prices, int maxTip = 0, IEnumerable<int> tips = null,
-            InlineKeyboardMarkup keyboard = null, Currency currency = Currency.USD)
+            string payload, IEnumerable<LabeledPrice> prices, InlineKeyboardMarkup keyboard = null, 
+            Currency currency = Currency.USD)
         {
             if (!user.IsBlocked)
                 try
                 {
                     await user.ClearChat();
                     var result = await Bot.Client.SendInvoiceAsync(user.ChatId, title, description, payload,
-                        AppSettings.PAYMENT_PROVIDER, currency.ToString(), prices, maxTip, tips,
-                        replyMarkup: keyboard, disableNotification: true);
+                        AppSettings.PAYMENT_PROVIDER, currency.ToString(), prices, replyMarkup: keyboard,
+                        disableNotification: true);
                     user.Session.Messages.Add(result.MessageId);
                     return result;
                 }

+ 2 - 2
CardCollector/DailyTasks/CustomTasks/SendStickers.cs

@@ -19,8 +19,8 @@ namespace CardCollector.DailyTasks.CustomTasks
             if (task.Progress == 0) return false;
             task.Progress--;
             if (user.Settings[UserSettingsEnum.DailyTaskProgress])
-                await MessageController.SendMessage(user,
-                    $"{Messages.send_sticker_progress}: {Goal - task.Progress} / {Goal}", addToList: false);
+                await MessageController.EditMessage(user,
+                    $"{Messages.send_sticker_progress}: {Goal - task.Progress} / {Goal}");
             return task.Progress == 0;
         }
 

+ 3 - 0
CardCollector/DataBase/BotDatabase.cs

@@ -24,7 +24,10 @@ namespace CardCollector.DataBase
         public static BotDatabase GetClassInstance(Type t)
         {
             if (!ClassInstances.ContainsKey(t))
+            {
                 ClassInstances.Add(t, new BotDatabase());
+                ClassInstances[t].Database.EnsureCreated();
+            }
             return ClassInstances[t];
         }
 

+ 1 - 1
CardCollector/DataBase/Entity/UserEntity.cs

@@ -77,7 +77,7 @@ namespace CardCollector.DataBase.Entity
                 var levelReward = levelInfo.GetRewardInstance();
                 var message = $"{Messages.congratulation_new_level} {CurrentLevel.Level}" +
                               $"\n{await levelReward.GetReward(this)}";
-                await MessageController.SendMessage(this, message, addToList: false);
+                await MessageController.SendMessage(this, message, levelReward.RandomPacks > 0 ? Keyboard.MyPacks : null);
                 levelInfo = await LevelDao.GetLevel(CurrentLevel.Level + 1);
             }
         }

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

@@ -61,5 +61,18 @@ namespace CardCollector.DataBase.EntityDao
                 return await GetOne(userId, packId);
             }
         }
+
+        public static async Task<int> GetCount(long userId)
+        {
+            try
+            {
+                return await Table.Where(item => item.UserId == userId).SumAsync(item => item.Count);
+            }
+            catch (InvalidOperationException)
+            {
+                Thread.Sleep(Utilities.rnd.Next(30));
+                return await GetCount(userId);
+            }
+        }
     }
 }

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

@@ -339,6 +339,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to ACA.
+        /// </summary>
+        internal static string return_from_auction {
+            get {
+                return ResourceManager.GetString("return_from_auction", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to ABF.
         /// </summary>
@@ -402,6 +411,24 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to ABY.
+        /// </summary>
+        internal static string set_exchange_sum {
+            get {
+                return ResourceManager.GetString("set_exchange_sum", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ABZ.
+        /// </summary>
+        internal static string set_gems_sum {
+            get {
+                return ResourceManager.GetString("set_gems_sum", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to ABW.
         /// </summary>

+ 9 - 0
CardCollector/Resources/Command.resx

@@ -153,4 +153,13 @@
     <data name="alerts" xml:space="preserve">
         <value>ABX</value>
     </data>
+    <data name="set_exchange_sum" xml:space="preserve">
+        <value>ABY</value>
+    </data>
+    <data name="set_gems_sum" xml:space="preserve">
+        <value>ABZ</value>
+    </data>
+    <data name="return_from_auction" xml:space="preserve">
+        <value>ACA</value>
+    </data>
 </root>

+ 78 - 25
CardCollector/Resources/Keyboard.cs

@@ -26,10 +26,32 @@ namespace CardCollector.Resources
             new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
         });
 
-        public static readonly InlineKeyboardMarkup BuyCoinsKeyboard = new(new[]
+        public static InlineKeyboardMarkup BuyCoinsKeyboard(bool confirmButton = false)
         {
-            new[] {InlineKeyboardButton.WithCallbackData(Text.confirm_exchange, Command.confirm_exchange)},
-            new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
+            var keyboard = new List<InlineKeyboardButton[]>
+            {
+                new[]
+                {//TODO исправить суммы монет
+                    InlineKeyboardButton.WithCallbackData($"100{Text.coin}", $"{Command.set_exchange_sum}=100"),
+                    InlineKeyboardButton.WithCallbackData($"300{Text.coin}", $"{Command.set_exchange_sum}=300"),
+                    InlineKeyboardButton.WithCallbackData($"700{Text.coin}", $"{Command.set_exchange_sum}=700")
+                }
+            };
+            if (confirmButton) keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData(Text.confirm_exchange,
+                Command.confirm_exchange)});
+            keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)});
+            return new InlineKeyboardMarkup(keyboard);
+        }
+
+        public static readonly InlineKeyboardMarkup BuyGems = new(new[]
+        {
+            new[]
+            {
+                InlineKeyboardButton.WithCallbackData($"100{Text.gem}", $"{Command.set_gems_sum}=100"),
+                InlineKeyboardButton.WithCallbackData($"300{Text.gem}", $"{Command.set_gems_sum}=300"),
+                InlineKeyboardButton.WithCallbackData($"700{Text.gem}", $"{Command.set_gems_sum}=700")
+            },
+            new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)}
         });
 
         public static readonly InlineKeyboardMarkup EndStickerUpload = new(new[]
@@ -44,6 +66,11 @@ namespace CardCollector.Resources
             new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
         });
 
+        public static InlineKeyboardMarkup MyPacks = new(new[]
+        {
+            InlineKeyboardButton.WithCallbackData(Text.open_packs, Command.my_packs)
+        });
+        
         public static InlineKeyboardMarkup Alerts(UserSettings settings)
         {
             var keyboard = new List<InlineKeyboardButton[]>
@@ -144,11 +171,14 @@ namespace CardCollector.Resources
         });
 
         /* Клавиатура для покупок */
-        public static readonly InlineKeyboardMarkup BuyGemsKeyboard = new (new[]
+        public static InlineKeyboardMarkup BuyGemsKeyboard(int count)
         {
-            new[] {InlineKeyboardButton.WithPayment(Text.buy_gems_button)},
-            new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
-        });
+            return new InlineKeyboardMarkup(new[]
+            {
+                new[] {InlineKeyboardButton.WithPayment($"{Text.buy} {count}{Text.gem} {Text.per} ${count/50}")},
+                new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
+            });
+        }
 
         /* Клавиатура с отменой и выставлением */
         public static readonly InlineKeyboardMarkup AuctionPutCancelKeyboard = new (new[]
@@ -296,18 +326,28 @@ namespace CardCollector.Resources
             });
         }
 
-        public static InlineKeyboardMarkup GetAuctionProductKeyboard(AuctionModule module, double discount)
+        public static InlineKeyboardMarkup GetAuctionProductKeyboard(AuctionModule module, double discount, bool owner)
         {
             var price = (int)(module.Price * module.Count * discount);
-            return new InlineKeyboardMarkup(new[] {
-                new[] {InlineKeyboardButton.WithCallbackData($"{Text.buy} ({module.Count}) {price}{Text.gem}", Command.confirm_buying)},
-                new[]
+            var keyboard = new List<InlineKeyboardButton[]>();
+            if (owner)
+                keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData(Text.return_from_auction, 
+                    Command.return_from_auction)});
+            else
+            {
+                keyboard.AddRange(new []
                 {
-                    InlineKeyboardButton.WithCallbackData(Text.minus, $"{Command.count}={Text.minus}"),
-                    InlineKeyboardButton.WithCallbackData(Text.plus, $"{Command.count}={Text.plus}"),
-                },
-                new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
-            });
+                    new[] {InlineKeyboardButton.WithCallbackData($"{Text.buy} ({module.Count}) {price}{Text.gem}", 
+                        Command.confirm_buying)},
+                    new[]
+                    {
+                        InlineKeyboardButton.WithCallbackData(Text.minus, $"{Command.count}={Text.minus}"),
+                        InlineKeyboardButton.WithCallbackData(Text.plus, $"{Command.count}={Text.plus}"),
+                    },
+                });
+            }
+            keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)});
+            return new InlineKeyboardMarkup(keyboard);
         }
 
         public static InlineKeyboardMarkup GetStickerKeyboard(StickerEntity stickerInfo)
@@ -329,11 +369,10 @@ namespace CardCollector.Resources
             });
         }
 
-        public static InlineKeyboardMarkup GetStickerKeyboard(UserSession session, double discount = 1.0)
+        public static InlineKeyboardMarkup GetStickerKeyboard(UserSession session)
         {
             return session.State switch
             {
-                UserState.ProductMenu => GetAuctionProductKeyboard(session.GetModule<AuctionModule>(), discount),
                 UserState.AuctionMenu => GetAuctionStickerKeyboard(),
                 UserState.CombineMenu => GetCombineStickerKeyboard(session.GetModule<CombineModule>()),
                 UserState.CollectionMenu => GetCollectionStickerKeyboard(session.GetModule<CollectionModule>()),
@@ -372,19 +411,23 @@ namespace CardCollector.Resources
         }
 
         /* Клавиатура, отображаемая вместе с сообщением профиля */
-        public static InlineKeyboardMarkup GetProfileKeyboard(int income, int privilegeLevel)
+        public static InlineKeyboardMarkup GetProfileKeyboard(int privilegeLevel, int packsCount, int income = 0)
         {
-            var keyboard = new List<InlineKeyboardButton[]> {
-                new[] {InlineKeyboardButton.WithCallbackData($"{Text.collect} {income}{Text.coin}", Command.collect_income)},
+            var keyboard = new List<InlineKeyboardButton[]>();
+            if (income > 0)
+                keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData($"{Text.collect} {income}{Text.coin}",
+                    Command.collect_income)});
+            keyboard.AddRange(new []
+            {
                 new[] {InlineKeyboardButton.WithCallbackData(Text.daily_tasks, Command.daily_tasks)},
                 new[] {
                     InlineKeyboardButton.WithCallbackData(Text.settings, Command.settings),
-                    InlineKeyboardButton.WithCallbackData(Text.my_packs, Command.my_packs),
-                },
-            };
+                    InlineKeyboardButton.WithCallbackData($"{Text.my_packs} {(packsCount > 0 ? Text.gift : "")}",
+                        Command.my_packs)
+                }
+            });
             if (privilegeLevel > 2) keyboard.Add(
                 new[] {InlineKeyboardButton.WithCallbackData(Text.control_panel, Command.control_panel)});
-            keyboard.Add(new[] {InlineKeyboardButton.WithCallbackData(Text.back, Command.back)});
             return new InlineKeyboardMarkup(keyboard);
         }
 
@@ -459,5 +502,15 @@ namespace CardCollector.Resources
                 new []{InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
             });
         }
+
+        public static InlineKeyboardMarkup BuyShopItem(string callbackData)
+        {
+            return new InlineKeyboardMarkup(new[]
+            {
+                new []{InlineKeyboardButton.WithCallbackData(Text.buy_more, callbackData)},
+                new []{InlineKeyboardButton.WithCallbackData(Text.open_packs, Command.my_packs)},
+                new []{InlineKeyboardButton.WithCallbackData(Text.back, Command.back)},
+            });
+        }
     }
 }

+ 50 - 5
CardCollector/Resources/Messages.Designer.cs

@@ -124,7 +124,9 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to за покупку алмазов в магазине.
+        ///   Looks up a localized string similar to Покупка алмазов производится по курсу $1 = 50💎
+        ///
+        ///Выберите одну из опций ниже:.
         /// </summary>
         internal static string buy_gems {
             get {
@@ -177,6 +179,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Выберите желаемое количество монет:.
+        /// </summary>
+        internal static string choose_exchange_sum {
+            get {
+                return ResourceManager.GetString("choose_exchange_sum", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Выберите одну из опций ниже.
         /// </summary>
@@ -465,6 +476,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to за покупку алмазов в магазине.
+        /// </summary>
+        internal static string for_buy_gems {
+            get {
+                return ResourceManager.GetString("for_buy_gems", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Алмазы.
         /// </summary>
@@ -483,6 +503,16 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Подробное руководство по использованию бота ниже:
+        ///https://telegra.ph/help-11-04-4.
+        /// </summary>
+        internal static string help {
+            get {
+                return ResourceManager.GetString("help", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Уровень.
         /// </summary>
@@ -582,7 +612,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Поздравляем! Вы получили случайный пак! Открыть его можно во вкладке профиля..
+        ///   Looks up a localized string similar to Поздравляем! Вы получили обычный пак! Открыть его можно во вкладке профиля..
         /// </summary>
         internal static string pack_prize {
             get {
@@ -591,7 +621,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to У вас недостаточно паков.
+        ///   Looks up a localized string similar to У вас нет паков.
         /// </summary>
         internal static string packs_count_zero {
             get {
@@ -636,7 +666,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Случайный пак.
+        ///   Looks up a localized string similar to Обычный пак.
         /// </summary>
         internal static string random_packs {
             get {
@@ -717,7 +747,13 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Добро пожаловать! Этот бот позволяет вам коллекционировать стикеры. Вы можете выбрать одну из опций ниже. Напишите /help, чтобы получить подробную справку..
+        ///   Looks up a localized string similar to Добро пожаловать! Этот бот позволяет вам коллекционировать стикеры. Вы можете выбрать одну из опций ниже.
+        ///
+        ///Для того, чтобы получить стартовый набор стикеров, нажмите &quot;Магазин&quot; -&gt; &quot;0💰&quot;
+        ///После этого их можно открыть, нажав:
+        ///&quot;Профиль&quot; -&gt; &quot;Мои паки&quot; -&gt; &quot;Открыть обычный пак&quot;
+        ///            
+        ///Напишите /help, чтобы получить подробную справку..
         /// </summary>
         internal static string start_message {
             get {
@@ -734,6 +770,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Вы успешно вернули {0} стикеров {1} с аукциона!.
+        /// </summary>
+        internal static string successfully_returned {
+            get {
+                return ResourceManager.GetString("successfully_returned", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Товар успешно попал на аукцион.
         /// </summary>

+ 27 - 6
CardCollector/Resources/Messages.resx

@@ -19,7 +19,13 @@
         <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
     </resheader>
     <data name="start_message" xml:space="preserve">
-        <value>Добро пожаловать! Этот бот позволяет вам коллекционировать стикеры. Вы можете выбрать одну из опций ниже. Напишите /help, чтобы получить подробную справку.</value>
+        <value>Добро пожаловать! Этот бот позволяет вам коллекционировать стикеры. Вы можете выбрать одну из опций ниже.
+
+Для того, чтобы получить стартовый набор стикеров, нажмите "Магазин" -&gt; "0💰"
+После этого их можно открыть, нажав:
+"Профиль" -&gt; "Мои паки" -&gt; "Открыть обычный пак"
+            
+Напишите /help, чтобы получить подробную справку.</value>
     </data>
     <data name="current_filters" xml:space="preserve">
         <value>Текущие примененные фильтры</value>
@@ -154,7 +160,7 @@
         <value>У вас сейчас:</value>
     </data>
     <data name="random_packs" xml:space="preserve">
-        <value>Случайный пак</value>
+        <value>Обычный пак</value>
     </data>
     <data name="author_pack" xml:space="preserve">
         <value>Пак художника</value>
@@ -169,7 +175,7 @@
         <value>Поздравляем! Вы получили стикер:</value>
     </data>
     <data name="packs_count_zero" xml:space="preserve">
-        <value>У вас недостаточно паков</value>
+        <value>У вас нет паков</value>
     </data>
     <data name="page_not_found" xml:space="preserve">
         <value>Страница не найдена</value>
@@ -195,7 +201,7 @@
 4 - 0.7%</value>
     </data>
     <data name="pack_prize" xml:space="preserve">
-        <value>Поздравляем! Вы получили случайный пак! Открыть его можно во вкладке профиля.</value>
+        <value>Поздравляем! Вы получили обычный пак! Открыть его можно во вкладке профиля.</value>
     </data>
     <data name="you_already_use_this_offer" xml:space="preserve">
         <value>Вы уже воспользовались данным предложением!</value>
@@ -269,7 +275,7 @@
 1 - Увеличивает копилку на 200 монет
 2 - Пользователь получает 25% алмазов к своему кошельку
 3 - Скидка на аукционе 5%
-4 - Случайный пак раз в 5 дней
+4 - Обычный пак раз в 5 дней
 5 - Случайный стикер 2 тира раз в 3 дня
 6 - Случайный стикер 1 тира раз в 3 дня</value>
     </data>
@@ -297,7 +303,7 @@
     <data name="you_can_add_bot_to_conversation" xml:space="preserve">
         <value>Чтобы увеличить получаемый опыт, Вы можете добавить бота в беседу.</value>
     </data>
-    <data name="buy_gems" xml:space="preserve">
+    <data name="for_buy_gems" xml:space="preserve">
         <value>за покупку алмазов в магазине</value>
     </data>
     <data name="count_sends_per_day" xml:space="preserve">
@@ -321,4 +327,19 @@
     <data name="users_top_exp" xml:space="preserve">
         <value>🧪&lt;b&gt;Топ пользователей по опыту&lt;/b&gt;🧪</value>
     </data>
+    <data name="help" xml:space="preserve">
+        <value>Подробное руководство по использованию бота ниже:
+https://telegra.ph/help-11-04-4</value>
+    </data>
+    <data name="choose_exchange_sum" xml:space="preserve">
+        <value>Выберите желаемое количество монет:</value>
+    </data>
+    <data name="buy_gems" xml:space="preserve">
+        <value>Покупка алмазов производится по курсу $1 = 50💎
+
+Выберите одну из опций ниже:</value>
+    </data>
+    <data name="successfully_returned" xml:space="preserve">
+        <value>Вы успешно вернули {0} стикеров {1} с аукциона!</value>
+    </data>
 </root>

+ 28 - 28
CardCollector/Resources/Text.Designer.cs

@@ -214,7 +214,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Случайный пак.
+        ///   Looks up a localized string similar to Обычный пак.
         /// </summary>
         internal static string buy_random {
             get {
@@ -222,15 +222,6 @@ namespace CardCollector.Resources {
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Отмена.
-        /// </summary>
-        internal static string cancel {
-            get {
-                return ResourceManager.GetString("cancel", resourceCulture);
-            }
-        }
-        
         /// <summary>
         ///   Looks up a localized string similar to Размер копилки увеличен:.
         /// </summary>
@@ -304,7 +295,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Топ игроков по опыту.
+        ///   Looks up a localized string similar to Топ-5 по опыту.
         /// </summary>
         internal static string daily_exp_top {
             get {
@@ -313,7 +304,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Прогресс еж. заданий.
+        ///   Looks up a localized string similar to Прогр. еж. задания.
         /// </summary>
         internal static string daily_task_progress {
             get {
@@ -322,7 +313,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Ежедневные задания.
+        ///   Looks up a localized string similar to Еж. задания.
         /// </summary>
         internal static string daily_tasks {
             get {
@@ -412,7 +403,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Получение опыта.
+        ///   Looks up a localized string similar to Пол. опыта.
         /// </summary>
         internal static string exp_gain {
             get {
@@ -439,7 +430,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to После покупки вы получите 50 алмазов на свой счет. Вы также можете оставить чаевые. Вы получите алмазы в рассчете 50💎 за $1.
+        ///   Looks up a localized string similar to После покупки вы получите {0} алмазов на свой счет..
         /// </summary>
         internal static string gems_description {
             get {
@@ -448,16 +439,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to 50💎 за $1.
-        /// </summary>
-        internal static string gems_label50 {
-            get {
-                return ResourceManager.GetString("gems_label50", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to 50💎 за $1.
+        ///   Looks up a localized string similar to {0}💎 за ${1}.
         /// </summary>
         internal static string gems_title {
             get {
@@ -583,7 +565,16 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Открыть случайный пак.
+        ///   Looks up a localized string similar to Открыть паки.
+        /// </summary>
+        internal static string open_packs {
+            get {
+                return ResourceManager.GetString("open_packs", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Открыть обычный пак.
         /// </summary>
         internal static string open_random {
             get {
@@ -628,7 +619,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Наполнение копилки.
+        ///   Looks up a localized string similar to Наполн. копилки.
         /// </summary>
         internal static string piggy_bank_capacity {
             get {
@@ -699,6 +690,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Вернуть с аукциона.
+        /// </summary>
+        internal static string return_from_auction {
+            get {
+                return ResourceManager.GetString("return_from_auction", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Выбрать.
         /// </summary>
@@ -826,7 +826,7 @@ namespace CardCollector.Resources {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Эффекты стикеров.
+        ///   Looks up a localized string similar to Эфф. стикеров.
         /// </summary>
         internal static string sticker_effects {
             get {

+ 16 - 16
CardCollector/Resources/Text.resx

@@ -30,9 +30,6 @@
     <data name="sort" xml:space="preserve">
         <value>Сортировка</value>
     </data>
-    <data name="cancel" xml:space="preserve">
-        <value>Отмена</value>
-    </data>
     <data name="show_stickers" xml:space="preserve">
         <value>Показать стикеры</value>
     </data>
@@ -172,13 +169,13 @@
         <value>Панель управления</value>
     </data>
     <data name="daily_tasks" xml:space="preserve">
-        <value>Ежедневные задания</value>
+        <value>Еж. задания</value>
     </data>
     <data name="my_packs" xml:space="preserve">
         <value>Мои паки</value>
     </data>
     <data name="open_random" xml:space="preserve">
-        <value>Открыть случайный пак</value>
+        <value>Открыть обычный пак</value>
     </data>
     <data name="open_author" xml:space="preserve">
         <value>Открыть пак художника</value>
@@ -205,7 +202,7 @@
         <value>В подарок вы получите</value>
     </data>
     <data name="buy_random" xml:space="preserve">
-        <value>Случайный пак</value>
+        <value>Обычный пак</value>
     </data>
     <data name="buy_author" xml:space="preserve">
         <value>Пак художника</value>
@@ -214,13 +211,10 @@
         <value>Информация</value>
     </data>
     <data name="gems_title" xml:space="preserve">
-        <value>50💎 за $1</value>
+        <value>{0}💎 за ${1}</value>
     </data>
     <data name="gems_description" xml:space="preserve">
-        <value>После покупки вы получите 50 алмазов на свой счет. Вы также можете оставить чаевые. Вы получите алмазы в рассчете 50💎 за $1</value>
-    </data>
-    <data name="gems_label50" xml:space="preserve">
-        <value>50💎 за $1</value>
+        <value>После покупки вы получите {0} алмазов на свой счет.</value>
     </data>
     <data name="open_specific" xml:space="preserve">
         <value>Открыть авторский пак</value>
@@ -286,21 +280,27 @@
         <value>🔕</value>
     </data>
     <data name="sticker_effects" xml:space="preserve">
-        <value>Эффекты стикеров</value>
+        <value>Эфф. стикеров</value>
     </data>
     <data name="exp_gain" xml:space="preserve">
-        <value>Получение опыта</value>
+        <value>Пол. опыта</value>
     </data>
     <data name="daily_task_progress" xml:space="preserve">
-        <value>Прогресс еж. заданий</value>
+        <value>Прогр. еж. задания</value>
     </data>
     <data name="piggy_bank_capacity" xml:space="preserve">
-        <value>Наполнение копилки</value>
+        <value>Наполн. копилки</value>
     </data>
     <data name="daily_exp_top" xml:space="preserve">
-        <value>Топ игроков по опыту</value>
+        <value>Топ-5 по опыту</value>
     </data>
     <data name="packs" xml:space="preserve">
         <value>паков</value>
     </data>
+    <data name="open_packs" xml:space="preserve">
+        <value>Открыть паки</value>
+    </data>
+    <data name="return_from_auction" xml:space="preserve">
+        <value>Вернуть с аукциона</value>
+    </data>
 </root>

+ 9 - 2
CardCollector/Session/Modules/CombineModule.cs

@@ -14,9 +14,16 @@ namespace CardCollector.Session.Modules
         
         public int CalculateCombinePrice()
         {
-            var coinsSum = CombineList.Sum(pair => 1440 / pair.Key.IncomeTime * pair.Key.Income * pair.Value);
+            /*var coinsSum = CombineList.Sum(pair => 1440 / pair.Key.IncomeTime * pair.Key.Income * pair.Value);
             var multiplier = SelectedSticker.Tier * 0.25 + 1;
-            return (int)(coinsSum * multiplier);
+            return (int)(coinsSum * multiplier);*/
+            return Tier switch
+            {
+                1 => 200,
+                2 => 500,
+                3 => 1200,
+                _ => 0
+            };
         }
         
         public int CombineCount => CombineList.Values.Sum();

+ 1 - 1
CardCollector/StickerEffects/EffectTranslations.Designer.cs

@@ -88,7 +88,7 @@ namespace CardCollector.StickerEffects {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to За каждый такой стикер в коллекции, вы будете получать 1 случайный пак раз в 5 дней!.
+        ///   Looks up a localized string similar to За каждый такой стикер в коллекции, вы будете получать 1 обычный пак раз в 5 дней!.
         /// </summary>
         internal static string _4 {
             get {

+ 1 - 1
CardCollector/StickerEffects/EffectTranslations.resx

@@ -28,7 +28,7 @@
         <value>При наличии этого стикера, вы будете получать скидку к покупкам на аукционе в размере 5% (эффект не складывается)</value>
     </data>
     <data name="4" xml:space="preserve">
-        <value>За каждый такой стикер в коллекции, вы будете получать 1 случайный пак раз в 5 дней!</value>
+        <value>За каждый такой стикер в коллекции, вы будете получать 1 обычный пак раз в 5 дней!</value>
     </data>
     <data name="5" xml:space="preserve">
         <value>За каждый такой стикер в коллекции, вы будете получать 1 случайный стикер 2-го тира каждые 3 дня!</value>

+ 1 - 1
CardCollector/TimerTasks/PiggyBankAlert.cs

@@ -10,7 +10,7 @@ namespace CardCollector.TimerTasks
     public class PiggyBankAlert : TimerTask
     {
         protected override TimeSpan RunAt => Constants.DEBUG
-                ? new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes, DateTime.Now.TimeOfDay.Seconds + 1000)
+                ? new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes + 10, 0)
                 : new TimeSpan((DateTime.Now.TimeOfDay.Hours / 4 + 1) * 4, 0, 0);
         
         protected override async void TimerCallback(object o, ElapsedEventArgs e)