Преглед изворни кода

Refactor in game processing

Tigran пре 4 година
родитељ
комит
2b19787812

+ 17 - 27
MafiaTelegramBot/Commands/ChannelPost/ChannelPost.cs

@@ -1,45 +1,35 @@
 #nullable enable
-using System;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.Timers;
-using MafiaTelegramBot.Commands;
-using MafiaTelegramBot.Resources;
+using MafiaTelegramBot.Controllers;
+using MafiaTelegramBot.Game;
 using Telegram.Bot.Types;
 
-namespace MafiaTelegramBot.Models.ChannelPost
+namespace MafiaTelegramBot.Commands.ChannelPost
 {
-    public abstract class ChannelPost : UpdateModel<string>
+    public class ChannelPost : UpdateHandler
     {
-        protected int MessageId;
-        protected string Text = "";
-        protected override bool IsMatches(string command)
+        protected override List<UpdateHandler> List => new()
         {
-            return command.Contains(Name);
-        }
-
-        public static async Task<Message> Update(Update update)
-        {
-            var text = update.ChannelPost.Text;
-            var chatId = update.ChannelPost.Chat.Id;
-            var messageId = update.ChannelPost.MessageId;
-            if (text == null) return new Message();
-            if (text.Contains(keywords.giveaway)) return await new GiveawayChannelPost(text, chatId, messageId).Execute(update);
-            return new Message();
-        }
+            new GiveawayChannelPost(null),
+        };
 
         protected async Task<Message> SendErrorAndDelete(string message)
         {
-            var error = await Bot.SendWithMarkdown2(ChatId, message);
+            var error = await MessageController.SendText(User.Info, message);
             var timer = new Timer { AutoReset = false, Interval = 10 * 1000 };
-            timer.Elapsed += async (_, _) =>
+
+            async void OnTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
             {
-                try
-                {
-                    await DeletePreviousMessage(ChatId, error.MessageId);
-                } catch (Exception) { /* ignore */ }
-            };
+                await MessageController.DeleteMessage(User.Info.ChatId, error.MessageId);
+            }
+
+            timer.Elapsed += OnTimerOnElapsed;
             timer.Start();
             return error;
         }
+
+        public ChannelPost(Player player) : base(player) { }
     }
 }

+ 15 - 18
MafiaTelegramBot/Commands/ChannelPost/GiveawayChannelPost.cs

@@ -1,19 +1,21 @@
 using System;
 using System.Collections.Generic;
 using System.Threading.Tasks;
+using MafiaTelegramBot.Controllers;
+using MafiaTelegramBot.Game;
 using MafiaTelegramBot.Other;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 
-namespace MafiaTelegramBot.Models.ChannelPost
+namespace MafiaTelegramBot.Commands.ChannelPost
 {
     public class GiveawayChannelPost : ChannelPost
     {
-        protected override string Name => keywords.giveaway;
-        protected override async Task<Message> Execute(Update update)
+        protected override string Command => keywords.giveaway;
+        public override async Task<Message> Execute(Update update)
         {
-            await DeletePreviousMessage(ChatId, MessageId);
-            var structure = ParseMessage();
+            await MessageController.DeleteMessage(User.Info.ChatId, update.ChannelPost.MessageId);
+            var structure = ParseMessage(update.ChannelPost.Text);
             if (structure[keywords.message] == "" && structure[keywords.picture] == "") return await SendErrorAndDelete(strings.message_could_contain_text_or_image);
             if (structure[keywords.prize] == "") return await SendErrorAndDelete(strings.message_could_contain_prize);
             if (structure[keywords.button] == "") return await SendErrorAndDelete(strings.message_could_contain_button_name);
@@ -21,21 +23,21 @@ namespace MafiaTelegramBot.Models.ChannelPost
             if (!int.TryParse(structure[keywords.count], out var count)) return await SendErrorAndDelete(strings.count_of_prizes_must_be_int);
             if (!Enum.TryParse<Roles>(structure[keywords.prize], out var prize)) return await SendErrorAndDelete(strings.prize_name_must_be_an_english_keyword);
             var giveaway = new GiveAway(count, prize);
-            return await giveaway.PostGiveAway(ChatId, structure[keywords.button], 
+            return await giveaway.PostGiveAway(User.Info, structure[keywords.button], 
                 structure[keywords.message] != "" ? structure[keywords.message] : null, 
                 structure[keywords.picture] != "" ? structure[keywords.picture] : null,
                 structure[keywords.to] != "" ? structure[keywords.to] : null);
         }
 
-        private Dictionary<string, string> ParseMessage()
+        private Dictionary<string, string> ParseMessage(string text)
         {
             string GetPart(string keyword)
             {
-                if (!Text.Contains(keyword)) return "";
-                var start = Text.IndexOf(keyword, StringComparison.Ordinal);
-                start = Text.IndexOf('<', start) + 1;
-                var end = Text.IndexOf('>', start);
-                return end - start > 0 || end == -1 || start == -1 ? Text.Substring(start, end - start) : "";
+                if (!text.Contains(keyword)) return "";
+                var start = text.IndexOf(keyword, StringComparison.Ordinal);
+                start = text.IndexOf('<', start) + 1;
+                var end = text.IndexOf('>', start);
+                return end - start > 0 || end == -1 || start == -1 ? text.Substring(start, end - start) : "";
             }
             
             var result = new Dictionary<string, string>
@@ -50,11 +52,6 @@ namespace MafiaTelegramBot.Models.ChannelPost
             return result;
         }
 
-        public GiveawayChannelPost(string text, long chatId, int messageId)
-        {
-            Text = text;
-            ChatId = chatId;
-            MessageId = messageId;
-        }
+        public GiveawayChannelPost(Player player) : base(player) { }
     }
 }

+ 3 - 4
MafiaTelegramBot/Commands/UpdateHandler.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands.Messages;
 using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Game;
 using Telegram.Bot.Types;
@@ -10,13 +9,13 @@ namespace MafiaTelegramBot.Commands
 {
     public class UpdateHandler
     {
-        protected virtual string Command { get; } = "";
-        
+        protected virtual string Command => "";
+
         protected virtual List<UpdateHandler> List { get; } = new();
         
         protected Player User { get; }
         
-        public virtual async Task<Message> Execute(Update update) { return new Message(); }
+        public virtual Task<Message> Execute(Update update) { return Task.FromResult(new Message()); }
 
         protected virtual bool IsMatches(string command) { return command.Contains(Command); }
 

+ 27 - 1
MafiaTelegramBot/Controllers/MessageController.cs

@@ -3,12 +3,14 @@ using System.Threading;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Commands;
 using MafiaTelegramBot.Commands.CallbackQueries;
+using MafiaTelegramBot.Commands.ChannelPost;
 using MafiaTelegramBot.Commands.Messages;
 using MafiaTelegramBot.DataBase.Entity;
 using Telegram.Bot;
 using Telegram.Bot.Exceptions;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
+using Telegram.Bot.Types.InputFiles;
 using Telegram.Bot.Types.ReplyMarkups;
 using static MafiaTelegramBot.Logs;
 #pragma warning disable 1998
@@ -19,6 +21,19 @@ namespace MafiaTelegramBot.Controllers
     {
         public static async Task HandleUpdateAsync(ITelegramBotClient bot, Update update, CancellationToken ct)
         {
+            User ChatToUser(Chat chat)
+            {
+                return new User
+                {
+                    FirstName = chat.Title,
+                    Id = chat.Id,
+                    IsBot = true,
+                    LastName = "",
+                    LanguageCode = "ru",
+                    Username = chat.Username
+                };
+            }
+            
             try
             {
                 var handler = update.Type switch
@@ -27,7 +42,8 @@ namespace MafiaTelegramBot.Controllers
                         await UpdateHandler.Factory(update.Message.From, update.Message.Text, new MessageHandler(null)),
                     UpdateType.CallbackQuery =>
                         await UpdateHandler.Factory(update.CallbackQuery.From, update.CallbackQuery.Data, new CallbackQueryHandler(null)),
-                    // UpdateType.ChannelPost => ChannelPost.Update(update),
+                    UpdateType.ChannelPost =>
+                        await UpdateHandler.Factory(ChatToUser(update.ChannelPost.Chat), update.ChannelPost.Text, new ChannelPost(null)),
                     // UpdateType.ChatMember => ChatMember.Update(update),
                     _ => await UnknownUpdateHandlerAsync(update)
                 };
@@ -79,10 +95,20 @@ namespace MafiaTelegramBot.Controllers
         {
             return await Bot.Client.EditMessageTextAsync(info.ChatId, messageId, message, replyMarkup: keyboard);
         }
+
+        public static async Task<Message> EditReplyMarkup(UserEntity info, int messageId, InlineKeyboardMarkup keyboard)
+        {
+            return await Bot.Client.EditMessageReplyMarkupAsync(info.ChatId, messageId, keyboard);
+        }
         
         public static async Task DeleteMessage(long chatId, int messageId)
         {
             await Bot.Client.DeleteMessageAsync(chatId, messageId);
         }
+
+        public static async Task<Message> SendImage(UserEntity info, InputOnlineFile inputOnlineFile, string message, InlineKeyboardMarkup replyMarkup)
+        {
+            return await Bot.Client.SendPhotoAsync(info.ChatId, inputOnlineFile, message, replyMarkup: replyMarkup);
+        }
     }
 }

+ 14 - 18
MafiaTelegramBot/Controllers/RoomController.cs

@@ -1,10 +1,8 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
 using MafiaTelegramBot.Game;
 using MafiaTelegramBot.Game.GameRooms;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 
 namespace MafiaTelegramBot.Controllers
@@ -25,7 +23,7 @@ namespace MafiaTelegramBot.Controllers
                     ? new ExtendedGameRoom {Owner = creator, RoomName = roomName, IsPrivate = isPrivate, IsRanking = isRanking}
                     : new NormalGameRoom {Owner = creator, RoomName = roomName, IsPrivate = isPrivate, IsRanking = isRanking};
                 OpenedGames.Add(roomKey, room);
-                room.Players.Add(creator.Id, creator);
+                room.Players.Add(creator.Info.Id, creator);
                 
                 room.SetTimer();
                 
@@ -33,7 +31,7 @@ namespace MafiaTelegramBot.Controllers
             });
         }
 
