Browse Source

Sticker bonus system

Tigran 3 years ago
parent
commit
3ab16af8f8

+ 2 - 2
CardCollector.sln.DotSettings.user

@@ -11,12 +11,12 @@
 	
 	<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">True</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_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>
 	

+ 3 - 0
CardCollector/Bot.cs

@@ -7,6 +7,7 @@ using CardCollector.DailyTasks;
 using CardCollector.DataBase;
 using CardCollector.DataBase.EntityDao;
 using CardCollector.Resources;
+using CardCollector.StickerEffects;
 using Telegram.Bot;
 using Telegram.Bot.Types;
 using CancellationTokenSource = System.Threading.CancellationTokenSource;
@@ -47,6 +48,8 @@ namespace CardCollector
             Utilities.SetUpTimer(Constants.DailyTaskAlert, DailyTaskAlert);
             /* Запускаем сброс ежедневных заданий */
             Utilities.SetUpTimer(Constants.DailyTaskReset, DailyTask.ResetTasks);
+            /* Запускаем таймер с эффектами стикеров */
+            Utilities.SetUpTimer(Constants.DailyStickerRewardCheck, EffectFunctions.RunAll);
             
             _end.WaitOne();
             Logs.LogOut("Stopping program");

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

@@ -25,6 +25,8 @@ namespace CardCollector.Commands.CallbackQuery
             else
             {
                 await auctionModule.SelectedPosition.BuyCard(auctionModule.Count);
+                var discount = 1.0 - await User.AuctionDiscount() / 100.0;
+                User.Cash.Gems -= (int)(auctionModule.Price * auctionModule.Count * discount);
                 if (!User.Stickers.ContainsKey(auctionModule.SelectedSticker.Md5Hash))
                     await UserStickerRelationDao.AddNew(User, auctionModule.SelectedSticker, auctionModule.Count);
                 else
@@ -33,7 +35,6 @@ namespace CardCollector.Commands.CallbackQuery
                         $"{Messages.you_collected} {await User.Cash.Payout(User.Stickers)}{Text.coin}");
                     User.Stickers[auctionModule.SelectedSticker.Md5Hash].Count += auctionModule.Count;
                 }
-                User.Cash.Gems -= auctionModule.Price * auctionModule.Count;
                 User.Session.ResetModule<AuctionModule>();
                 await User.ClearChat();
             }

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

@@ -13,7 +13,7 @@ namespace CardCollector.Commands.CallbackQuery
         public override async Task Execute()
         {
             var auctionModule = User.Session.GetModule<AuctionModule>();
-            var price = auctionModule.Price * auctionModule.Count;
+            var price = auctionModule.Price * auctionModule.Count ;
             if (price > User.Cash.Gems)
                 await MessageController.AnswerCallbackQuery(User, Update.CallbackQuery!.Id, Messages.not_enougth_gems);
             else

+ 2 - 0
CardCollector/DataBase/Entity/StickerEntity.cs

@@ -40,6 +40,8 @@ namespace CardCollector.DataBase.Entity
         
         /* Хеш id стикера для определения его в системе */
         [Column("md5hash"), MaxLength(40)] public string Md5Hash { get; set; }
+        
+        [Column("effect"), MaxLength(32)] public int Effect { get; set; }
 
         public override string ToString()
         {

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

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 using CardCollector.DataBase.EntityDao;
 using CardCollector.Resources;
 using CardCollector.Session;
-using Telegram.Bot.Types;
+using CardCollector.StickerEffects;
 
 namespace CardCollector.DataBase.Entity
 {
@@ -58,6 +58,11 @@ namespace CardCollector.DataBase.Entity
             return result;
         }
 
+        public async Task<int> AuctionDiscount()
+        {
+            return await AuctionDiscount5.IsApplied(Stickers) ? 5 : 0;
+        }
+
         public UserEntity()
         {
             Session = new UserSession(this);

+ 3 - 0
CardCollector/DataBase/Entity/UserStickerRelationEntity.cs

@@ -27,5 +27,8 @@ namespace CardCollector.DataBase.Entity
         
         /* MD5 хеш id стикера */
         [Column("short_hash"), MaxLength(40)] public string ShortHash { get; set; }
+        
+        /* дополнительные данные */
+        [Column("additional_data"), MaxLength(512)] public string AdditionalData { get; set; } = "";
     }
 }

+ 5 - 0
CardCollector/DataBase/EntityDao/UserDao.cs

@@ -103,5 +103,10 @@ namespace CardCollector.DataBase.EntityDao
         {
             return await Table.WhereAsync(callback);
         }
+
+        public static async Task<IEnumerable<UserEntity>> GetAll()
+        {
+            return await Table.ToListAsync();
+        }
     }
 }

