Browse Source

Shop structure and showing special offers

Tigran 3 years ago
parent
commit
9e9cd7f654

+ 3 - 3
CardCollector.sln.DotSettings.user

@@ -11,13 +11,13 @@
 	
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FDailyTasks_002FTitles/@EntryIndexedValue">False</s:Boolean>
 	
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FCommand/@EntryIndexedValue">False</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FCommand/@EntryIndexedValue">True</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_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">True</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=CardCollector_002FResources_002FText/@EntryIndexedValue">False</s:Boolean>
 	
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>

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

@@ -75,6 +75,8 @@ namespace CardCollector.Commands.CallbackQuery
             new ConfirmationSellingQuery(),
             /* Отмена в момент выбора "значения фильтра", не в самом меню */
             new BackToFiltersMenu(),
+            /* Отмена в момент выбора "значения фильтра", не в самом меню */
+            new SelectOfferCallback(),
             /* Очистка чата */
             new ClearChat(),
         };

+ 45 - 0
CardCollector/Commands/CallbackQuery/SelectOfferCallback.cs

@@ -0,0 +1,45 @@
+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 SelectOfferCallback : CallbackQuery
+    {
+        protected override string CommandText => Command.select_offer;
+        public override async Task Execute()
+        {
+            var offerId = int.Parse(CallbackData.Split('=')[1]);
+            var offerInfo = await ShopDao.GetById(offerId);
+            var packInfo = await PacksDao.GetById(offerInfo.PackId);
+            User.Session.GetModule<ShopModule>().SelectedPosition = offerInfo;
+            var message = $"{offerInfo.Title}" +
+                          $"\n{packInfo.Author}" +
+                          $"{(packInfo.Description != "" ? $"\n{packInfo.Description}" : "")}";
+            if (offerInfo.Discount > 0) message += $"\n{Text.discount}: {offerInfo.Discount}%";
+            if (offerInfo.Count > 1) message += $"\n{Text.count}: {offerInfo.Count}{Text.items}";
+            if (offerInfo.AdditionalPrize != "") 
+                message += $"\n{Text.prize}: {await PrizeToString(offerInfo.AdditionalPrize)}";
+            if (offerInfo.TimeLimited) message += $"\n{Text.time_limit}: {offerInfo.TimeLimit}";
+            await MessageController.EditMessage(User, CallbackMessageId, message, Keyboard.OfferKeyboard(offerInfo));
+        }
+
+        private async Task<string> PrizeToString(string prize)
+        {
+            var data = prize.Split('=');
+            return data[0] switch
+            {
+                "tier" => $"{Text.sticker} {data[1]} {Text.tier2}",
+                "sticker" => $"{Text.sticker} {(await StickerDao.GetStickerByHash(data[1])).Title}",
+                _ => ""
+            };
+        }
+
+        public SelectOfferCallback() { }
+        public SelectOfferCallback(UserEntity user, Update update) : base(user, update) { }
+    }
+}

+ 0 - 2
CardCollector/Commands/InlineQuery/InlineQuery.cs

@@ -34,8 +34,6 @@ namespace CardCollector.Commands.InlineQuery
             new ShowCollectionStickers(),
             // Показать стикеры для комбинации
             new ShowCombineStickers(),
-            // Показать стикеры в магазине
-            new ShowShopStickers(),
             // Показать список продавцов
             new ShowTradersInBotChat(),
             // Показать стикеры в личных сообщениях с ботом для выбора или просмотра информации

+ 0 - 37
CardCollector/Commands/InlineQuery/ShowShopStickers.cs

@@ -1,37 +0,0 @@
-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.InlineQuery
-{
-    public class ShowShopStickers : InlineQuery
-    {
-        protected override string CommandText => "";
-        public override async Task Execute()
-        {
-            // Фильтр - введенная пользователем фраза
-            var filter = Update.InlineQuery!.Query;
-            // Получаем список стикеров
-            var stickersList = await ShopController.GetStickers(filter);
-            var results = User.Session.GetModule<FiltersModule>()
-                .ApplyTo(stickersList).ToTelegramResults(Command.select_sticker);
-            // Посылаем пользователю ответ на его запрос
-            await MessageController.AnswerInlineQuery(InlineQueryId, results);
-        }
-        
-        /* Команда пользователя удовлетворяет условию, если она вызвана
-         в личных сообщениях с ботом и пользователь в меню магазина */
-        protected internal override bool IsMatches(string command)
-        {
-            return User == null 
-                ? command.Contains("Sender")
-                : User.Session.State == UserState.ShopMenu;
-        }
-
-        public ShowShopStickers() { }
-        public ShowShopStickers(UserEntity user, Update update) : base(user, update) { }
-    }
-}

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