-        public static async Task ConnectToFastGame(Player player)
+        public static async Task<ResultCode> ConnectToFastGame(Player player)
         {
             return await Task.Run(async () =>
             {
@@ -66,16 +64,14 @@ namespace MafiaTelegramBot.Controllers
                     }
                 }
                 player.SetRoomName(room.RoomName);
-                room.Players.Add(player.Id, player);
+                room.Players.Add(player.Info.Id, player);
                 if (room.Players.Count > Constants.MEMORY_CLEANER_PLAYERS_COUNT) room.StopTimer();
-                await room.PlayersMessageChannel.SendExcept(player.Id, $"{player.NickName} {strings.connected_to_game}");
-                room.PlayersMessageChannel.AddPerson(player.ChatId);
-                await Bot.SendHyperLink(player.ChatId, $"<a href='https://t.me/{AppSettings.Name}?start=fast_game={RoomEncrypter.GetCode(room.RoomName)}'>{strings.link}</a>");
-                if (room.Players.Count == Constants.PLAYERS_TO_START_FAST_GAME)
-                {
-                    await room.Prepare();
-                    room.Start();
-                }
+                await room.PlayersMessageChannel.SendExcept(player.Info, $"{player.Info.NickName} {strings.connected_to_game}");
+                room.PlayersMessageChannel.AddPerson(player.Info);
+                await MessageController.SendTextWithHtml(player.Info, $"<a href='https://t.me/{AppSettings.Name}?start=fast_game={RoomEncrypter.GetCode(room.RoomName)}'>{strings.link}</a>");
+                if (room.Players.Count < Constants.PLAYERS_TO_START_FAST_GAME) return ResultCode.CodeOk;
+                await room.Prepare();
+                room.Start();
                 return ResultCode.CodeOk;
             });
         }
@@ -107,12 +103,12 @@ namespace MafiaTelegramBot.Controllers
                 if (room.IsRunning) return ResultCode.GameAlreadyRunning;
                 if (room.IsFilled()) return ResultCode.RoomIsFilled;
                 if (!player.SetRoomName(roomName)) return ResultCode.UserAlreadyInGame;
-                room.Players.Add(player.Id, player);
+                room.Players.Add(player.Info.Id, player);
 
                 if (room.Players.Count > Constants.MEMORY_CLEANER_PLAYERS_COUNT) room.StopTimer();
                 
-                await room.PlayersMessageChannel.SendExcept(player.Id, $"{player.NickName} {strings.connected_to_game}");
-                room.PlayersMessageChannel.AddPerson(player.ChatId);
+                await room.PlayersMessageChannel.SendExcept(player.Info, $"{player.Info.NickName} {strings.connected_to_game}");
+                room.PlayersMessageChannel.AddPerson(player.Info);
                 return ResultCode.CodeOk;
             });
         }