+ 29 - 1
CardCollector/DataBase/EntityDao/UserStickerRelationDao.cs

@@ -1,8 +1,14 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using System.Threading.Tasks;
+using CardCollector.Controllers;
 using CardCollector.DataBase.Entity;
+using CardCollector.Resources;
+using CardCollector.StickerEffects;
 using Microsoft.EntityFrameworkCore;
+using Telegram.Bot.Types;
 
 namespace CardCollector.DataBase.EntityDao
 {
@@ -37,6 +43,28 @@ namespace CardCollector.DataBase.EntityDao
                 Count = count,
                 ShortHash = sticker.Md5Hash
             };
+            switch ((Effect)sticker.Effect)
+            {
+                case Effect.PiggyBank200:
+                    user.Cash.MaxCapacity += 200;
+                    user.Session.Messages.Add((await MessageController
+                        .SendMessage(user, Messages.effect_PiggyBank200)).MessageId);
+                    break;
+                case Effect.Diamonds25Percent:
+                    user.Cash.Gems += (int)(user.Cash.Gems * 0.25);
+                    user.Session.Messages.Add((await MessageController
+                        .SendMessage(user, Messages.effect_Diamonds25Percent)).MessageId);
+                    break;
+                case Effect.Random1Pack5Day:
+                    relation.AdditionalData = DateTime.Today.ToString(CultureInfo.CurrentCulture);
+                    break;
+                case Effect.RandomSticker1Tier3Day:
+                    relation.AdditionalData = DateTime.Today.ToString(CultureInfo.CurrentCulture);
+                    break;
+                case Effect.RandomSticker2Tier3Day:
+                    relation.AdditionalData = DateTime.Today.ToString(CultureInfo.CurrentCulture);
+                    break;
+            }
             var result = await Table.AddAsync(relation);
             user.Stickers.Add(sticker.Md5Hash, result.Entity);
             await Instance.SaveChangesAsync();

+ 10 - 0
CardCollector/Extensions.cs

@@ -77,6 +77,16 @@ namespace CardCollector
             return results;
         }
 
+        public static async Task<bool> AnyAsync<T>(
+            this IEnumerable<T> source, Func<T, Task<bool>> predicate)
+        {
+            foreach (var element in source)
+            {
+                if (await predicate(element)) return true;
+            }
+            return false;
+        }
+
         public static async Task<IEnumerable<TSource>> WhereAsync<TSource>(
             [NotNull] this IQueryable<TSource> source, 
             [NotNull] Func<TSource, bool> predicate,

+ 1 - 0
CardCollector/Resources/Constants.cs

@@ -28,5 +28,6 @@ namespace CardCollector.Resources
         /* Время оповещения и сброса ежедневных заданий */
         public static readonly TimeSpan DailyTaskAlert = DEBUG ? new TimeSpan(21, 0, 0) : new TimeSpan(12, 0, 0);
         public static readonly TimeSpan DailyTaskReset = DEBUG ? new TimeSpan(0, 13, 0) : new TimeSpan(0, 0, 0);
+        public static readonly TimeSpan DailyStickerRewardCheck = DEBUG ? new TimeSpan(0, 30, 0) : new TimeSpan(1, 0, 0);
     }
 }

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