@@ -37,8 +37,7 @@ namespace CardCollector.Commands.Message
                 // Команда "Коллекция"
                 new CollectionMessage(),
                 // Команда "Магазин"
-                // TODO переписать магазин
-                // new ShopMessage(),
+                new ShopMessage(),
                 // Команда "Аукцион"
                 new AuctionMessage(),
                 // Ожидание ввода эмоджи

+ 2 - 0
CardCollector/Commands/Message/TextMessage/AuctionMessage.cs

@@ -1,6 +1,7 @@
 using System.Threading.Tasks;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
+using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
 
 namespace CardCollector.Commands.Message.TextMessage
@@ -15,6 +16,7 @@ namespace CardCollector.Commands.Message.TextMessage
             await User.ClearChat();
             /* Переводим состояние пользователя в меню аукциона */
             User.Session.State = UserState.AuctionMenu;
+            User.Session.InitNewModule<AuctionModule>();
             /* Отображаем сообщение с фильтрами */
             await new ShowFiltersMenu(User, Update).Execute();
         }

+ 2 - 0
CardCollector/Commands/Message/TextMessage/CollectionMessage.cs

@@ -1,6 +1,7 @@
 using System.Threading.Tasks;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;
+using CardCollector.Session.Modules;
 using Telegram.Bot.Types;
 
 namespace CardCollector.Commands.Message.TextMessage
@@ -15,6 +16,7 @@ namespace CardCollector.Commands.Message.TextMessage
             await User.ClearChat();
             /* Переводим состояние пользователя в меню коллекции */
             User.Session.State = UserState.CollectionMenu;
+            User.Session.InitNewModule<CollectionModule>();
             /* Отображаем сообщение с фильтрами */
             await new ShowFiltersMenu(User, Update).Execute();
         }

+ 8 - 1
CardCollector/Commands/Message/TextMessage/ShopMessage.cs

@@ -1,6 +1,9 @@
 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.Message.TextMessage
@@ -15,7 +18,11 @@ namespace CardCollector.Commands.Message.TextMessage
             await User.ClearChat();
             /* Переводим состояние пользователя в меню магазина */
             User.Session.State = UserState.ShopMenu;
-            
+            User.Session.InitNewModule<ShopModule>();
+            var specialOffers = await ShopDao.GetSpecialPositions();
+            var message = await MessageController.SendMessage(User, Messages.shop_message, 
+                Keyboard.ShopKeyboard(specialOffers));
+            User.Session.Messages.Add(message.MessageId);
         }
         
         public ShopMessage() { }

+ 1 - 2
CardCollector/Commands/Message/TextMessage/ShowFiltersMenu.cs

@@ -1,5 +1,4 @@
-using System;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
 using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
 using CardCollector.Resources;

+ 0 - 23
CardCollector/Controllers/ShopController.cs

@@ -1,23 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using CardCollector.DataBase.Entity;
-using CardCollector.DataBase.EntityDao;
-
-namespace CardCollector.Controllers
-{
-    public static class ShopController
-    {
-        public static async Task<int> GetStickerCount(string stickerId)
-        {
-            var sticker = await ShopDao.GetSticker(stickerId);
-            return sticker.IsInfinite ? -1 : sticker.Count;
-        }
-        
-        public static async Task<List<StickerEntity>> GetStickers(string filter)
-        {
-            var result = await ShopDao.GetAllShopPositions(filter);
-            return result.ToList();
-        }
-    }
-}

+ 1 - 0
CardCollector/DataBase/CardCollectorDatabase.cs

@@ -66,6 +66,7 @@ namespace CardCollector.DataBase
         public DbSet<DailyTaskEntity> DailyTasks { get; set; }
         public DbSet<UsersPacksEntity> UsersPacks { get; set; }
         public DbSet<PackEntity> Packs { get; set; }
+        public DbSet<SpecialOfferUsers> SpecialOfferUsers { get; set; }
 
         
         /* Конфигурация подключения к БД */

+ 19 - 6
CardCollector/DataBase/Entity/ShopEntity.cs

@@ -1,4 +1,5 @@
-using System.ComponentModel.DataAnnotations;
+using System;
+using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
 
 namespace CardCollector.DataBase.Entity