@@ -150,8 +146,8 @@ namespace MafiaTelegramBot.Controllers
                 {
                     foreach (var player in room.Players.Values)
                     {
-                        await room.PlayersMessageChannel.SendTo(player.Id, strings.room_dissolved,
-                            player.IsAdmin ? Keyboard.AdminMainMenu : Keyboard.MainMenu);
+                        await room.PlayersMessageChannel.SendTo(player.Info, strings.room_dissolved,
+                            player.Info.IsAdmin ? Keyboard.AdminMainMenu : Keyboard.MainMenu);
                         player.RemoveGame();
                         player.ResetState();
                     }

+ 14 - 14
MafiaTelegramBot/Game/GameRooms/FastGameRoom.cs

@@ -1,10 +1,8 @@
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.Timers;
-using MafiaTelegramBot.Commands;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections.Extensions;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 
 namespace MafiaTelegramBot.Game.GameRooms
@@ -15,29 +13,31 @@ namespace MafiaTelegramBot.Game.GameRooms
 
         public async Task RunContinueVote()
         {
-            var result = await PlayersMessageChannel.Send(strings.press_button_to_continue_game, Keyboard.ContinueButton);
+            var result = await PlayersMessageChannel.SendAndReturn(strings.press_button_to_continue_game, Keyboard.ContinueButton());
             var timer = new Timer { Interval = Constants.TIME_TO_DECIDE, AutoReset = false, Enabled = true};
-            timer.Elapsed += async (_, _) =>
+
+            async void OnTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
             {
-                foreach (var (k, v) in result)
-                    await Bot.Get().DeleteMessageAsync(k, v);
+                foreach (var (k, v) in result) await MessageController.DeleteMessage(k, v);
                 await ApplyResults();
-            };
+            }
+
+            timer.Elapsed += OnTimerOnElapsed;
         }
 
         private async Task ApplyResults()
         {
-            foreach (var (k, v) in Players)
-                if (!ContinuePlayers.Contains(v))
+            foreach (var player in Players.Values)
+                if (!ContinuePlayers.Contains(player))
                 {
-                    var result = await RoomController.LeaveFromGame(v);
+                    var result = await RoomController.LeaveFromGame(player);
                     if (result == ResultCode.CodeOk)
-                        await Bot.SendWithMarkdown2(k, $"{strings.you_leave_from_game} _*{RoomName}*_",
-                            v.IsAdmin ? Keyboard.AdminMainMenu : Keyboard.MainMenu);
-                    else await Utilities.GetResultCodeMessage(result, k);
+                        await MessageController.SendText(player.Info, $"{strings.you_leave_from_game} {RoomName}",
+                            player.Info.IsAdmin ? Keyboard.AdminMainMenu : Keyboard.MainMenu);
+                    else await MessageController.SendText(player.Info, Utilities.GetResultCodeMessage(result));
                 }
             ContinuePlayers.Clear();
-            if (Players.Values.Count == Constants.PLAYERS_TO_START_FAST_GAME)
+            if (Players.Values.Count >= Constants.PLAYERS_TO_START_FAST_GAME)
             {
                 await Prepare();
                 Start();

+ 65 - 59
MafiaTelegramBot/Game/GameRooms/GameRoom.GameProcess.cs

@@ -2,12 +2,11 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
+using System.Timers;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections.Extensions;
 using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Game.GameRoles;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 using Timer = System.Timers.Timer;
 
@@ -17,14 +16,16 @@ namespace MafiaTelegramBot.Game.GameRooms
     {
         public void Start()
         {
-            new Task(async () =>
+            async void Action()
             {
                 IsRunning = true;
                 await FirstNight();
                 await FirstDay();
                 await GameCycle();
                 await EndOfGame();
-            }).Start();
+            }
+
+            new Task(Action).Start();
         }
 
         private async Task FirstDay()
@@ -40,8 +41,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                 {
                     var player = _turnOrder.Dequeue();
                     if (!player.IsPlaying) continue;
-                    await PlayersMessageChannel.Send($"{strings.now_turn} ({player.TurnOrder}) {player.NickName}");
-                    if (TimerEnabled) await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
+                    await PlayersMessageChannel.Send($"{strings.now_turn} ({player.TurnOrder}) {player.Info.NickName}");
+                    if (TimerEnabled) await MessageController.SendText(player.Info, strings.you_turn_say);
                     await player.CurrentRole.SpeakAction(Constants.DAY_SPEAK_INTERVAL);
                     if (firstPlayer != null && player.IsPlaying) _turnOrder.Enqueue(player);
                     else firstPlayer = player;
@@ -68,10 +69,10 @@ namespace MafiaTelegramBot.Game.GameRooms
                 var don = Players.Values.FirstOrDefault(player => player.GetRole() is Roles.Don);
                 var dame = Players.Values.FirstOrDefault(player => player.GetRole() is Roles.Dame);
                 var message = strings.your_teammates;
-                if (don != null) message += $"\n({don.TurnOrder}) {don.NickName} - {roles.Don}";
-                if (dame != null) message += $"\n({dame.TurnOrder}) {dame.NickName} - {roles.Dame}";
+                if (don != null) message += $"\n({don.TurnOrder}) {don.Info.NickName} - {roles.Don}";
+                if (dame != null) message += $"\n({dame.TurnOrder}) {dame.Info.NickName} - {roles.Dame}";
                 message = mafia.Aggregate(message,
-                    (current, player) => current + $"\n({player.TurnOrder}) {player.NickName}");
+                    (current, player) => current + $"\n({player.TurnOrder}) {player.Info.NickName}");
                 await MafiaMessageChannel.Send(message);
                 var resetEvent = new ManualResetEvent(false);
                 var timer = new Timer
@@ -85,11 +86,11 @@ namespace MafiaTelegramBot.Game.GameRooms
                 foreach (var player in Players.Values)
                 {
                     if (player.GetRole() is not (Roles.Don or Roles.Mafia or Roles.Dame))
-                        player.CurrentRole.KnownRoles.Add(player.Id, player.GetRoleName());
+                        player.CurrentRole.KnownRoles.Add(player.Info.Id, player.GetRoleName());
                     else
                         foreach (var p in Players.Values
                             .Where(p => p.GetRole() is Roles.Don or Roles.Mafia or Roles.Dame))
-                            player.CurrentRole.KnownRoles.Add(p.Id, p.GetRoleName());
+                            player.CurrentRole.KnownRoles.Add(p.Info.Id, p.GetRoleName());
                 }
 
                 resetEvent.WaitOne();
@@ -127,12 +128,15 @@ namespace MafiaTelegramBot.Game.GameRooms
             var discussionTimer = new Timer { AutoReset = false, Interval = Constants.DISCUSSION_INTERVAL };
             var discussionEnded = new ManualResetEvent(false);
             foreach (var player in Players.Values.Where(player => !player.IsBlocked)) player.IsSpeaker = true;
-            discussionTimer.Elapsed += async (_, _) =>
+
+            async void OnDiscussionTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
             {
                 foreach (var player in Players.Values) player.IsSpeaker = false;
                 await PlayersMessageChannel.Send(strings.day_discussion_ended);
                 discussionEnded.Set();
-            };
+            }
+
+            discussionTimer.Elapsed += OnDiscussionTimerOnElapsed;
             await PlayersMessageChannel.Send(strings.disscution_time);
             discussionTimer.Start();
             discussionEnded.WaitOne();
@@ -141,16 +145,16 @@ namespace MafiaTelegramBot.Game.GameRooms
             for (var i = 0; i < turnsCount; ++i)
             {
                 var player = _turnOrder.Dequeue();
-                if (!Players.ContainsKey(player.Id)) continue;
+                if (!Players.ContainsKey(player.Info.Id)) continue;
                 if (!player.IsBlocked && player.IsAlive)
                 {
-                    await PlayersMessageChannel.Send($"{strings.now_turn} ({player.TurnOrder}) {player.NickName}");
+                    await PlayersMessageChannel.Send($"{strings.now_turn} ({player.TurnOrder}) {player.Info.NickName}");
                     if (Owner != null)
                     {
-                        if (TimerEnabled) await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
+                        if (TimerEnabled) await MessageController.SendText(player.Info, strings.you_turn_say);
                         await player.CurrentRole.SpeakAction(Constants.DAY_SPEAK_INTERVAL);
                     }
-                    if (Players.ContainsKey(player.Id)) await player.CurrentRole.VotingAction(VoteUpList.Count == 0);
+                    if (Players.ContainsKey(player.Info.Id)) await player.CurrentRole.VotingAction(VoteUpList.Count == 0);
                 }
                 _turnOrder.Enqueue(player);
             }
@@ -169,10 +173,10 @@ namespace MafiaTelegramBot.Game.GameRooms
                 foreach (var player in Players.Values)
                     await player.CurrentRole.NightAction();
                 timer.Elapsed += (_, _) => resetEvent.Set();
-                var doctorId = PlayersRole[Roles.Doctor].Count == 1 ? PlayersRole[Roles.Doctor][0].Id : -1;
+                var doctorId = PlayersRole[Roles.Doctor].Count == 1 ? PlayersRole[Roles.Doctor][0].Info.Id : -1;
                 foreach (var player in Players.Values)
                 {
-                    if (doctorId != player.Id) player.CanBeHealed = true;
+                    if (doctorId != player.Info.Id) player.CanBeHealed = true;
                     player.CanBeBlockedNight = true;
                     player.CanBeBlockedDay = true;
                     player.IsBlocked = false;
@@ -187,7 +191,7 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             await Task.Run(async () =>
             {
-                var beforeKill = Players.Values.ToDictionary(p => p.Id, p => p.IsAlive);
+                var beforeKill = Players.Values.ToDictionary(p => p.Info.Id, p => p.IsAlive);
                 var mafiaNotAgree = "";
                 var votes = Players.Values.Where(p =>
                         p.IsAlive && p.CurrentRole.MafiaTargetId != -1 && p.CurrentRole.MafiaTargetId != -2 &&
@@ -228,7 +232,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                     else if (players.Count == 1) await players[0].CurrentRole.ApplyNightActionResult();
                 }
 
-                var afterKill = Players.Values.ToDictionary(p => p.Id, p => p.IsAlive);
+                var afterKill = Players.Values.ToDictionary(p => p.Info.Id, p => p.IsAlive);
                 var message = strings.city_wakes_up;
                 if (afterKill.IsEquals(beforeKill)) message += strings.everyone_survived;
                 else
@@ -236,13 +240,13 @@ namespace MafiaTelegramBot.Game.GameRooms
                         if (beforeKill[id] != alive && Players.ContainsKey(id))
                         {
                             message += alive
-                                ? $"\n{Players[id].NickName} {strings.will_be_ressurected}"
-                                : $"\n{Players[id].NickName} {strings.will_be_killed}";
+                                ? $"\n{Players[id].Info.NickName} {strings.will_be_ressurected}"
+                                : $"\n{Players[id].Info.NickName} {strings.will_be_killed}";
                             if (!alive && Players[id].GetRole() is Roles.Don or Roles.Dame or Roles.Mafia
                                        && PlayersRole.ContainsKey(Roles.Werewolf) &&
                                        PlayersRole[Roles.Werewolf].Count == 1)
                                 await ((WerewolfRole)PlayersRole[Roles.Werewolf][0].CurrentRole).TransformToMafia();
-                            await PlayersMessageChannel.SendTo(id,
+                            await PlayersMessageChannel.SendTo(Players[id].Info,
                                 alive ? strings.you_will_be_ressurected : strings.you_will_be_killed);
                         }
 
@@ -258,21 +262,23 @@ namespace MafiaTelegramBot.Game.GameRooms
             {
                 var contendersCopy = contenders.ToList();
                 foreach (var contender in contendersCopy.Where(p => !p.IsBlocked))
-                    if (Players.ContainsKey(contender.Id))
+                    if (Players.ContainsKey(contender.Info.Id))
                         await contender.CurrentRole.DefenceAction();
                 var votersPlayers = Players.Values.Where(p => p.IsAlive && !p.IsBlocked).ToArray();
                 foreach (var voter in votersPlayers)
-                    await voter.CurrentRole.VotingAction(contendersCopy.Where(p => Players.ContainsKey(p.Id)).ToList());
+                    await voter.CurrentRole.VotingAction(contendersCopy.Where(p => Players.ContainsKey(p.Info.Id)).ToList());
                 var timer = new Timer { Interval = Constants.VOTE_KILL_INTERVAL, AutoReset = false };
                 var resetEvent = new ManualResetEvent(false);
-                timer.Elapsed += async (_, _) =>
+
+                async void OnTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
                 {
                     if (Constants.ENABLE_AUTO_VOTING)
-                        foreach (var voter in votersPlayers.Where(p =>
-                            !_voteKillList.ContainsKey(p.Id) && Players.ContainsKey(p.Id)))
+                        foreach (var voter in votersPlayers.Where(p => !_voteKillList.ContainsKey(p.Info.Id) && Players.ContainsKey(p.Info.Id)))
                             await voter.CurrentRole.RandomVoting();
                     resetEvent.Set();
-                };
+                }
+
+                timer.Elapsed += OnTimerOnElapsed;
                 timer.Start();
                 resetEvent.WaitOne();
             });
@@ -345,16 +351,16 @@ namespace MafiaTelegramBot.Game.GameRooms
             foreach (var (playerId, targetId) in _voteKillList)
             {
                 message += Players.ContainsKey(playerId) && Players.ContainsKey(targetId)
-                    ? $"\n({Players[playerId].TurnOrder}) {Players[playerId].NickName} {strings.vote_to} " +
-                      $"({Players[targetId].TurnOrder}) {Players[targetId].NickName}"
+                    ? $"\n({Players[playerId].TurnOrder}) {Players[playerId].Info.NickName} {strings.vote_to} " +
+                      $"({Players[targetId].TurnOrder}) {Players[targetId].Info.NickName}"
                     : "";
             }
 
             if (message == strings.results_of_voting) message = strings.no_one_voted;
             await PlayersMessageChannel.Send(message);
 
-            var votes = VoteUpList.Where(p => Players.ContainsKey(p.Id))
-                .GroupBy(p => p.Id)
+            var votes = VoteUpList.Where(p => Players.ContainsKey(p.Info.Id))
+                .GroupBy(p => p.Info.Id)
                 .Select(item => new { id = item.Key, count = item.Count() })
                 .ToList();
             List<Player> result = new();
@@ -374,9 +380,9 @@ namespace MafiaTelegramBot.Game.GameRooms
                 if (targetId == 0)
                 {
                     if (!toKill)
-                        await PlayersMessageChannel.SendExcept(playerId,
-                            $"{Players[playerId].NickName} {strings.skip_vote}");
-                    await PlayersMessageChannel.EditTo(playerId, messageId, strings.you_skip_vote);
+                        await PlayersMessageChannel.SendExcept(Players[playerId].Info,
+                            $"{Players[playerId].Info.NickName} {strings.skip_vote}");
+                    await PlayersMessageChannel.EditTo(Players[playerId].Info, messageId, strings.you_skip_vote);
                 }
                 else
                 {
@@ -388,16 +394,16 @@ namespace MafiaTelegramBot.Game.GameRooms
                             {
                                 if (playerId != targetId)
                                 {
-                                    await PlayersMessageChannel.SendExcept(playerId,
-                                        $"{Players[playerId].NickName} {strings.put_up_vote_to} {Players[targetId].NickName}");
-                                    await PlayersMessageChannel.EditTo(playerId, messageId,
-                                        $"{strings.you_vote_player} {Players[targetId].NickName}");
+                                    await PlayersMessageChannel.SendExcept(Players[playerId].Info,
+                                        $"{Players[playerId].Info.NickName} {strings.put_up_vote_to} {Players[targetId].Info.NickName}");
+                                    await PlayersMessageChannel.EditTo(Players[playerId].Info, messageId,
+                                        $"{strings.you_vote_player} {Players[targetId].Info.NickName}");
                                 }
                                 else
                                 {
-                                    await PlayersMessageChannel.SendExcept(playerId,
-                                        $"{Players[playerId].NickName} {strings.vote_to_self}");
-                                    await PlayersMessageChannel.EditTo(playerId, messageId, strings.you_vote_to_self);
+                                    await PlayersMessageChannel.SendExcept(Players[playerId].Info,
+                                        $"{Players[playerId].Info.NickName} {strings.vote_to_self}");
+                                    await PlayersMessageChannel.EditTo(Players[playerId].Info, messageId, strings.you_vote_to_self);
                                 }
                             }
                         }
@@ -407,17 +413,17 @@ namespace MafiaTelegramBot.Game.GameRooms
                             if (messageId != -1)
                             {
                                 if (playerId != targetId)
-                                    await PlayersMessageChannel.EditTo(playerId, messageId,
-                                        $"{strings.you_vote_to_kill} {Players[targetId].NickName}");
+                                    await PlayersMessageChannel.EditTo(Players[playerId].Info, messageId,
+                                        $"{strings.you_vote_to_kill} {Players[targetId].Info.NickName}");
                                 else
-                                    await PlayersMessageChannel.EditTo(playerId, messageId,
+                                    await PlayersMessageChannel.EditTo(Players[playerId].Info, messageId,
                                         strings.you_vote_to_kill_self);
                             }
                         }
                     }
                 }
             }