@@ -294,6 +294,51 @@ namespace CardCollector.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Поздравляем! Вы получили +25% к своим алмазам!.
+        /// </summary>
+        internal static string effect_Diamonds25Percent {
+            get {
+                return ResourceManager.GetString("effect_Diamonds25Percent", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Поздравляем! Ваша копилка увеличена на 200!.
+        /// </summary>
+        internal static string effect_PiggyBank200 {
+            get {
+                return ResourceManager.GetString("effect_PiggyBank200", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Поздравляем! Вы получили паки в количестве.
+        /// </summary>
+        internal static string effect_Random1Pack5Day {
+            get {
+                return ResourceManager.GetString("effect_Random1Pack5Day", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Поздравляем! Вы получили следующие стикеры:.
+        /// </summary>
+        internal static string effect_RandomSticker1Tier3Day {
+            get {
+                return ResourceManager.GetString("effect_RandomSticker1Tier3Day", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Поздравляем! Вы получили следующие стикеры:.
+        /// </summary>
+        internal static string effect_RandomSticker2Tier3Day {
+            get {
+                return ResourceManager.GetString("effect_RandomSticker2Tier3Day", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Эмоция:.
         /// </summary>

+ 15 - 0
CardCollector/Resources/Messages.resx

@@ -224,4 +224,19 @@
     <data name="specific_packs" xml:space="preserve">
         <value>Авторских паков:</value>
     </data>
+    <data name="effect_PiggyBank200" xml:space="preserve">
+        <value>Поздравляем! Ваша копилка увеличена на 200!</value>
+    </data>
+    <data name="effect_Diamonds25Percent" xml:space="preserve">
+        <value>Поздравляем! Вы получили +25% к своим алмазам!</value>
+    </data>
+    <data name="effect_Random1Pack5Day" xml:space="preserve">
+        <value>Поздравляем! Вы получили паки в количестве</value>
+    </data>
+    <data name="effect_RandomSticker2Tier3Day" xml:space="preserve">
+        <value>Поздравляем! Вы получили следующие стикеры:</value>
+    </data>
+    <data name="effect_RandomSticker1Tier3Day" xml:space="preserve">
+        <value>Поздравляем! Вы получили следующие стикеры:</value>
+    </data>
 </root>

+ 19 - 0
CardCollector/StickerEffects/AuctionDiscount5.cs

@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+
+namespace CardCollector.StickerEffects
+{
+    public static class AuctionDiscount5
+    {
+        public static async Task<bool> IsApplied(Dictionary<string, UserStickerRelationEntity> stickers)
+        {
+            return await stickers.AnyAsync(async item =>
+            {
+                var stickerInfo = await StickerDao.GetById(item.Value.StickerId);
+                return stickerInfo.Effect == (int) Effect.AuctionDiscount5;
+            });
+        }
+    }
+}

+ 12 - 0
CardCollector/StickerEffects/Effect.cs

@@ -0,0 +1,12 @@
+namespace CardCollector.StickerEffects
+{
+    public enum Effect
+    {
+        PiggyBank200,
+        Diamonds25Percent,
+        AuctionDiscount5,
+        Random1Pack5Day,
+        RandomSticker2Tier3Day,
+        RandomSticker1Tier3Day
+    }
+}

+ 67 - 0
CardCollector/StickerEffects/EffectFunctions.cs

@@ -0,0 +1,67 @@
+using System.Threading.Tasks;
+using System.Timers;
+using CardCollector.Controllers;
+using CardCollector.DataBase.EntityDao;
+using CardCollector.Resources;
+
+namespace CardCollector.StickerEffects
+{
+    public static class EffectFunctions
+    {
+        public static async void RunAll(object o, ElapsedEventArgs e)
+        {
+            await GivePacks();
+            await GiveTier1();
+            await GiveTier2();
+        }
+
+        public static async Task GivePacks()
+        {
+            var users = await UserDao.GetAll();
+            foreach (var user in users)
+            {
+                var stickers = await UserStickerRelationDao.GetListById(user.Id);
+                var packsCount = await Random1Pack5Day.GetPacksCount(stickers);
+                var userPacks = await UsersPacksDao.GetUserPacks(user.Id);
+                userPacks.RandomCount += packsCount;
+                await MessageController.SendMessage(user, $"{Messages.effect_Random1Pack5Day} {packsCount}{Text.items}");
+            }
+        }
+
+        public static async Task GiveTier2()
+        {
+            var users = await UserDao.GetAll();
+            foreach (var user in users)
+            {
+                var stickers = await UserStickerRelationDao.GetListById(user.Id);
+                var stickerCount = await RandomSticker2Tier3Day.GetStickersCount(stickers);
+                var stickerList = await RandomSticker2Tier3Day.GenerateList(stickerCount);
+                var generatedMessage = "";
+                foreach (var (sticker, count) in stickerList)
+                {
+                    generatedMessage += $"\n{sticker.Title} {count}{Text.items}";
+                    await UserStickerRelationDao.AddNew(user, sticker, count);
+                }
+                await MessageController.SendMessage(user, $"{Messages.effect_RandomSticker2Tier3Day}{generatedMessage}");
+            }
+        }
+
+        public static async Task GiveTier1()
+        {
+            var users = await UserDao.GetAll();
+            foreach (var user in users)
+            {
+                var stickers = await UserStickerRelationDao.GetListById(user.Id);
+                var stickerCount = await RandomSticker1Tier3Day.GetStickersCount(stickers);
+                var stickerList = await RandomSticker1Tier3Day.GenerateList(stickerCount);
+                var generatedMessage = "";
+                foreach (var (sticker, count) in stickerList)
+                {
+                    generatedMessage += $"\n{sticker.Title} {count}{Text.items}";
+                    await UserStickerRelationDao.AddNew(user, sticker, count);
+                }
+                await MessageController.SendMessage(user, $"{Messages.effect_RandomSticker1Tier3Day}{generatedMessage}");
+            }
+        }
+    }
+}

+ 23 - 0
CardCollector/StickerEffects/Random1Pack5Day.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+
+namespace CardCollector.StickerEffects
+{
+    public static class Random1Pack5Day
+    {
+        public static int Interval = 5;
+
+        public static async Task<int> GetPacksCount(Dictionary<string, UserStickerRelationEntity> stickers)
+        {
+            var stickersWithEffect = (await StickerDao.GetListWhere(
+                item => item.Effect == (int) Effect.Random1Pack5Day)).Select(item => item.Md5Hash);
+            var userStickers = stickers.Values.Where(item => stickersWithEffect.Contains(item.ShortHash));
+            return userStickers.Sum(item => (DateTime.Today - Convert.ToDateTime(item.AdditionalData)).Days >= Interval 
+                ? item.Count : 0);
+        }
+    }
+}

+ 33 - 0
CardCollector/StickerEffects/RandomSticker1Tier3Day.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+
+namespace CardCollector.StickerEffects
+{
+    public class RandomSticker1Tier3Day
+    {
+        public static int Interval = 3;
+
+        public static async Task<int> GetStickersCount(Dictionary<string, UserStickerRelationEntity> stickers)
+        {
+            var stickersWithEffect = (await StickerDao.GetListWhere(
+                item => item.Effect == (int) Effect.RandomSticker1Tier3Day)).Select(item => item.Md5Hash);
+            var userStickers = stickers.Values.Where(item => stickersWithEffect.Contains(item.ShortHash));
+            return userStickers.Sum(item => (DateTime.Today - Convert.ToDateTime(item.AdditionalData)).Days >= Interval 
+                ? item.Count : 0);
+        }
+
+        public static async Task<Dictionary<StickerEntity, int>> GenerateList(int count)
+        {
+            var stickers = await StickerDao.GetListWhere(item => item.Tier == 1);
+            var rnd = new Random();
+            var result = new List<StickerEntity>();
+            for (var i = 0; i < count; i++)
+                result.Add(stickers[rnd.Next(stickers.Count)]);
+            return result.GroupBy(item => item).ToDictionary(item => item.Key, item => item.Count());
+        }
+    }
+}

+ 33 - 0
CardCollector/StickerEffects/RandomSticker2Tier3Day.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CardCollector.DataBase.Entity;
+using CardCollector.DataBase.EntityDao;
+
+namespace CardCollector.StickerEffects
+{
+    public class RandomSticker2Tier3Day
+    {
+        public static int Interval = 3;
+
+        public static async Task<int> GetStickersCount(Dictionary<string, UserStickerRelationEntity> stickers)
+        {
+            var stickersWithEffect = (await StickerDao.GetListWhere(
+                item => item.Effect == (int) Effect.RandomSticker2Tier3Day)).Select(item => item.Md5Hash);
+            var userStickers = stickers.Values.Where(item => stickersWithEffect.Contains(item.ShortHash));
+            return userStickers.Sum(item => (DateTime.Today - Convert.ToDateTime(item.AdditionalData)).Days >= Interval 
+                ? item.Count : 0);
+        }
+
+        public static async Task<Dictionary<StickerEntity, int>> GenerateList(int count)
+        {
+            var stickers = await StickerDao.GetListWhere(item => item.Tier == 2);
+            var rnd = new Random();
+            var result = new List<StickerEntity>();
+            for (var i = 0; i < count; i++)
+                result.Add(stickers[rnd.Next(stickers.Count)]);
+            return result.GroupBy(item => item).ToDictionary(item => item.Key, item => item.Count());
+        }
+    }
+}