@@ -6,10 +7,22 @@ namespace CardCollector.DataBase.Entity
     [Table("shop")]
     public class ShopEntity
     {
-        [Key]
-        [Column("id"), MaxLength(32)] public int Id { get; set; }
-        [Column("sticker_id"), MaxLength(127)] public string StickerId { get; set; }
-        [Column("count"), MaxLength(32)] public int Count { get; set; }
-        [Column("is_infinite"), MaxLength(11)] public bool IsInfinite { get; set; }
+        [Key] [Column("id"), MaxLength(32)] public int Id { get; set; }
+        [Column("pack_id"), MaxLength(32)] public int PackId { get; set; } = 0;
+        [Column("title"), MaxLength(256)] public string Title { get; set; } = "";
+        [Column("is_infinite"), MaxLength(11)] public bool IsInfinite { get; set; } = true;
+        [Column("count"), MaxLength(32)] public int Count { get; set; } = 1;
+        [Column("price_coins"), MaxLength(32)] public int PriceCoins { get; set; } = 1000;
+        [Column("price_gems"), MaxLength(32)] public int PriceGems { get; set; } = 80;
+        [Column("discount"), MaxLength(32)] public int Discount { get; set; } = 0;
+        [Column("time_limited"), MaxLength(32)] public bool TimeLimited { get; set; } = false;
+        [Column("time_limit"), MaxLength(32)] public DateTime TimeLimit { get; set; } = DateTime.Now;
+        [Column("additional_prize"), MaxLength(256)] public string AdditionalPrize { get; set; } = "";
+
+        [NotMapped] public bool IsSpecial => Count > 1 || Discount > 0 || TimeLimited || AdditionalPrize != "";
+        [NotMapped] public bool Expired => TimeLimited && TimeLimit < DateTime.Now;
+        [NotMapped] public int ResultPriceCoins => PriceCoins < 0 ? -1 : PriceCoins - PriceCoins * Discount / 100;
+        [NotMapped] public int ResultPriceGems => PriceGems < 0 ? -1 : PriceGems - PriceGems * Discount / 100;
+        
     }
 }

+ 14 - 0
CardCollector/DataBase/Entity/SpecialOfferUsers.cs

@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace CardCollector.DataBase.Entity
+{
+    [Table("special_offer_users")]
+    public class SpecialOfferUsers
+    {
+        [Key] [Column("id"), MaxLength(127)] public long Id { get; set; }
+        [Column("offer_id"), MaxLength(32)] public int OfferId { get; set; }
+        [Column("user_id"), MaxLength(127)] public long UserId { get; set; }
+        [Column("count"), MaxLength(32)] public int Count { get; set; } = 1;
+    }
+}

+ 10 - 12
CardCollector/DataBase/EntityDao/ShopDao.cs

@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using CardCollector.DataBase.Entity;
 using Microsoft.EntityFrameworkCore;
@@ -12,19 +10,19 @@ namespace CardCollector.DataBase.EntityDao
         private static readonly CardCollectorDatabase Instance = CardCollectorDatabase.GetSpecificInstance(typeof(ShopDao));
         private static readonly DbSet<ShopEntity> Table = Instance.Shop;
 
-        public static async Task<IEnumerable<StickerEntity>> GetAllShopPositions(string filter = "")
+        public static async Task<IEnumerable<ShopEntity>> GetShopPositions()
         {
-            var entityList = Table
-                .Where(e => e.Count > 0 || e.IsInfinite)
-                .Select(e => e.StickerId)
-                .ToHashSet();
-            var stickersList = await StickerDao.GetAll(filter);
-            return stickersList.Where(e => entityList.Contains(e.Id));
+            return await Table.WhereAsync(e => !e.IsSpecial);
+        }
+        
+        public static async Task<IEnumerable<ShopEntity>> GetSpecialPositions()
+        {
+            return await Table.WhereAsync(e => e.IsSpecial && !e.Expired);
         }
 
-        public static async Task<ShopEntity> GetSticker(string stickerId)
+        public static async Task<ShopEntity> GetById(int positionId)
         {
-            return await Table.FirstAsync(e => e.StickerId == stickerId);
+            return await Table.FirstAsync(e => e.Id == positionId);
         }
 
         public static async void DeleteRow(int productId)

+ 26 - 0
CardCollector/DataBase/EntityDao/SpecialOfferUsersDao.cs

@@ -0,0 +1,26 @@
+using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using Microsoft.EntityFrameworkCore;
+
+namespace CardCollector.DataBase.EntityDao
+{
+    public class SpecialOfferUsersDao
+    {
+        private static readonly CardCollectorDatabase Instance = CardCollectorDatabase.GetSpecificInstance(typeof(SpecialOfferUsersDao));
+        private static readonly DbSet<SpecialOfferUsers> Table = Instance.SpecialOfferUsers;
+
+        public static async Task<bool> NowUsed(long userId, int offerId)
+        {
+            return await Table.AnyAsync(e => e.UserId == userId && e.OfferId == offerId);
+        }
+
+        public static async Task AddNew(long userId, int offerId)
+        {
+            await Table.AddAsync(new SpecialOfferUsers
+            {
+                UserId = userId,
+                OfferId = offerId
+            });
+        }
+    }
+}