-            else await PlayersMessageChannel.SendTo(playerId, strings.this_player_left_from_game);
+            else await PlayersMessageChannel.SendTo(Players[playerId].Info, strings.this_player_left_from_game);
         }
 
         private async Task EndOfGame()
@@ -436,12 +442,12 @@ namespace MafiaTelegramBot.Game.GameRooms
                     await PlayersMessageChannel.Send(strings.thanks_for_game, Keyboard.PlayerGameMenu);
                     await r.RunContinueVote();
                 }
-                else if (!Players.ContainsKey(Owner.Id))
+                else if (!Players.ContainsKey(Owner.Info.Id))
                     await RoomController.DissolveRoom(RoomEncrypter.GetCode(RoomName));
                 else
                 {
-                    await PlayersMessageChannel.SendTo(Owner.ChatId, strings.thanks_for_game, Keyboard.OwnerGameMenu);
-                    await PlayersMessageChannel.SendExcept(Owner.Id, strings.thanks_for_game, Keyboard.PlayerGameMenu);
+                    await PlayersMessageChannel.SendTo(Owner.Info, strings.thanks_for_game, Keyboard.OwnerGameMenu);
+                    await PlayersMessageChannel.SendExcept(Owner.Info, strings.thanks_for_game, Keyboard.PlayerGameMenu);
                     if (Players.Count <= Constants.MEMORY_CLEANER_PLAYERS_COUNT) StartTimer();
                 }
                 await UserDao.DataBase.SaveChangesAsync();
@@ -452,7 +458,7 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             foreach (var player in Players.Values)
             {
-                await Bot.SendWithMarkdown2(player.ChatId, strings.game_ended_with_draw);
+                await MessageController.SendText(player.Info, strings.game_ended_with_draw);
                 player.Statistics[Roles.All].Games--;
                 player.Statistics[player.GetRole()].Games--;
                 player.ResetState();
@@ -486,19 +492,19 @@ namespace MafiaTelegramBot.Game.GameRooms
             
             var villagerTeam = Players.Values
                 .Where(p => p.CurrentRole.ColorRole == 1 && p.GetRole() != Roles.Lawyer)
-                .Select(p => p.Id).ToList();
+                .Select(p => p.Info.Id).ToList();
             var mafiaTeam = Players.Values
                 .Where(p => p.CurrentRole.ColorRole == 2 || p.GetRole() == Roles.Lawyer)
-                .Select(p => p.Id).ToList();
+                .Select(p => p.Info.Id).ToList();
             
             foreach (var player in Players.Values)
             {
-                rolesMessage += $"\n({player.TurnOrder}) {player.NickName} - {player.GetRoleName()}";
+                rolesMessage += $"\n({player.TurnOrder}) {player.Info.NickName} - {player.GetRoleName()}";
                 if (IsRanking) await SumRankingPoints(player, mafiaWins);
                 if (mafiaWins)
                 {
-                    await Bot.SendWithMarkdown2(player.ChatId, strings.mafia_won + additionalResult);
-                    await Bot.SendStickerAsync(player.ChatId, Stickers.Sticker["MafiaWins"]);
+                    await MessageController.SendText(player.Info, strings.mafia_won + additionalResult);
+                    await MessageController.SendSticker(player.Info, Stickers.Sticker["MafiaWins"]);
                     if (player.CurrentRole.ColorRole == 2 || player.CurrentRole.RoleKey == Roles.Lawyer)
                     {
                         player.Statistics[Roles.All].Wins++;
@@ -517,8 +523,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                 }
                 else
                 {
-                    await Bot.SendWithMarkdown2(player.ChatId, strings.villagers_won + additionalResult);
-                    await Bot.SendStickerAsync(player.ChatId, Stickers.Sticker["VillagerWins"]);
+                    await MessageController.SendText(player.Info, strings.villagers_won + additionalResult);
+                    await MessageController.SendSticker(player.Info, Stickers.Sticker["VillagerWins"]);
                     if (player.CurrentRole.ColorRole == 1 && player.GetRole() != Roles.Lawyer)
                     {
                         player.Statistics[Roles.All].Wins++;

+ 25 - 25
MafiaTelegramBot/Game/GameRooms/GameRoom.MessageChannels.cs

@@ -2,9 +2,9 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
+using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections.Extensions;
-using MafiaTelegramBot.Models;
+using MafiaTelegramBot.DataBase.Entity;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.ReplyMarkups;
 
@@ -15,70 +15,70 @@ namespace MafiaTelegramBot.Game.GameRooms
         public class Channel
         {
             protected readonly GameRoom Room;
-            protected IEnumerable<long> Players;
+            protected IEnumerable<UserEntity> Players;
             
-            public async Task<Message> SendTo(long userId, string message, IReplyMarkup replyMarkup = null)
+            public async Task<Message> SendTo(UserEntity info, string message, IReplyMarkup replyMarkup = null)
             {
-                if(Room.Players.ContainsKey(userId)) return await Bot.SendWithMarkdown2(Room.Players[userId].ChatId, message, replyMarkup);
+                if (Room.Players.ContainsKey(info.Id)) return await MessageController.SendText(info, message, replyMarkup);
                 return new Message();
             }
             
-            public async Task EditTo(long userId, int messageId, string message, InlineKeyboardMarkup replyMarkup = null)
+            public async Task EditTo(UserEntity info, int messageId, string message, InlineKeyboardMarkup replyMarkup = null)
             {
-                if(Room.Players.ContainsKey(userId)) await Bot.EditMessageAsync(Room.Players[userId].ChatId, messageId, message, replyMarkup);
+                if (Room.Players.ContainsKey(info.Id)) await MessageController.EditMessage(info, messageId, message, replyMarkup);
             }
             
             public async Task Send(string message, IReplyMarkup replyMarkup = null)
             {
-                foreach (var id in Players)
-                    await Bot.SendWithMarkdown2(id, message, replyMarkup);
+                foreach (var info in Players)
+                    await MessageController.SendText(info, message, replyMarkup);
             }
             
-            public async Task<Dictionary<long, int>> Send(string message, Func<long, IReplyMarkup> keyboard)
+            public async Task<Dictionary<long, int>> SendAndReturn(string message, IReplyMarkup keyboard)
             {
                 var messages = new Dictionary<long, int>();
-                foreach (var id in Players)
+                foreach (var info in Players)
                 {
-                    var result = await Bot.SendWithMarkdown2(id, message, keyboard(id));
-                    messages.Add(id, result.MessageId);
+                    var result = await MessageController.SendText(info, message, keyboard);
+                    messages.Add(info.ChatId, result.MessageId);
                 }
 
                 return messages;
             }
 
-            public async Task SendExcept(long playerId, string message, IReplyMarkup replyMarkup = null)
+            public async Task SendExcept(UserEntity user, string message, IReplyMarkup replyMarkup = null)
             {
-                foreach (var id in Players)
-                    if (id != playerId) await Bot.SendWithMarkdown2(id, message, replyMarkup);
+                foreach (var info in Players)
+                    if (info.Id != user.Id) await MessageController.SendText(info, message, replyMarkup);
             }
 
             public async Task SendSticker(string fileId)
             {
-                foreach (var id in Players)
-                    await Bot.SendStickerAsync(id, fileId);
+                foreach (var info in Players)
+                    await MessageController.SendSticker(info, fileId);
             }
 
             public void Remove(long playerId)
             {
-                Players = Players.Where(id => id != playerId);
+                Players = Players.Where(id => id.Id != playerId);
             }
 
-            public void AddPerson(long id)
+            public void AddPerson(UserEntity user)
             {
                 var list = Players.ToList();
-                list.AddUnique(id);
+                list.AddUnique(user);
                 Players = list;
             }
 
             public virtual async Task UpdateList(IEnumerable<Player> players)
             {
-                Players = await Task.FromResult(players.Select(p => p.ChatId));
+                Players = await Task.FromResult(players.Select(p => p.Info));
             }
 
             public Channel(GameRoom room)
             {
                 Room = room;
-                Players = room.Players.Values.Select(p=>p.ChatId);
+                Players = room.Players.Values.Select(p=>p.Info);
             }
         }
 
@@ -86,12 +86,12 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             public MafiaChannel(GameRoom room) : base(room)
             {
-                Players = room.Players.Values.Where(p => p.CurrentRole.ColorRole is 2).Select(p=>p.ChatId);
+                Players = room.Players.Values.Where(p => p.CurrentRole.ColorRole is 2).Select(p=>p.Info);
             }
 
             public override async Task UpdateList(IEnumerable<Player> players)
             {
-                Players = await Task.FromResult(players.Where(p=>p.CurrentRole.ColorRole == 2).Select(p => p.ChatId));
+                Players = await Task.FromResult(players.Where(p=>p.CurrentRole.ColorRole == 2).Select(p => p.Info));
             }
         }
     }

+ 3 - 4
MafiaTelegramBot/Game/GameRooms/GameRoom.PrepareRoom.cs

@@ -2,9 +2,8 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
+using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections.Extensions;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 
 namespace MafiaTelegramBot.Game.GameRooms
@@ -83,12 +82,12 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             foreach (var player in Players.Values)
             {
-                await Bot.SendStickerAsync(player.ChatId, Stickers.Sticker[player.GetRole().ToString()]);
+                await MessageController.SendSticker(player.Info, Stickers.Sticker[player.GetRole().ToString()]);
                 var message =
                     $"{strings.your_role}: _*{player.GetRoleName()}*_\n" +
                     $"{strings.your_turn_order}: _*{player.TurnOrder}*_\n"+
                     $"{strings.bot_starting_game}";
-                await Bot.SendWithMarkdown2(player.ChatId, message, Keyboard.InGamePlayerMenu);
+                await MessageController.SendText(player.Info, message, Keyboard.InGamePlayerMenu);
             }
         }
 

+ 38 - 32
MafiaTelegramBot/Game/GameRooms/GameRoom.Role.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using System.Timers;
 using MafiaTelegramBot.Game.GameRoles;
 using MafiaTelegramBot.Resources;
 using Timer = System.Timers.Timer;
@@ -41,16 +42,16 @@ namespace MafiaTelegramBot.Game.GameRooms
             {
                 if (MessageId != -1)
                 {
-                    await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId, strings.activity_blocked);
+                    await Room.PlayersMessageChannel.EditTo(Player.Info, MessageId, strings.activity_blocked);
                     NightTargetId = -2;
                 }
                 if (MafiaMessageId != -1)
                 {
                     Player.IsSpeaker = false;
-                    await Room.PlayersMessageChannel.EditTo(Player.Id, MafiaMessageId, strings.activity_blocked);
+                    await Room.PlayersMessageChannel.EditTo(Player.Info, MafiaMessageId, strings.activity_blocked);
                     MafiaTargetId = -2;
                 }
-                await Room.PlayersMessageChannel.SendTo(Player.ChatId, message);
+                await Room.PlayersMessageChannel.SendTo(Player.Info, message);
             }
 
             public virtual async Task<string> IsWon()
@@ -61,20 +62,20 @@ namespace MafiaTelegramBot.Game.GameRooms
             {
                 if (Room.PlayersRole.ContainsKey(Roles.Hooker)
                     && Room.PlayersRole[Roles.Hooker].Count == 1 
-                    && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id)
+                    && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Info.Id)
                 {
-                    await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.villagers_want_dispatch} {Player.NickName}, {strings.player_not_died_he_has_alibi}");
+                    await Room.PlayersMessageChannel.SendExcept(Player.Info, $"{strings.villagers_want_dispatch} {Player.Info.NickName}, {strings.player_not_died_he_has_alibi}");
                 }
                 else
                 {
                     if (!Player.IsBlocked)
                     {
-                        await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
-                        await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.you_will_be_dispatched);
+                        await Room.PlayersMessageChannel.SendExcept(Player.Info, $"{strings.to_player} {Player.Info.NickName} {strings.issued_posthumous_minute}");
+                        await Room.PlayersMessageChannel.SendTo(Player.Info, strings.you_will_be_dispatched);
                         await SpeakAction(Constants.DISPATCH_SPEAK_INTERVAL, true);
                     }
                     await Kill();
-                    await Room.PlayersMessageChannel.Send($"({Player.TurnOrder}) {Player.NickName} {strings.dispatched}");
+                    await Room.PlayersMessageChannel.Send($"({Player.TurnOrder}) {Player.Info.NickName} {strings.dispatched}");
                     if(RoleKey == Roles.Cop) Player.FoolRoleAchievementEvent();
                 }
             }
@@ -84,28 +85,28 @@ namespace MafiaTelegramBot.Game.GameRooms
                 Player.IsAlive = false;
                 if (Room.PlayersRole.ContainsKey(Roles.Parasite)
                     && Room.PlayersRole[Roles.Parasite].Count == 1
-                    && ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == Player.Id)
+                    && ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == Player.Info.Id)
                 {
                     await Room.PlayersRole[Roles.Parasite][0].CurrentRole.Kill();
-                    if(Room.IsDay) await Room.PlayersMessageChannel.Send($"{strings.for_unknown_reasons_died} {Room.PlayersRole[Roles.Parasite][0].NickName}");
-                    await Room.PlayersMessageChannel.SendTo(Room.PlayersRole[Roles.Parasite][0].Id,
+                    if(Room.IsDay) await Room.PlayersMessageChannel.Send($"{strings.for_unknown_reasons_died} {Room.PlayersRole[Roles.Parasite][0].Info.NickName}");
+                    await Room.PlayersMessageChannel.SendTo(Room.PlayersRole[Roles.Parasite][0].Info,
                         strings.your_carrier_player_has_died);
                 }
             }
 
             protected async Task SetRandomNightTarget()
             {
-                var inGamePlayers = NightTargetList.Where(p => Room.Players.ContainsKey(p.Id)).ToArray();
+                var inGamePlayers = NightTargetList.Where(p => Room.Players.ContainsKey(p.Info.Id)).ToArray();
                 if (inGamePlayers.Length == 0)
                 {
                     NightTargetId = -1;
-                    await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId, strings.nothing_to_choose);
+                    await Room.PlayersMessageChannel.EditTo(Player.Info, MessageId, strings.nothing_to_choose);
                 }
                 else
                 {
-                    NightTargetId = NightTargetList[Utilities.Rnd.Next(NightTargetList.Count)].Id;
-                    await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId,
-                        $"{strings.automatically_choosed_target} {Room.Players[NightTargetId].NickName}");
+                    NightTargetId = NightTargetList[Utilities.Rnd.Next(NightTargetList.Count)].Info.Id;
+                    await Room.PlayersMessageChannel.EditTo(Player.Info, MessageId,
+                        $"{strings.automatically_choosed_target} {Room.Players[NightTargetId].Info.NickName}");
                 }
             }
 