+ 13 - 5
CardCollector/Logs.cs

@@ -1,27 +1,35 @@
 using System;
-using System.Globalization;
+using System.IO;
+using CardCollector.Resources;
+// ReSharper disable ConditionIsAlwaysTrueOrFalse
 // ReSharper disable LocalizableElement
 
 namespace CardCollector
 {
     public static class Logs
     {
+        private static void Print(string message)
+        {
+            if (Constants.DEBUG) Console.WriteLine(message);
+            else File.AppendAllText($"Log {DateTime.Now.Date}.txt", message + Environment.NewLine);
+        }
+        
         public static void LogOut(object message)
         {
-            Console.WriteLine($"[INFO] [{DateTime.Now.ToString(CultureInfo.CurrentCulture)}] {message}");
+            Print($"[INFO] [{DateTime.Now.TimeOfDay.ToString()}] {message}");
         }
         public static void LogOutWarning(object message)
         {
-            Console.WriteLine($"[WARNING] [{DateTime.Now.ToString(CultureInfo.CurrentCulture)}] {message}");
+            Print($"[WARNING] [{DateTime.Now.TimeOfDay.ToString()}] {message}");
         }
         public static void LogOutError(object message)
         {
-            Console.WriteLine($"[ERROR] [{DateTime.Now.ToString(CultureInfo.CurrentCulture)}] {message}");
+            Print($"[ERROR] [{DateTime.Now.TimeOfDay.ToString()}] {message}");
         }
 
         public static void LogOutJson(object message)
         {
-            Console.WriteLine($"[JSON] [{DateTime.Now.ToString(CultureInfo.CurrentCulture)}] {Utilities.ToJson(message)}");
+            Print($"[JSON] [{DateTime.Now.TimeOfDay.ToString()}] {Utilities.ToJson(message)}");
         }
     }
 }

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