@@ -117,7 +118,7 @@ namespace MafiaTelegramBot.Game.GameRooms
 
             public async Task SpeakAction(int interval, bool enableTimer = false)
             {
-                await Room.PlayersMessageChannel.SendTo(Player.ChatId, $"{strings.your_turn}", Keyboard.InGamePlayerMenuWithEndTurn);
+                await Room.PlayersMessageChannel.SendTo(Player.Info, $"{strings.your_turn}", Keyboard.InGamePlayerMenuWithEndTurn);
                 Player.IsSpeaker = true;
                 var timer = new Timer(interval) {AutoReset = false};
                 timer.Elapsed += (_, _) => TalkingActionComplete.Set();
@@ -125,7 +126,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                 TalkingActionComplete.WaitOne();
                 if (Room.TimerEnabled || enableTimer) timer.Stop();
                 TalkingActionComplete.Reset();
-                await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
+                await Room.PlayersMessageChannel.SendTo(Player.Info, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
                 Player.IsSpeaker = false;
             }
 
@@ -133,15 +134,20 @@ namespace MafiaTelegramBot.Game.GameRooms
             {
                 var voteTimer = new Timer(Constants.PUT_UP_VOTE_INTERVAL) {AutoReset = false};
                 var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).Except(Room.VoteUpList).ToList();
-                var message = await Room.PlayersMessageChannel.SendTo(Player.ChatId,
+                var message = await Room.PlayersMessageChannel.SendTo(Player.Info,
                     $"{strings.put_up_vote}\n{strings.you_have_twenty_seconds}{(isFirst ? "\n" + strings.user_not_choose : "")}",  
-                    Keyboard.VoteKeyboard(alivePlayers, Player.Id, !isFirst));
-                voteTimer.Elapsed += async (_, _) =>
+                    Keyboard.VoteKeyboard(alivePlayers, !isFirst));
+
+                async void OnVoteTimerOnElapsed(object o, ElapsedEventArgs elapsedEventArgs)
                 {
-                    if (isFirst) await Room.PutUpVote(Player.Id, Player.Id, message.MessageId);
-                    else await Room.PutUpVote(Player.Id, 0, message.MessageId);
+                    if (isFirst)
+                        await Room.PutUpVote(Player.Info.Id, Player.Info.Id, message.MessageId);
+                    else
+                        await Room.PutUpVote(Player.Info.Id, 0, message.MessageId);
                     VoteActionComplete.Set();
-                };
+                }
+
+                voteTimer.Elapsed += OnVoteTimerOnElapsed;
                 voteTimer.Start();
                 VoteActionComplete.WaitOne();
                 voteTimer.Stop();
@@ -153,26 +159,26 @@ namespace MafiaTelegramBot.Game.GameRooms
             private List<Player> _votingTargetsList;
             public async Task VotingAction(List<Player> targets)
             {
-                _votingMessageId = (await Room.PlayersMessageChannel.SendTo(Player.Id, strings.you_have_ten_seconds_to_vote, 
-                    Keyboard.VoteKeyboard(targets, Player.Id, false, Callback.VoteToKill))).MessageId;
+                _votingMessageId = (await Room.PlayersMessageChannel.SendTo(Player.Info, strings.you_have_ten_seconds_to_vote, 
+                    Keyboard.VoteKeyboard(targets, false, Callback.VoteToKill))).MessageId;
                 _votingTargetsList = targets;
             }
             public async Task RandomVoting()
             {
-                var players = _votingTargetsList.Where(p => Room.Players.ContainsKey(p.Id)).ToArray();
-                if(players.Length == 0) await Room.PlayersMessageChannel.EditTo(Player.Id, _votingMessageId, strings.nothing_to_choose);
+                var players = _votingTargetsList.Where(p => Room.Players.ContainsKey(p.Info.Id)).ToArray();
+                if(players.Length == 0) await Room.PlayersMessageChannel.EditTo(Player.Info, _votingMessageId, strings.nothing_to_choose);
                 else
                 {
                     var randomPlayer = players[Utilities.Rnd.Next(players.Length)];
-                    await Room.PutUpVote(Player.Id, randomPlayer.Id, toKill: true);
-                    await Room.PlayersMessageChannel.EditTo(Player.Id, _votingMessageId, $"{strings.automatically_vote} ({randomPlayer.TurnOrder}) {randomPlayer.NickName}");
+                    await Room.PutUpVote(Player.Info.Id, randomPlayer.Info.Id, toKill: true);
+                    await Room.PlayersMessageChannel.EditTo(Player.Info, _votingMessageId, $"{strings.automatically_vote} ({randomPlayer.TurnOrder}) {randomPlayer.Info.NickName}");
                 }
             }
 
             public async Task DefenceAction()
             {
-                await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.now_defence} ({Player.TurnOrder}) {Player.NickName}");
-                await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.you_have_thirty_seconds_to_defence);
+                await Room.PlayersMessageChannel.SendExcept(Player.Info, $"{strings.now_defence} ({Player.TurnOrder}) {Player.Info.NickName}");
+                await Room.PlayersMessageChannel.SendTo(Player.Info, strings.you_have_thirty_seconds_to_defence);
                 await SpeakAction(Constants.DEFENCE_INTERVAL);
             }
             public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)

+ 19 - 20
MafiaTelegramBot/Game/GameRooms/GameRoom.Structure.cs

@@ -2,9 +2,8 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using System.Timers;
-using MafiaTelegramBot.Commands;
+using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.Game.GameRoles;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 
@@ -66,32 +65,32 @@ namespace MafiaTelegramBot.Game.GameRooms
 
         public async Task Leave(Player player)
         {
-            Players.Remove(player.Id);
-            PlayersMessageChannel.Remove(player.Id);
-            MafiaMessageChannel.Remove(player.Id);
-            var message = Owner != null && Owner.Id == player.Id
-                ? $"{player.NickName} ({strings.room_owner}) {strings.leave_from_game}"
-                : $"{player.NickName} {strings.leave_from_game}";
+            Players.Remove(player.Info.Id);
+            PlayersMessageChannel.Remove(player.Info.Id);
+            MafiaMessageChannel.Remove(player.Info.Id);
+            var message = Owner != null && Owner.Info.Id == player.Info.Id
+                ? $"{player.Info.NickName} ({strings.room_owner}) {strings.leave_from_game}"
+                : $"{player.Info.NickName} {strings.leave_from_game}";
             await PlayersMessageChannel.Send(message);
             if (IsRunning)
             {
                 if (IsDay && player.IsSpeaker) player.CurrentRole.TalkingActionComplete.Set();
                 if (IsDay && !player.IsSpeaker) player.CurrentRole.VoteActionComplete.Set();
                 if (!IsDay) await player.CurrentRole.SetNightTarget(-1);
-                VoteUpList.RemoveAll(p=> p.Id == player.Id);
-                _voteKillList.Remove(player.Id);
+                VoteUpList.RemoveAll(p=> p.Info.Id == player.Info.Id);
+                _voteKillList.Remove(player.Info.Id);
                 var voteKillCopy = _voteKillList.ToList();
                 foreach (var (k, v) in voteKillCopy)
-                    if (v == player.Id) _voteKillList.Remove(k);
+                    if (v == player.Info.Id) _voteKillList.Remove(k);
                 PlayersRole[player.CurrentRole.RoleKey].Remove(player);
                 player.ResetParasiteProgress();
                 if (PlayersRole.ContainsKey(Roles.Parasite)
                     && PlayersRole[Roles.Parasite].Count == 1
-                    && ((ParasiteRole) PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == player.Id)
+                    && ((ParasiteRole) PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == player.Info.Id)
                     await PlayersRole[Roles.Parasite][0].CurrentRole.Kill();
                 if (player.CurrentRole.RoleKey==Roles.Werewolf) player.WerewolfRoleAchievementEvent(0,true);
             }
-            if (IsRanking && IsRunning) await Bot.SendWithMarkdown2(player.ChatId, $"{strings.you_lost} {player.SubtractRankPoints()} {strings.points}");
+            if (IsRanking && IsRunning) await MessageController.SendText(player.Info, $"{strings.you_lost} {player.SubtractRankPoints()} {strings.points}");
             player.ResetState();
         }
 
@@ -114,19 +113,19 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             return player.CurrentRole.ColorRole switch
             {
-                3 when player.CurrentRole.IsWon().Result != "" => Bot.SendWithMarkdown2(player.ChatId,
+                3 when player.CurrentRole.IsWon().Result != "" => MessageController.SendText(player.Info,
                     $"{strings.you_got} {player.AddRankPoints()} {strings.points}"),
-                3 => Bot.SendWithMarkdown2(player.ChatId,
+                3 => MessageController.SendText(player.Info,
                     $"{strings.you_lost} {player.SubtractRankPoints()} {strings.points}"),
-                1 when player.GetRole() != Roles.Lawyer && mafiaWins => Bot.SendWithMarkdown2(player.ChatId,
+                1 when player.GetRole() != Roles.Lawyer && mafiaWins => MessageController.SendText(player.Info,
                     $"{strings.you_lost} {player.SubtractRankPoints()} {strings.points}"),
-                1 when player.GetRole() == Roles.Lawyer && mafiaWins => Bot.SendWithMarkdown2(player.ChatId,
+                1 when player.GetRole() == Roles.Lawyer && mafiaWins => MessageController.SendText(player.Info,
                     $"{strings.you_got} {player.AddRankPoints()} {strings.points}"),
-                1 => Bot.SendWithMarkdown2(player.ChatId,
+                1 => MessageController.SendText(player.Info,
                     $"{strings.you_got} {player.AddRankPoints()} {strings.points}"),
-                2 when mafiaWins => Bot.SendWithMarkdown2(player.ChatId,
+                2 when mafiaWins => MessageController.SendText(player.Info,
                     $"{strings.you_got} {player.AddRankPoints()} {strings.points}"),
-                2 => Bot.SendWithMarkdown2(player.ChatId,
+                2 => MessageController.SendText(player.Info,
                     $"{strings.you_lost} {player.SubtractRankPoints()} {strings.points}"),
                 _ => Task.FromResult(new Message())
             };

+ 1 - 3
MafiaTelegramBot/Game/GameRooms/GameRoom.Timer.cs

@@ -1,8 +1,6 @@
 using System;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
 using MafiaTelegramBot.Controllers;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 
 namespace MafiaTelegramBot.Game.GameRooms
@@ -37,7 +35,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                 {
                     case Constants.MINUTES_UNTIL_DISSOLVE - 2:
                         if (Owner != null)
-                            await Bot.SendWithMarkdown2(Owner.ChatId, strings.dissolve_warning);
+                            await MessageController.SendText(Owner.Info, strings.dissolve_warning);
                         else
                             await PlayersMessageChannel.Send(strings.dissolve_warning);
                         _minutes++;

+ 23 - 24
MafiaTelegramBot/Game/Player.cs

@@ -3,11 +3,10 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
+using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections;
 using MafiaTelegramBot.DataBase.Entity;
 using MafiaTelegramBot.Game.GameRoles;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 
 namespace MafiaTelegramBot.Game
@@ -100,8 +99,8 @@ namespace MafiaTelegramBot.Game
                     Achievements.DoctorHeals++;
                     if (Achievements.DoctorHeals == 10)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId, $"{strings.congrats} {roles.Bodyguard}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Bodyguard.ToString()]);
+                        await MessageController.SendText(Info, $"{strings.congrats} {roles.Bodyguard}! {strings.you_can_use}");
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Bodyguard.ToString()]);
                         OpenedRoles.OpenBodyguard();
                     }
                 });
@@ -117,8 +116,8 @@ namespace MafiaTelegramBot.Game
                     Achievements.DoctorHeals++;
                     if (Achievements.DoctorHeals == 50)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId, $"{strings.congrats} {roles.Necromancer}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Necromancer.ToString()]);
+                        await MessageController.SendText(Info, $"{strings.congrats} {roles.Necromancer}! {strings.you_can_use}");
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Necromancer.ToString()]);
                         OpenedRoles.OpenNecromancer();
                     }
                 });
@@ -134,8 +133,8 @@ namespace MafiaTelegramBot.Game
                     Achievements.CopDispatches++;
                     if (Achievements.CopDispatches == 3)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId, $"{strings.congrats} {roles.Fool}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Fool.ToString()]);
+                        await MessageController.SendText(Info, $"{strings.congrats} {roles.Fool}! {strings.you_can_use}");
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Fool.ToString()]);
                         OpenedRoles.OpenFool();
                     }
                 });
@@ -148,9 +147,9 @@ namespace MafiaTelegramBot.Game
             {
                 Task.Run(async () =>
                 {
-                    await Bot.SendWithMarkdown2(Info.ChatId,
+                    await MessageController.SendText(Info,
                         $"{strings.congrats} {roles.Journalist}! {strings.you_can_use}");
-                    await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Journalist.ToString()]);
+                    await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Journalist.ToString()]);
                     OpenedRoles.OpenJournalist();
                 });
             }
@@ -165,9 +164,9 @@ namespace MafiaTelegramBot.Game
                     Achievements.GamesWhereCopCheckOnlyMafia++;
                     if (Achievements.GamesWhereCopCheckOnlyMafia == 3)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId,
+                        await MessageController.SendText(Info,
                             $"{strings.congrats} {roles.Detective}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Detective.ToString()]);
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Detective.ToString()]);
                         OpenedRoles.OpenDetective();
                     }
                 });
@@ -183,9 +182,9 @@ namespace MafiaTelegramBot.Game
                     Achievements.HaveSexWithDon++;
                     if (Achievements.HaveSexWithDon == 5)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId,
+                        await MessageController.SendText(Info,
                             $"{strings.congrats} {roles.Dame}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Dame.ToString()]);
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Dame.ToString()]);
                         OpenedRoles.OpenDame();
                     }
                 }
@@ -201,9 +200,9 @@ namespace MafiaTelegramBot.Game
                     Achievements.NotDispatchedOnSecondStage++;
                     if (Achievements.NotDispatchedOnSecondStage == 2)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId,
+                        await MessageController.SendText(Info,
                             $"{strings.congrats} {roles.Elder}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Elder.ToString()]);
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Elder.ToString()]);
                         OpenedRoles.OpenElder();
                     }
                 }
@@ -219,9 +218,9 @@ namespace MafiaTelegramBot.Game
                     Achievements.MafiaSoloWins++;
                     if (Achievements.MafiaSoloWins == 3)
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId,
+                        await MessageController.SendText(Info,
                             $"{strings.congrats} {roles.Lawyer}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Lawyer.ToString()]);
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Lawyer.ToString()]);
                         OpenedRoles.OpenLawyer();
                     }
                 });
@@ -241,9 +240,9 @@ namespace MafiaTelegramBot.Game
                     else if ((Achievements.PreviousGameWinColor == 1 && color == 2)
                              || (Achievements.PreviousGameWinColor == 2 && color == 1))
                     {
-                        await Bot.SendWithMarkdown2(Info.ChatId,
+                        await MessageController.SendText(Info,
                             $"{strings.congrats} {roles.Werewolf}! {strings.you_can_use}");
-                        await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Werewolf.ToString()]);
+                        await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Werewolf.ToString()]);
                         OpenedRoles.OpenWerewolf();
                     }
                     else
@@ -260,9 +259,9 @@ namespace MafiaTelegramBot.Game
             {
                 Task.Run(async () =>
                 {
-                    await Bot.SendWithMarkdown2(Info.ChatId,
+                    await MessageController.SendText(Info,
                         $"{strings.congrats} {roles.Hooker}! {strings.you_can_use}");
-                    await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Hooker.ToString()]);
+                    await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Hooker.ToString()]);
                     OpenedRoles.OpenHooker();
                 });
             }
@@ -303,9 +302,9 @@ namespace MafiaTelegramBot.Game
                                 if (secondCross.Count == 0) Achievements.PlayerWinTeamTwo = BuildString(team);
                                 else
                                 {
-                                    await Bot.SendWithMarkdown2(Info.ChatId,
+                                    await MessageController.SendText(Info,
                                         $"{strings.congrats} {roles.Parasite}! {strings.you_can_use}");
-                                    await Bot.SendStickerAsync(Info.ChatId, Stickers.Sticker[Roles.Parasite.ToString()]);
+                                    await MessageController.SendSticker(Info, Stickers.Sticker[Roles.Parasite.ToString()]);
                                     OpenedRoles.OpenParasite();
                                 }
                             }

+ 11 - 14
MafiaTelegramBot/Other/GiveAway.cs

@@ -1,12 +1,9 @@
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading.Tasks;
-using MafiaTelegramBot.Commands;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.DataBase.Entity;
 using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Game;
-using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.InputFiles;
@@ -21,9 +18,9 @@ namespace MafiaTelegramBot.Other
         private readonly int _id;
         private readonly string _url;
         private int _count;
+        private UserEntity _chatInfo;
         private readonly List<long> _awardedIdList = new ();
-        private Roles _prize;
-        private long _chatId;
+        private readonly Roles _prize;
         private int _messageId;
         private string _buttonText = "";
 
@@ -36,19 +33,19 @@ namespace MafiaTelegramBot.Other
             OpenedGiveaways.Add(_id, this);
         }
 
-        public async Task<Message> PostGiveAway(long channelId, string buttonText, string message = null, string imageUrl = null, string userName = null)
+        public async Task<Message> PostGiveAway(UserEntity info, string buttonText, string message = null, string imageUrl = null, string userName = null)
         {
-            _chatId = channelId;
             _buttonText = buttonText;
+            _chatInfo = info;
             var keyboard = new InlineKeyboardMarkup(InlineKeyboardButton.WithUrl(_buttonText + $" ({_count})", _url));
             var result = imageUrl == null
-                ? await Bot.SendWithMarkdown2(_chatId, message, keyboard)
-                : await Bot.Get().SendPhotoAsync(_chatId, new InputOnlineFile(imageUrl), message, replyMarkup: keyboard);
+                ? await MessageController.SendText(info, message, keyboard)
+                : await MessageController.SendImage(info, new InputOnlineFile(imageUrl), message, replyMarkup: keyboard);
             _messageId = result.MessageId;
             if (userName == null) return result;
             var adminId = await UserDao.GetIdByUsername(userName);
             var admin = await UserDao.GetPlayerById(adminId);
-            await Bot.SendHyperLink(admin.ChatId, $"<a href='{_url}'>{strings.giveaway_link}</a>");
+            await MessageController.SendTextWithHtml(admin.Info, $"<a href='{_url}'>{strings.giveaway_link}</a>");
             return result;
         }
 