@@ -105,6 +105,42 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to ABI.
+        /// </summary>
+        internal static string buy_by_coins {
+            get {
+                return ResourceManager.GetString("buy_by_coins", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ABJ.
+        /// </summary>
+        internal static string buy_by_gems {
+            get {
+                return ResourceManager.GetString("buy_by_gems", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ABH.
+        /// </summary>
+        internal static string buy_gems {
+            get {
+                return ResourceManager.GetString("buy_gems", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ABG.
+        /// </summary>
+        internal static string buy_pack {
+            get {
+                return ResourceManager.GetString("buy_pack", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to AAF.
         /// </summary>
@@ -285,6 +321,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to ABF.
+        /// </summary>
+        internal static string select_offer {
+            get {
+                return ResourceManager.GetString("select_offer", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to AAV.
         /// </summary>

+ 15 - 0
CardCollector/Resources/Command.resx

@@ -117,4 +117,19 @@
     <data name="open_pack" xml:space="preserve">
         <value>ABE</value>
     </data>
+    <data name="select_offer" xml:space="preserve">
+        <value>ABF</value>
+    </data>
+    <data name="buy_pack" xml:space="preserve">
+        <value>ABG</value>
+    </data>
+    <data name="buy_gems" xml:space="preserve">
+        <value>ABH</value>
+    </data>
+    <data name="buy_by_coins" xml:space="preserve">
+        <value>ABI</value>
+    </data>
+    <data name="buy_by_gems" xml:space="preserve">
+        <value>ABJ</value>
+    </data>
 </root>

+ 31 - 2
CardCollector/Resources/Keyboard.cs

@@ -338,8 +338,7 @@ namespace CardCollector.Resources
         /* Клавиатура, отображаемая вместе с сообщением профиля */
         public static InlineKeyboardMarkup GetProfileKeyboard(int income, int privilegeLevel)
         {
-            var keyboard = new List<InlineKeyboardButton[]>
-            {
+            var keyboard = new List<InlineKeyboardButton[]> {
                 new[] {InlineKeyboardButton.WithCallbackData($"{Text.collect} {income}{Text.coin}", Command.collect_income)},
                 new[] {InlineKeyboardButton.WithCallbackData(Text.daily_tasks, Command.daily_tasks)},
                 new[] {InlineKeyboardButton.WithCallbackData(Text.my_packs, Command.my_packs)},
@@ -348,5 +347,35 @@ namespace CardCollector.Resources
                 new[] {InlineKeyboardButton.WithCallbackData(Text.control_panel, Command.control_panel)});
             return new InlineKeyboardMarkup(keyboard);
         }
+
+        public static InlineKeyboardMarkup ShopKeyboard(IEnumerable<ShopEntity> specialOffers)
+        {
+            var keyboard = new List<InlineKeyboardButton[]>();
+            foreach (var offer in specialOffers)
+                keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(offer.Title,
+                        $"{Command.select_offer}={offer.Id}")
+                });
+            keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(Text.buy_pack, Command.buy_pack)});
+            keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(Text.buy_gems, Command.buy_gems)});
+            keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(Text.cancel, Command.cancel)});
+            return new InlineKeyboardMarkup(keyboard);
+        }
+
+        public static InlineKeyboardMarkup OfferKeyboard(ShopEntity offerInfo)
+        {
+            var keyboard = new List<InlineKeyboardButton[]>();
+            if (offerInfo.PriceCoins >= 0)
+                keyboard.Add(new [] {
+                    InlineKeyboardButton.WithCallbackData($"{Text.buy} {offerInfo.ResultPriceCoins}{Text.coin}", 
+                        Command.buy_by_coins)
+                });
+            if (offerInfo.PriceGems >= 0)
+                keyboard.Add(new [] {
+                    InlineKeyboardButton.WithCallbackData($"{Text.buy} {offerInfo.ResultPriceGems}{Text.gem}", 
+                        Command.buy_by_gems)
+                });
+            keyboard.Add(new []{InlineKeyboardButton.WithCallbackData(Text.cancel, Command.cancel)});
+            return new InlineKeyboardMarkup(keyboard);
+        }
     }
 }

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

@@ -456,6 +456,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Выберите одну из опций ниже:.
+        /// </summary>
+        internal static string shop_message {
+            get {
+                return ResourceManager.GetString("shop_message", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Сортировка:.
         /// </summary>

+ 3 - 0
CardCollector/Resources/Messages.resx

@@ -192,4 +192,7 @@
     <data name="page_not_found" xml:space="preserve">
         <value>Страница не найдена</value>
     </data>
+    <data name="shop_message" xml:space="preserve">
+        <value>Выберите одну из опций ниже:</value>
+    </data>
 </root>

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

@@ -132,6 +132,24 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Купить алмазы.
+        /// </summary>
+        internal static string buy_gems {
+            get {
+                return ResourceManager.GetString("buy_gems", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Купить пак.
+        /// </summary>
+        internal static string buy_pack {
+            get {
+                return ResourceManager.GetString("buy_pack", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Отмена.
         /// </summary>
@@ -141,6 +159,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Карта.
+        /// </summary>
+        internal static string card {
+            get {
+                return ResourceManager.GetString("card", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to 💰.
         /// </summary>
@@ -231,6 +258,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Скидка.
+        /// </summary>
+        internal static string discount {
+            get {
+                return ResourceManager.GetString("discount", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Загрузить стикерпак.
         /// </summary>
@@ -402,6 +438,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to В подарок вы получите.
+        /// </summary>
+        internal static string prize {
+            get {
+                return ResourceManager.GetString("prize", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Профиль.
         /// </summary>
@@ -537,6 +582,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Тира.
+        /// </summary>
+        internal static string tier2 {
+            get {
+                return ResourceManager.GetString("tier2", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to ⏱.
         /// </summary>
@@ -546,6 +600,15 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Акция заканчивается.
+        /// </summary>
+        internal static string time_limit {
+            get {
+                return ResourceManager.GetString("time_limit", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to До.
         /// </summary>

+ 21 - 0
CardCollector/Resources/Text.resx

@@ -189,4 +189,25 @@
     <data name="stop_bot" xml:space="preserve">
         <value>Остановить</value>
     </data>
+    <data name="buy_pack" xml:space="preserve">
+        <value>Купить пак</value>
+    </data>
+    <data name="buy_gems" xml:space="preserve">
+        <value>Купить алмазы</value>
+    </data>
+    <data name="card" xml:space="preserve">
+        <value>Карта</value>
+    </data>
+    <data name="tier2" xml:space="preserve">
+        <value>Тира</value>
+    </data>
+    <data name="time_limit" xml:space="preserve">
+        <value>Акция заканчивается</value>
+    </data>
+    <data name="discount" xml:space="preserve">
+        <value>Скидка</value>
+    </data>
+    <data name="prize" xml:space="preserve">
+        <value>В подарок вы получите</value>
+    </data>
 </root>