@@ -78,8 +75,8 @@ namespace MafiaTelegramBot.Other
         private static async Task<ResultCode> GivePackToUser(Player player)
         {
             player.Info.PackCount++;
-            await Bot.SendStickerAsync(player.ChatId, Stickers.Sticker["Pool"]);
-            await Bot.SendWithMarkdown2(player.ChatId, $"{strings.your_packs} {player.Info.PackCount}", Keyboard.PackKeyboard(player.Id));
+            await MessageController.SendSticker(player.Info, Stickers.Sticker["Pool"]);
+            await MessageController.SendText(player.Info, $"{strings.your_packs} {player.Info.PackCount}", Keyboard.PackKeyboard());
             return ResultCode.CodeOk;
         }
 
@@ -87,14 +84,14 @@ namespace MafiaTelegramBot.Other
         {
             if (_count == 0)
             {
-                await Bot.Get().EditMessageTextAsync(_chatId, _messageId, strings.giveaway_ended);
+                await MessageController.EditMessage(_chatInfo, _messageId, strings.giveaway_ended);
                 OpenedGiveaways.Remove(_id);
                 _awardedIdList.Clear();
             }
             else
             {
                 var keyboard = new InlineKeyboardMarkup(InlineKeyboardButton.WithUrl(_buttonText + $" ({_count})", _url));
-                await Bot.Get().EditMessageReplyMarkupAsync(_chatId, _messageId, keyboard);
+                await MessageController.EditReplyMarkup(_chatInfo, _messageId, keyboard);
             }
         }
     }

+ 22 - 24
MafiaTelegramBot/Resources/Keyboard.cs

@@ -191,16 +191,16 @@ namespace MafiaTelegramBot.Resources
             }
             if (previousButton && nextButton) inlineButtons[buttonsCount - 1] = new[]
             {
-                InlineKeyboardButton.WithCallbackData(strings.previous, $"{Callback.ConnectToPublicRoom}|{userId}|{page-1}"),
-                InlineKeyboardButton.WithCallbackData(strings.further, $"{Callback.ConnectToPublicRoom}|{userId}|{page+1}"),
+                InlineKeyboardButton.WithCallbackData(strings.previous, $"{Callback.ConnectToPublicRoom}|{page-1}"),
+                InlineKeyboardButton.WithCallbackData(strings.further, $"{Callback.ConnectToPublicRoom}|{page+1}"),
             };
             else if (previousButton) inlineButtons[buttonsCount - 1] = new[]
             {
-                InlineKeyboardButton.WithCallbackData(strings.previous, $"{Callback.ConnectToPublicRoom}|{userId}|{page-1}"),
+                InlineKeyboardButton.WithCallbackData(strings.previous, $"{Callback.ConnectToPublicRoom}|{page-1}"),
             };
             else if (nextButton) inlineButtons[buttonsCount - 1] = new[]
             {
-                InlineKeyboardButton.WithCallbackData(strings.further, $"{Callback.ConnectToPublicRoom}|{userId}|{page+1}"),
+                InlineKeyboardButton.WithCallbackData(strings.further, $"{Callback.ConnectToPublicRoom}|{page+1}"),
             };
             return new InlineKeyboardMarkup(inlineButtons);
         }
@@ -219,54 +219,53 @@ namespace MafiaTelegramBot.Resources
             return new InlineKeyboardMarkup(inlineButtons);
         }
 
-        public static InlineKeyboardMarkup VoteKeyboard(List<Player> players, long userId, bool withSkipButton = true, Callback vote = Callback.Vote)
+        public static InlineKeyboardMarkup VoteKeyboard(List<Player> players, bool withSkipButton = true, Callback vote = Callback.Vote)
         {
             var inlineButtons = new InlineKeyboardButton[withSkipButton ?players.Count+1 :players.Count][];
             for (var i = 0; i<players.Count; ++i)
             {
                 inlineButtons[i] = new[]
                 {
-                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].NickName}", $"{vote}|{userId}|{players[i].Id}")
+                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].Info.NickName}", $"{vote}|{players[i].Info.Id}")
                 };
             }
             if (withSkipButton) inlineButtons[players.Count] = new[]
-                    {InlineKeyboardButton.WithCallbackData(strings.skip, $"{vote}|{userId}|0")};
+                    {InlineKeyboardButton.WithCallbackData(strings.skip, $"{vote}|0")};
             return inlineButtons;
         }
 
-        public static InlineKeyboardMarkup NightChooseTargetKeyboard(List<Player> players, long userId, bool skipButton = false)
+        public static InlineKeyboardMarkup NightChooseTargetKeyboard(List<Player> players, bool skipButton = false)
         {
             var inlineButtons = new InlineKeyboardButton[skipButton ?players.Count+1 : players.Count][];
             for (var i = 0; i<players.Count; ++i)
             {
                 inlineButtons[i] = new[] {
-                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].NickName}", 
-                        $"{Callback.NightTarget}|{userId}|{players[i].Id}")
+                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].Info.NickName}", 
+                        $"{Callback.NightTarget}|{players[i].Info.Id}")
                 };
             }
-
             if (skipButton)
                 inlineButtons[players.Count] = new[] 
-                    { InlineKeyboardButton.WithCallbackData(strings.skip, $"{Callback.NightTarget}|{userId}|-1") };
+                    { InlineKeyboardButton.WithCallbackData(strings.skip, $"{Callback.NightTarget}|-1") };
             return inlineButtons;
         }
 
-        public static InlineKeyboardMarkup DetectiveTargetKeyboard(List<Player> players, long userId)
+        public static InlineKeyboardMarkup DetectiveTargetKeyboard(List<Player> players)
         {
             var inlineButtons = new InlineKeyboardButton[players.Count][];
             for (var i = 0; i<players.Count; ++i)
             {
                 inlineButtons[i] = new[] {
-                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].NickName} ({strings.check})", 
-                        $"{Callback.DetectiveTarget}|{userId}|{players[i].Id}|check"),
-                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].NickName} ({strings.kill})", 
-                        $"{Callback.DetectiveTarget}|{userId}|{players[i].Id}|kill"),
+                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].Info.NickName} ({strings.check})", 
+                        $"{Callback.DetectiveTarget}|{players[i].Info.Id}|check"),
+                    InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) {players[i].Info.NickName} ({strings.kill})", 
+                        $"{Callback.DetectiveTarget}|{players[i].Info.Id}|kill"),
                 };
             }
             return inlineButtons;
         }
 
-        public static InlineKeyboardMarkup NightMafiaTargetKeyboard(List<Player> players, long userId)
+        public static InlineKeyboardMarkup NightMafiaTargetKeyboard(List<Player> players)
         {
             var inlineButtons = new InlineKeyboardButton[players.Count + 1][];
             for (var i = 0; i<players.Count; ++i)
@@ -276,19 +275,18 @@ namespace MafiaTelegramBot.Resources
                 inlineButtons[i] = new[]
                 {
                     InlineKeyboardButton.WithCallbackData($"({players[i].TurnOrder}) " +
-                        $"{players[i].NickName}{(isMafia ? " - " + players[i].GetRoleName() : "")}", 
-                        $"{Callback.MafiaTarget}|{userId}|{players[i].Id}")
+                        $"{players[i].Info.NickName}{(isMafia ? " - " + players[i].GetRoleName() : "")}", 
+                        $"{Callback.MafiaTarget}|{players[i].Info.Id}")
                 };
             }
             inlineButtons[players.Count] = new[] {
-                InlineKeyboardButton.WithCallbackData(strings.skip, $"{Callback.MafiaTarget}|{userId}|-4")
+                InlineKeyboardButton.WithCallbackData(strings.skip, $"{Callback.MafiaTarget}|-4")
             };
             return inlineButtons;
         }
 
         public static InlineKeyboardMarkup SettingsRoomKeyboard(string timerStatus)
         {
-
             return new InlineKeyboardMarkup(new[]
             {
                 new[] { InlineKeyboardButton.WithCallbackData(timerStatus, Callback.SwitchTimer.ToString()) },
@@ -355,11 +353,11 @@ namespace MafiaTelegramBot.Resources
             return new InlineKeyboardMarkup(keyboard);
         }
 
-        public static InlineKeyboardMarkup ContinueButton(long userId)
+        public static InlineKeyboardMarkup ContinueButton()
         {
             return new InlineKeyboardMarkup(new[]
                 {
-                    InlineKeyboardButton.WithCallbackData(strings._continue, $"{Callback.Continue}|{userId}")
+                    InlineKeyboardButton.WithCallbackData(strings._continue, $"{Callback.Continue}")
                 }
             );
         }