Browse Source

Merge remote-tracking branch 'origin/develop' into develop

zelpold 4 years ago
parent
commit
e733cd4a7f

+ 6 - 3
MafiaTelegramBot.sln.DotSettings.user

@@ -10,13 +10,16 @@
   </TestAncestor>
 &lt;/SessionState&gt;</s:String>
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002Fappsettings/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Fkeyboard/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Froles/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Fstrings/@EntryIndexedValue">True</s:Boolean>
+	
+	
+	
 	
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Fkeyboard/@EntryIndexedValue">False</s:Boolean>
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Froles/@EntryIndexedValue">False</s:Boolean>
 	
 	
 	
-	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002FResources_002Fstrings/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002Fstrings/@EntryIndexedValue">True</s:Boolean>
 	
 	<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean>

+ 10 - 0
MafiaTelegramBot/Controllers/RoomController.cs

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Game;
 using MafiaTelegramBot.Game.GameRoles;
 using MafiaTelegramBot.Game.GameRooms;
@@ -25,6 +26,9 @@ namespace MafiaTelegramBot.Controllers
                     : new NormalGameRoom {Owner = creator, RoomName = roomName, IsPrivate = isPrivate};
                 OpenedGames.Add(roomKey, room);
                 room.Players.Add(creator.Id, creator);
+
+                UserDao.GetPlayerById(creator.Id).Result.StopTimer();
+                
                 return ResultCode.CodeOk;
             });
         }
@@ -39,6 +43,9 @@ namespace MafiaTelegramBot.Controllers
                 if (OpenedGames[roomKey].IsFilled()) return ResultCode.RoomIsFilled;
                 if (!player.SetRoomName(roomName)) return ResultCode.UserAlreadyInGame;
                 OpenedGames[roomKey].Players.Add(player.Id, player);
+                
+                UserDao.GetPlayerById(player.Id).Result.StopTimer();
+                
                 await OpenedGames[roomKey].PlayersCh.SendExcept(player.Id, $"{player.NickName} {strings.connected_to_game}");
                 return ResultCode.CodeOk;
             });
@@ -62,6 +69,9 @@ namespace MafiaTelegramBot.Controllers
                 player.CurrentRole = new NoneRole();
                 player.TurnOrder = -1;
                 OpenedGames[roomKey].Players.Remove(player.Id);
+                
+                UserDao.GetPlayerById(player.Id).Result.StartTimer();
+                
                 var message = OpenedGames[roomKey].Owner.Id == player.Id
                     ? $"{player.NickName} \\({strings.room_owner}\\) {strings.leave_from_game}"
                     : $"{player.NickName} {strings.leave_from_game}";

+ 45 - 0
MafiaTelegramBot/DataBase/Entity/OpenedRolesEntity.cs

@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using MafiaTelegramBot.Resources;
+
+namespace MafiaTelegramBot.DataBase.Entity
+{
+    [Table("opened_roles")]
+    public class OpenedRolesEntity
+    {
+        [Key]
+        [DatabaseGenerated(DatabaseGeneratedOption.None)]
+        [Column("id"), MaxLength(127)] public long Id { get; init; }
+
+        [Column("bodyguard") , MaxLength(127)] public bool Bodyguard { get; init; }
+        [Column("dame") , MaxLength(127)] public bool Dame { get; init; }
+        [Column("detective") , MaxLength(127)] public bool Detective { get; init; }
+        [Column("elder") , MaxLength(127)] public bool Elder { get; init; }
+        [Column("fool") , MaxLength(127)] public bool Fool { get; init; }
+        [Column("hooker") , MaxLength(127)] public bool Hooker { get; init; }
+        [Column("journalist") , MaxLength(127)] public bool Journalist { get; init; }
+        [Column("lawyer") , MaxLength(127)] public bool Lawyer { get; init; }
+        [Column("necromancer") , MaxLength(127)] public bool Necromancer { get; init; }
+        [Column("parasite") , MaxLength(127)] public bool Parasite { get; init; }
+        [Column("werewolf") , MaxLength(127)] public bool Werewolf { get; init; }
+        
+        public List<Roles> ToList()
+        {
+            var list = new List<Roles> {Roles.Don, Roles.Doctor, Roles.Cop};
+            if(Bodyguard) list.Add(Roles.Bodyguard);
+            if(Dame) list.Add(Roles.Dame);
+            if(Detective) list.Add(Roles.Detective);
+            if(Elder) list.Add(Roles.Elder);
+            if(Fool) list.Add(Roles.Fool);
+            if(Hooker) list.Add(Roles.Hooker);
+            if(Journalist) list.Add(Roles.Journalist);
+            if(Lawyer) list.Add(Roles.Lawyer);
+            if(Necromancer) list.Add(Roles.Necromancer);
+            if(Parasite) list.Add(Roles.Parasite);
+            if(Werewolf) list.Add(Roles.Werewolf);
+            return list;
+        }
+    }
+}

+ 28 - 0
MafiaTelegramBot/DataBase/EntityDao/OpenedRolesDao.cs

@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase.Entity;
+using MafiaTelegramBot.Resources;
+using Microsoft.EntityFrameworkCore;
+
+namespace MafiaTelegramBot.DataBase.EntityDao
+{
+    public static class OpenedRolesDao
+    {
+        private static readonly MafiaDataBase DataBase = MafiaDataBase.GetInstance();
+
+        public static async Task<OpenedRolesEntity> GetOpenedRolesById(long id)
+        {
+            if (await UserDataExists(id))
+                return await Task.Run(() => DataBase.OpenedRoles.First(entity => entity.Id == id));
+            await DataBase.OpenedRoles.AddAsync(new OpenedRolesEntity {Id = id});
+            await DataBase.SaveChangesAsync();
+            return await Task.Run(()=> DataBase.OpenedRoles.First(entity => entity.Id == id));
+        }
+
+        private static async Task<bool> UserDataExists(long id)
+        {
+            return await DataBase.OpenedRoles.AnyAsync(entity => entity.Id == id);
+        }
+    }
+}

+ 2 - 2
MafiaTelegramBot/DataBase/EntityDao/StatisticsDao.cs

@@ -7,9 +7,9 @@ namespace MafiaTelegramBot.DataBase.EntityDao
     {
         private static readonly MafiaDataBase DataBase = MafiaDataBase.GetInstance();
         
-        public static async Task Update(StatisticsEntity statistics)
+        public static Task Update(StatisticsEntity statistics)
         {
-            
+            return Task.CompletedTask;
         }
     }
 }

+ 2 - 0
MafiaTelegramBot/DataBase/EntityDao/UserDao.cs

@@ -16,7 +16,9 @@ namespace MafiaTelegramBot.DataBase.EntityDao
             if (ActiveUsers.ContainsKey(id)) return ActiveUsers[id];
             var user = await Task.Run(()=> DataBase.Users.First(user1 => user1.Id == id));
             var player = Player.FromUserEntity(user);
+            player.OpenedRoles = await OpenedRolesDao.GetOpenedRolesById(id);
             ActiveUsers.Add(user.Id, player);
+            ActiveUsers[user.Id].SetTimer();
             return player;
         }
         

+ 24 - 0
MafiaTelegramBot/DataBase/MafiaDataBase.cs

@@ -22,6 +22,7 @@ namespace MafiaTelegramBot.DataBase
         
         public DbSet<UserEntity> Users { get; set; }
         public DbSet<StatisticsEntity> Statistics { get; set; }
+        public DbSet<OpenedRolesEntity> OpenedRoles { get; set; }
 
         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
         {
@@ -38,6 +39,29 @@ namespace MafiaTelegramBot.DataBase
         {
             modelBuilder.Entity<StatisticsEntity>()
                 .HasKey(s => new {s.UserId, s.Role});
+
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Bodyguard).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Dame).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Detective).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Elder).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Fool).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Hooker).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Journalist).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Lawyer).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Necromancer).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Parasite).HasDefaultValue(0);
+            modelBuilder.Entity<OpenedRolesEntity>()
+                .Property(r => r.Werewolf).HasDefaultValue(0);
         }
     }
 }

+ 2 - 2
MafiaTelegramBot/Game/GameRoles/BodyguardRole.cs

@@ -14,7 +14,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task NightAction()
         {
             var targets = Room.Players.Values.Where(p => p.IsAlive && p.Id != Player.Id).ToList();
-            var message = await Bot.SendWithMarkdown2(Player.ChatId, strings.choose_player_to_block_night, 
+            var message = await Bot.SendWithMarkdown2(Player.ChatId, strings.choose_target_to_protect, 
                 Keyboard.NightChooseTargetKeyboard(targets, Player.Id, true));
             MessageId = message.MessageId;
         }
@@ -33,7 +33,7 @@ namespace MafiaTelegramBot.Game.GameRoles
                     target.IsAlive = true;
                     Player.IsAlive = false;
                     await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.you_save_player} {target.NickName}");
-                    await Bot.SendWithMarkdown2(target.ChatId, strings.doctor_save_you);
+                    await Bot.SendWithMarkdown2(target.ChatId, strings.bodyguard_save_you);
                 }
             }
             

+ 35 - 2
MafiaTelegramBot/Game/GameRooms/ExtendedGameRoom.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Resources;
 
@@ -8,6 +9,8 @@ namespace MafiaTelegramBot.Game.GameRooms
     {
         public override bool IsExtended { get; protected set; } = true;
 
+        public Dictionary<Roles, int> CustomRoomSettings = new();
+
         public override Dictionary<Roles, List<Player>> PlayersRole { get; set; } = new()
         {
             //passive roles
@@ -30,9 +33,39 @@ namespace MafiaTelegramBot.Game.GameRooms
             [Roles.Werewolf] = new List<Player>(),
         };
 
-        protected override Task ReadSettings()
+        protected override async Task<ResultCode> ReadSettings()
+        {
+            return await Task.Run(() =>
+            {
+                var rolesCount = CustomRoomSettings.Values.Sum();
+                if (rolesCount != Players.Count) return ResultCode.RolesNotEqualPlayers;
+                Settings = CustomRoomSettings.ToDictionary(k=>k.Key, k=>k.Value);
+                return ResultCode.CodeOk;
+            });
+        }
+
+        public async Task InitSettings()
         {
-            throw new System.NotImplementedException();
+            await Task.Run(() =>
+            {
+                CustomRoomSettings.Add(Roles.Villager, Players.Count);
+                CustomRoomSettings.Add(Roles.Cop, 1);
+                if (Players.Count != 8) CustomRoomSettings.Add(Roles.Doctor, 1);
+                if (Players.Count % 3 == 0)
+                    CustomRoomSettings.Add(Roles.Mafia, Players.Count/3);
+                else
+                {
+                    CustomRoomSettings.Add(Roles.Mafia, Players.Count/3 -1);
+                    CustomRoomSettings.Add(Roles.Don, 1);
+                }
+                foreach (var (key, value) in CustomRoomSettings)
+                {
+                    if (key != Roles.Villager)
+                        CustomRoomSettings[Roles.Villager] -= value;
+                }
+                if (CustomRoomSettings[Roles.Mafia] < 1) CustomRoomSettings.Remove(Roles.Mafia);
+                if (CustomRoomSettings[Roles.Villager] < 1) CustomRoomSettings.Remove(Roles.Villager);
+            });
         }
     }
 }

+ 10 - 7
MafiaTelegramBot/Game/GameRooms/GameRoom.GameProcess.cs

@@ -4,6 +4,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.CustomCollections.Extensions;
+using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
@@ -39,7 +40,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                     var player = _turnOrder.Dequeue();
                     if(!player.IsPlaying) continue;
                     await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
-                    await player.CurrentRole.OneMinuteSpeak();
+                    await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
+                    await player.CurrentRole.SpeakAction();
                     if (firstPlayer != null && player.IsPlaying) _turnOrder.Enqueue(player);
                     else firstPlayer = player;
                 }
@@ -115,7 +117,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                 if(!player.IsPlaying || !player.IsAlive) continue;
                 if (firstPlayer == null) player.IsFirst = true;
                 await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
-                await player.CurrentRole.OneMinuteSpeak();
+                await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
+                await player.CurrentRole.SpeakAction();
                 await player.CurrentRole.VotingAction();
                 if (player.IsFirst) firstPlayer = player;
                 else _turnOrder.Enqueue(player);
@@ -194,14 +197,11 @@ namespace MafiaTelegramBot.Game.GameRooms
             return await Task.Run( async () =>
             {
                 var contendersForDispatch = _voteUpList.Where(p => p.VotedCount == _largeVote).ToList();
+                foreach (var defender in _voteUpList) defender.VotedCount = 0;
                 _voteUpList.Clear();
                 _largeVote = 0;
                 if (contendersForDispatch.Count == 1) return contendersForDispatch;
-                foreach (var defender in _voteUpList)
-                {
-                    defender.VotedCount = 0;
-                    await defender.CurrentRole.DefenceAction();
-                }
+                foreach (var defender in contendersForDispatch) await defender.CurrentRole.DefenceAction();
                 var votersPlayers = Players.Values
                     .Where(p => p.IsAlive)
                     .Except(contendersForDispatch)
@@ -273,6 +273,9 @@ namespace MafiaTelegramBot.Game.GameRooms
                     rolesMessage += $"\n\\({player.TurnOrder}\\) {player.NickName} - {player.GetRoleName()}";
                     player.ResetState();
                 }
+
+                //var dblist = UserDao.DataBase.Statistics.Where(s => sortedPLayers.Contains(s.UserId, s.Role.ToString())).ToList();
+                
                 await PlayersCh.Send(rolesMessage);
                 IsRunning = false;
                 IsDay = false;

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

@@ -21,7 +21,8 @@ namespace MafiaTelegramBot.Game.GameRooms
         {
             var resultCode = CanStartGame();
             if (resultCode != ResultCode.CodeOk) return resultCode;
-            await ReadSettings();
+            resultCode = await ReadSettings();
+            if (resultCode != ResultCode.CodeOk) return resultCode;
             await GenerateTurnOrder();
             await AssignRoles();
             return resultCode;
@@ -78,6 +79,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                 await Bot.SendWithMarkdown2(player.ChatId, message, Keyboard.InGamePlayerMenu);
             }
         }
-        protected abstract Task ReadSettings();
+
+        protected abstract Task<ResultCode> ReadSettings();
     }
 }

+ 24 - 20
MafiaTelegramBot/Game/GameRooms/GameRoom.Role.cs

@@ -38,24 +38,27 @@ namespace MafiaTelegramBot.Game.GameRooms
             
             public virtual async Task Dispatch()
             {
-                await Room.PlayersCh.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
-                await OneMinuteSpeak();
-                await Kill();
+                if (Room.PlayersRole.ContainsKey(Roles.Hooker)
+                    && Room.PlayersRole[Roles.Hooker].Count == 1 
+                    && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id)
+                {
+                    await Room.PlayersCh.SendExcept(Player.Id, $"{strings.villagers_want_dispatch} {Player.NickName}, {strings.player_not_died_he_has_alibi}");
+                }
+                else
+                {
+                    await Room.PlayersCh.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
+                    await Bot.SendWithMarkdown2(Player.ChatId, strings.you_turn_say);
+                    await SpeakAction(enableTimer: true);
+                    await Kill();
+                }
             }
 
             public virtual async Task Kill()
             {
-                if (Room.PlayersRole.ContainsKey(Roles.Hooker) &&
-                    Room.PlayersRole[Roles.Hooker].Count == 1 && !Room.IsDay)
-                {
-                    var hooker = Room.PlayersRole[Roles.Hooker][0];
-                    if (hooker.CurrentRole.NightTargetId == Player.Id) await hooker.CurrentRole.Kill();
-                    else
-                    {
-                        Player.IsAlive = false;
-                        await Bot.SendWithMarkdown2(Player.ChatId, strings.you_died);
-                    }
-                }
+                if (Room.PlayersRole.ContainsKey(Roles.Hooker)
+                    && Room.PlayersRole[Roles.Hooker].Count == 1
+                    && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id
+                    && !Room.IsDay) await Room.PlayersRole[Roles.Hooker][0].CurrentRole.Kill();
                 else
                 {
                     Player.IsAlive = false;
@@ -74,16 +77,16 @@ namespace MafiaTelegramBot.Game.GameRooms
                 return NightTargetId;
             }
 
-            public async Task OneMinuteSpeak()
+            public async Task SpeakAction(int seconds = 60, bool enableTimer = false)
             {
                 TalkingActionComplete.Reset();
-                await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.your_turn}\n{strings.you_turn_say}", Keyboard.InGamePlayerMenuWithEndTurn);
+                await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.your_turn}", Keyboard.InGamePlayerMenuWithEndTurn);
                 Player.IsSpeaker = true;
-                var timer = new Timer(60 * 1000) {AutoReset = false};
+                var timer = new Timer(seconds * 1000) {AutoReset = false};
                 timer.Elapsed += (_, _) => TalkingActionComplete.Set();
-                timer.Start();
+                if (Room.TimerEnabled || enableTimer) timer.Start();
                 TalkingActionComplete.WaitOne();
-                timer.Stop();
+                if (Room.TimerEnabled || enableTimer) timer.Stop();
                 await Bot.SendWithMarkdown2(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
                 Player.IsSpeaker = false;
             }
@@ -119,7 +122,8 @@ namespace MafiaTelegramBot.Game.GameRooms
             public async Task DefenceAction()
             {
                 await Room.PlayersCh.SendExcept(Player.Id, $"{strings.now_defence} \\({Player.TurnOrder}\\) {Player.NickName}");
-                await OneMinuteSpeak();
+                await Bot.SendWithMarkdown2(Player.ChatId, strings.you_have_eigty_seconds_to_defence);
+                await SpeakAction(90);
             }
             public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)
             {

+ 1 - 1
MafiaTelegramBot/Game/GameRooms/GameRoom.Structure.cs

@@ -30,7 +30,7 @@ namespace MafiaTelegramBot.Game.GameRooms
 
         public readonly Dictionary<long, Player> Players = new();
 
-        protected readonly Dictionary<Roles, int> Settings = new();
+        protected Dictionary<Roles, int> Settings = new();
 
         public abstract Dictionary<Roles, List<Player>> PlayersRole { get; set; }
         

+ 2 - 1
MafiaTelegramBot/Game/GameRooms/NormalGameRoom.cs

@@ -19,7 +19,7 @@ namespace MafiaTelegramBot.Game.GameRooms
             [Roles.Doctor] = new List<Player>(),
         };
 
-        protected override async Task ReadSettings()
+        protected override async Task<ResultCode> ReadSettings()
         {
             await Task.Run(() =>
             {
@@ -41,6 +41,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                 if (Settings[Roles.Mafia] < 1) Settings.Remove(Roles.Mafia);
                 if (Settings[Roles.Villager] < 1) Settings.Remove(Roles.Villager);
             });
+            return ResultCode.CodeOk;
         }
     }
 }

+ 45 - 2
MafiaTelegramBot/Game/Player.cs

@@ -19,10 +19,13 @@ namespace MafiaTelegramBot.Game
         public GameRooms.GameRoom.Role CurrentRole = new NoneRole();
         public int TurnOrder = -1;
         private string _roomName = "";
-        public bool IsAlive = true;
+
+        private static System.Timers.Timer ActiveTime;
         public bool IsSpeaker;
         public bool IsPlaying;
         public bool IsFirst;
+        
+        public bool IsAlive = true;
         public bool CanBeHealed = true;
         public bool IsBlocked = false;
         public bool CanBeBlockedNight = true;
@@ -30,6 +33,7 @@ namespace MafiaTelegramBot.Game
         public int VotedCount = 0; //количество голосов за игрока
 
         public readonly StatisticsList Statistics = new();
+        public OpenedRolesEntity OpenedRoles = new();
 
         public async Task<bool> LoadStatistics()
         {
@@ -38,9 +42,48 @@ namespace MafiaTelegramBot.Game
             {
                 Statistics.Add(Enum.Parse<Roles>(role.Role),role);
             }
-
             return true;
         }
+
+        public async Task SetTimer()
+        {
+            ActiveTime = new System.Timers.Timer(3600000);
+            ActiveTime.Elapsed += async (x , y) =>
+            {
+                await Remove();
+            };
+            ActiveTime.Enabled = true;
+        }
+
+        public async Task Restart()
+        {
+            ActiveTime.Stop();
+            ActiveTime.Start();
+        }
+
+        public async Task StopTimer()
+        {
+            ActiveTime.Stop();
+        }
+
+        public async Task StartTimer()
+        {
+            ActiveTime.Start();
+        }
+
+        private async Task Remove()
+        {
+            try
+            {
+                UserDao.ActiveUsers.Remove(Id);
+                ActiveTime.Dispose();
+            }
+            catch (Exception)
+            {
+                await Console.Out.WriteLineAsync("Cant delete user!");
+            }
+            //await Bot.SendHyperLink(ChatId, "Inactive now!");
+        }
         
         public static Player FromUserEntity(UserEntity b)
         {

+ 4 - 3
MafiaTelegramBot/Models/Bot.cs

@@ -78,6 +78,7 @@ namespace MafiaTelegramBot.Models
                 new SwitchTimerQuery(),
                 new ChangeRolesQuery(),
                 new PlayersCountSettingsQuery(),
+                new ApplyRolesChangeQuery(),
             };
         }
         
@@ -127,13 +128,13 @@ namespace MafiaTelegramBot.Models
                 return new Message();
             }
         }
-        
-        public static async Task<Message> EditMessageAsync(long chatId, int messageId, string message)
+
+        public static async Task<Message> EditMessageAsync(long chatId, int messageId, string message, InlineKeyboardMarkup keyboard = null)
         {
             try
             {
                 var editedMessage = await Utilities.ToMarkdownString(message);
-                return await Get().EditMessageTextAsync(chatId, messageId, editedMessage, parseMode:ParseMode.MarkdownV2);
+                return await Get().EditMessageTextAsync(chatId, messageId, editedMessage, ParseMode.MarkdownV2, replyMarkup: keyboard);
             }
             catch (Exception e)
             {

+ 1 - 0
MafiaTelegramBot/Models/Commands/Command.cs

@@ -34,6 +34,7 @@ namespace MafiaTelegramBot.Models.Commands
             var startCommand = new StartCommand();
             //TODO refactor later
             if (message.Contains(startCommand.Name)) return await ((Command?) startCommand.Clone(chatId, userId))!.Execute(update);
+            await UserDao.GetPlayerById(userId).Result.Restart();
             var user = await UserDao.GetPlayerById(userId);
             if (user.IsPlaying)
             {

+ 49 - 0
MafiaTelegramBot/Models/Inlines/ApplyRolesChangeQuery.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Threading.Tasks;
+using MafiaTelegramBot.Controllers;
+using MafiaTelegramBot.Game.GameRooms;
+using MafiaTelegramBot.Resources;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Inlines
+{
+    public class ApplyRolesChangeQuery : Query
+    {
+        protected override Callback Name => Callback.ApplyRolesChange;
+        private ExtendedGameRoom _room;
+        protected override async Task<Message> Execute(Update update)
+        {
+            var data = update.CallbackQuery.Data.Split('|');
+            var roomKey = data[2];
+            _room = (ExtendedGameRoom) RoomController.GetRoom(roomKey);
+            var roleQuery = Enum.Parse<Roles>(data[3]);
+            if(roleQuery is Roles.Villager or Roles.Mafia) MafiaVillager(roleQuery, data[4]);
+            else SwitchRole(roleQuery);
+            var message = $"{strings.current_enabled_roles}\n";
+            foreach (var (role, count) in _room.CustomRoomSettings)
+                message += $"| {roles.ResourceManager.GetString(role.ToString())} \\({count}\\) |";
+            return await Bot.EditMessageAsync(ChatId, update.CallbackQuery.Message.MessageId, message, Keyboard.ChangeRolesKeyboard(UserId, roomKey, _room));
+        }
+
+        private void MafiaVillager(Roles role, string action)
+        {
+            switch (action)
+            {
+                case "+":
+                    if(!_room.CustomRoomSettings.ContainsKey(role)) _room.CustomRoomSettings.Add(role, 1);
+                    else if(_room.CustomRoomSettings[role] < _room.MaxPlayers) _room.CustomRoomSettings[role]++;
+                    break;
+                case "-":
+                    if (_room.CustomRoomSettings[role] > 1) _room.CustomRoomSettings[role]--;
+                    else _room.CustomRoomSettings.Remove(role);
+                    break;
+            }
+        }
+
+        private void SwitchRole(Roles role)
+        {
+            if (_room.CustomRoomSettings.ContainsKey(role)) _room.CustomRoomSettings.Remove(role);
+            else _room.CustomRoomSettings.Add(role, 1);
+        }
+    }
+}

+ 10 - 20
MafiaTelegramBot/Models/Inlines/ChangeRolesQuery.cs

@@ -1,4 +1,3 @@
-using System.Security.AccessControl;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.DataBase.EntityDao;
@@ -16,25 +15,16 @@ namespace MafiaTelegramBot.Models.Inlines
         {
             var user = await UserDao.GetPlayerById(UserId);
             var roomKey = RoomEncrypter.GetCode(user.GetRoomName());
-            var room = RoomController.GetRoom(roomKey);
-            var message = $"{strings.current_enabled_roles}" +
-                          $"\n{roles.Elder} - {strings.disabled}" +
-                          $"\n{roles.Fool} - {strings.disabled}" +
-                          $"\n{roles.Hooker} - {strings.enabled}" +
-                          $"\n{roles.Parasite} - {strings.disabled}" +
-                          $"\n{roles.Don} - {strings.enabled}" +
-                          $"\n{roles.Dame} - {strings.disabled}" +
-                          $"\n{roles.Cop} - {strings.enabled}" +
-                          $"\n{roles.Journalist} - {strings.disabled}" +
-                          $"\n{roles.Detective} - {strings.disabled}" +
-                          $"\n{roles.Lawyer} - {strings.disabled}" +
-                          $"\n{roles.Bodyguard} - {strings.disabled}" +
-                          $"\n{roles.Doctor} - {strings.disabled}" +
-                          $"\n{roles.Necromancer} - {strings.enabled}" +
-                          $"\n{roles.Werewolf} - {strings.enabled}" +
-                          $"\n{roles.Mafia} - 1" +
-                          $"\n{roles.Villager} - 3";
-            return await Bot.SendWithMarkdown2(ChatId, message, Keyboard.ChangeRolesKeyboard(UserId, roomKey, (ExtendedGameRoom)room));
+            var room = (ExtendedGameRoom) RoomController.GetRoom(roomKey);
+            if(room.CustomRoomSettings.Count == 0) await room.InitSettings();
+            var message = $"{strings.current_enabled_roles}\n| ";
+            foreach (var (role, count) in room.CustomRoomSettings)
+            {
+                if (role is Roles.Mafia) message += $"{roles.Mafia} \\({count}\\) | ";
+                if (role is Roles.Villager) message += $"{roles.Villager} \\({count}\\) | ";
+                else message += $"{roles.ResourceManager.GetString(role.ToString())} \\({count}\\) | ";
+            }
+            return await Bot.SendWithMarkdown2(ChatId, message, Keyboard.ChangeRolesKeyboard(UserId, roomKey, room));
         }
     }
 }

+ 25 - 48
MafiaTelegramBot/Resources/Keyboard.cs

@@ -188,54 +188,31 @@ namespace MafiaTelegramBot.Resources
 
         public static InlineKeyboardMarkup ChangeRolesKeyboard(long userId, string roomKey, ExtendedGameRoom room)
         {
-            return new( new[]
-            {
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Mafia}-", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Mafia}+", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Villager}-", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Villager}+", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Elder} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Fool} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Hooker} (1)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Parasite} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Don} (1)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Dame} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Cop} (1)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Journalist} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Detective} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Lawyer} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Bodyguard} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Doctor} (0)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-                new[]
-                {
-                    InlineKeyboardButton.WithCallbackData($"{roles.Necromancer} (1)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                    InlineKeyboardButton.WithCallbackData($"{roles.Werewolf} (1)", $"{Callback.ApplyRolesChange}|{userId}|{roomKey}"),
-                },
-            });
+            var openedRoles = room.Owner.OpenedRoles.ToList();
+            var keyboard = new InlineKeyboardButton[2+openedRoles.Count][];
+            keyboard[0] = new[]
+            {
+                InlineKeyboardButton.WithCallbackData($"{roles.Mafia}-",
+                    $"{Callback.ApplyRolesChange}|{userId}|{roomKey}|{Roles.Mafia}|-"),
+                InlineKeyboardButton.WithCallbackData($"{roles.Mafia}+",
+                    $"{Callback.ApplyRolesChange}|{userId}|{roomKey}|{Roles.Mafia}|+"),
+            };
+            keyboard[1] = new[]
+            {
+                InlineKeyboardButton.WithCallbackData($"{roles.Villager}-",
+                    $"{Callback.ApplyRolesChange}|{userId}|{roomKey}|{Roles.Villager}|-"),
+                InlineKeyboardButton.WithCallbackData($"{roles.Villager}+",
+                    $"{Callback.ApplyRolesChange}|{userId}|{roomKey}|{Roles.Villager}|+"),
+            };
+            for (var i = 0; i < openedRoles.Count; ++i)
+            {
+                var contain = room.CustomRoomSettings.ContainsKey(openedRoles[i]);
+                    keyboard[2+i] = new []{ InlineKeyboardButton.WithCallbackData(
+                        $"{roles.ResourceManager.GetString(openedRoles[i].ToString())} ({(contain ? 1 : 0)})",
+                        $"{Callback.ApplyRolesChange}|{userId}|{roomKey}|{openedRoles[i]}"
+                        )};
+            }
+            return keyboard;
         }
     }
 }

+ 1 - 0
MafiaTelegramBot/Resources/ResultCode.cs

@@ -10,6 +10,7 @@ namespace MafiaTelegramBot.Resources
         UserNotInGame,
         RoomIsFilled,
         RoomDoesNotExist,
+        RolesNotEqualPlayers,
         CodeOk,
     }
 }

+ 290 - 677
MafiaTelegramBot/Resources/strings.Designer.cs

@@ -1,7 +1,6 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -12,46 +11,32 @@ namespace MafiaTelegramBot {
     using System;
     
     
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     internal class strings {
         
-        private static global::System.Resources.ResourceManager resourceMan;
+        private static System.Resources.ResourceManager resourceMan;
         
-        private static global::System.Globalization.CultureInfo resourceCulture;
+        private static System.Globalization.CultureInfo resourceCulture;
         
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         internal strings() {
         }
         
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static System.Resources.ResourceManager ResourceManager {
             get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MafiaTelegramBot.Resources.strings", typeof(strings).Assembly);
+                if (object.Equals(null, resourceMan)) {
+                    System.Resources.ResourceManager temp = new System.Resources.ResourceManager("MafiaTelegramBot.Resources.strings", typeof(strings).Assembly);
                     resourceMan = temp;
                 }
                 return resourceMan;
             }
         }
         
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static System.Globalization.CultureInfo Culture {
             get {
                 return resourceCulture;
             }
@@ -60,1191 +45,819 @@ namespace MafiaTelegramBot {
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Приватная.
-        /// </summary>
-        internal static string _private {
+        internal static string start_message {
             get {
-                return ResourceManager.GetString("private", resourceCulture);
+                return ResourceManager.GetString("start_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Публичная.
-        /// </summary>
-        internal static string _public {
+        internal static string statistics_for {
             get {
-                return ResourceManager.GetString("public", resourceCulture);
+                return ResourceManager.GetString("statistics_for", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Действие заблокировано.
-        /// </summary>
-        internal static string activity_blocked {
+        internal static string games_count {
             get {
-                return ResourceManager.GetString("activity_blocked", resourceCulture);
+                return ResourceManager.GetString("games_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to живой.
-        /// </summary>
-        internal static string alive {
+        internal static string wins_count {
             get {
-                return ResourceManager.GetString("alive", resourceCulture);
+                return ResourceManager.GetString("wins_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Этой ночью был убит.
-        /// </summary>
-        internal static string at_this_night {
+        internal static string winrate {
             get {
-                return ResourceManager.GetString("at_this_night", resourceCulture);
+                return ResourceManager.GetString("winrate", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Телохранитель защищает вас сегодня.
-        /// </summary>
-        internal static string bodyguard_protected_you {
+        internal static string shop {
             get {
-                return ResourceManager.GetString("bodyguard_protected_you", resourceCulture);
+                return ResourceManager.GetString("shop", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Телохранитель спас вас.
-        /// </summary>
-        internal static string bodyguard_save_you {
+        internal static string my_roles {
             get {
-                return ResourceManager.GetString("bodyguard_save_you", resourceCulture);
+                return ResourceManager.GetString("my_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра начинается....
-        /// </summary>
-        internal static string bot_starting_game {
+        internal static string settings {
             get {
-                return ResourceManager.GetString("bot_starting_game", resourceCulture);
+                return ResourceManager.GetString("settings", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to но он оказался старейшийной.
-        /// </summary>
-        internal static string but_he_is_elder {
+        internal static string your_name {
             get {
-                return ResourceManager.GetString("but_he_is_elder", resourceCulture);
+                return ResourceManager.GetString("your_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сменить имя.
-        /// </summary>
         internal static string change_name {
             get {
                 return ResourceManager.GetString("change_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Изменить рассадку.
-        /// </summary>
-        internal static string change_roles {
+        internal static string enter_your_name {
             get {
-                return ResourceManager.GetString("change_roles", resourceCulture);
+                return ResourceManager.GetString("enter_your_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите режим игры.
-        /// </summary>
-        internal static string choose_game_type {
+        internal static string name_updated {
             get {
-                return ResourceManager.GetString("choose_game_type", resourceCulture);
+                return ResourceManager.GetString("name_updated", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите цель для блокировки.
-        /// </summary>
-        internal static string choose_player_to_block_night {
+        internal static string command_not_found {
             get {
-                return ResourceManager.GetString("choose_player_to_block_night", resourceCulture);
+                return ResourceManager.GetString("command_not_found", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для проверки роли.
-        /// </summary>
-        internal static string choose_player_to_check_role {
+        internal static string settings_room {
             get {
-                return ResourceManager.GetString("choose_player_to_check_role", resourceCulture);
+                return ResourceManager.GetString("settings_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для лечения.
-        /// </summary>
-        internal static string choose_player_to_heal {
+        internal static string choose_game_type {
             get {
-                return ResourceManager.GetString("choose_player_to_heal", resourceCulture);
+                return ResourceManager.GetString("choose_game_type", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите свою жертву.
-        /// </summary>
-        internal static string choose_player_to_kill {
+        internal static string enter_room_name {
             get {
-                return ResourceManager.GetString("choose_player_to_kill", resourceCulture);
+                return ResourceManager.GetString("enter_room_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите тип комнаты.
-        /// </summary>
-        internal static string choose_type_room {
+        internal static string room_with_name {
             get {
-                return ResourceManager.GetString("choose_type_room", resourceCulture);
+                return ResourceManager.GetString("room_with_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Город засыпает.
-        /// </summary>
-        internal static string city_falls_asleep {
+        internal static string was_created {
             get {
-                return ResourceManager.GetString("city_falls_asleep", resourceCulture);
+                return ResourceManager.GetString("was_created", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Город просыпается и обнаруживает, что... .
-        /// </summary>
-        internal static string city_wakes_up {
+        internal static string unexpected_error {
             get {
-                return ResourceManager.GetString("city_wakes_up", resourceCulture);
+                return ResourceManager.GetString("unexpected_error", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Команда не найдена.
-        /// </summary>
-        internal static string command_not_found {
+        internal static string game_already_exists {
             get {
-                return ResourceManager.GetString("command_not_found", resourceCulture);
+                return ResourceManager.GetString("game_already_exists", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to подключился к игре.
-        /// </summary>
-        internal static string connected_to_game {
+        internal static string leave_from_game {
             get {
-                return ResourceManager.GetString("connected_to_game", resourceCulture);
+                return ResourceManager.GetString("leave_from_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Текущая рассадка в комнате:.
-        /// </summary>
-        internal static string current_enabled_roles {
+        internal static string user_not_in_game {
             get {
-                return ResourceManager.GetString("current_enabled_roles", resourceCulture);
+                return ResourceManager.GetString("user_not_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Дама заблокировала вас. Вы не сможете разговаривать и голосовать в этот день..
-        /// </summary>
-        internal static string dame_block_you {
+        internal static string standart {
             get {
-                return ResourceManager.GetString("dame_block_you", resourceCulture);
+                return ResourceManager.GetString("standart", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to никого не выставил на голосование.
-        /// </summary>
-        internal static string didnt_put_anyone {
+        internal static string extended {
             get {
-                return ResourceManager.GetString("didnt_put_anyone", resourceCulture);
+                return ResourceManager.GetString("extended", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to мертвый.
-        /// </summary>
-        internal static string died {
+        internal static string secret_key_is {
             get {
-                return ResourceManager.GetString("died", resourceCulture);
+                return ResourceManager.GetString("secret_key_is", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Отключить.
-        /// </summary>
-        internal static string disable {
+        internal static string choose_type_room {
             get {
-                return ResourceManager.GetString("disable", resourceCulture);
+                return ResourceManager.GetString("choose_type_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to отключен.
-        /// </summary>
-        internal static string disabled {
+        internal static string enter_private_code {
             get {
-                return ResourceManager.GetString("disabled", resourceCulture);
+                return ResourceManager.GetString("enter_private_code", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Доктор вылечил вас.
-        /// </summary>
-        internal static string doctor_heals_you {
+        internal static string room_is_filled {
             get {
-                return ResourceManager.GetString("doctor_heals_you", resourceCulture);
+                return ResourceManager.GetString("room_is_filled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Доктор спас вас от смерти.
-        /// </summary>
-        internal static string doctor_save_you {
+        internal static string user_already_in_game {
             get {
-                return ResourceManager.GetString("doctor_save_you", resourceCulture);
+                return ResourceManager.GetString("user_already_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Включить.
-        /// </summary>
-        internal static string enable {
+        internal static string successful_entry_into_room {
             get {
-                return ResourceManager.GetString("enable", resourceCulture);
+                return ResourceManager.GetString("successful_entry_into_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to включен.
-        /// </summary>
-        internal static string enabled {
+        internal static string users_list {
             get {
-                return ResourceManager.GetString("enabled", resourceCulture);
+                return ResourceManager.GetString("users_list", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите код от комнаты.
-        /// </summary>
-        internal static string enter_private_code {
+        internal static string users_list_empty {
             get {
-                return ResourceManager.GetString("enter_private_code", resourceCulture);
+                return ResourceManager.GetString("users_list_empty", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите название комнаты.
-        /// </summary>
-        internal static string enter_room_name {
+        internal static string max_capacity_message {
             get {
-                return ResourceManager.GetString("enter_room_name", resourceCulture);
+                return ResourceManager.GetString("max_capacity_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите ваше имя.
-        /// </summary>
-        internal static string enter_your_name {
+        internal static string prefer_leave_from_room {
             get {
-                return ResourceManager.GetString("enter_your_name", resourceCulture);
+                return ResourceManager.GetString("prefer_leave_from_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to все игроки остались в живых!.
-        /// </summary>
-        internal static string everyone_survived {
+        internal static string room_does_not_exists {
             get {
-                return ResourceManager.GetString("everyone_survived", resourceCulture);
+                return ResourceManager.GetString("room_does_not_exists", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Расширенный.
-        /// </summary>
-        internal static string extended {
+        internal static string public_rooms_are_not_exist {
             get {
-                return ResourceManager.GetString("extended", resourceCulture);
+                return ResourceManager.GetString("public_rooms_are_not_exist", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Пока мирные жители спали, в городе завелась мафия. Город собрался на главной площади и жители решают, кто среди них предатель..
-        /// </summary>
-        internal static string first_day_message {
+        internal static string rooms {
             get {
-                return ResourceManager.GetString("first_day_message", resourceCulture);
+                return ResourceManager.GetString("rooms", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната с таким именем уже существует.
-        /// </summary>
-        internal static string game_already_exists {
+        internal static string too_many_players {
             get {
-                return ResourceManager.GetString("game_already_exists", resourceCulture);
+                return ResourceManager.GetString("too_many_players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра уже запущена.
-        /// </summary>
-        internal static string game_already_running {
+        internal static string too_few_players {
             get {
-                return ResourceManager.GetString("game_already_running", resourceCulture);
+                return ResourceManager.GetString("too_few_players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Процесс подготовки комнаты начался.
-        /// </summary>
-        internal static string game_process_started {
+        internal static string game_already_running {
             get {
-                return ResourceManager.GetString("game_process_started", resourceCulture);
+                return ResourceManager.GetString("game_already_running", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Число игр:.
-        /// </summary>
-        internal static string games_count {
+        internal static string minimum_players_count {
             get {
-                return ResourceManager.GetString("games_count", resourceCulture);
+                return ResourceManager.GetString("minimum_players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Проститутка переспала с вами. Ваши действия этой ночью ограничены..
-        /// </summary>
-        internal static string hooker_block_you {
+        internal static string maximum_players_count {
             get {
-                return ResourceManager.GetString("hooker_block_you", resourceCulture);
+                return ResourceManager.GetString("maximum_players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В этой игре участвовали:.
-        /// </summary>
-        internal static string in_this_game_roles {
+        internal static string maximum_was_set_to {
             get {
-                return ResourceManager.GetString("in_this_game_roles", resourceCulture);
+                return ResourceManager.GetString("maximum_was_set_to", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to выдается посмертная минута..
-        /// </summary>
-        internal static string issued_posthumous_minute {
+        internal static string players {
             get {
-                return ResourceManager.GetString("issued_posthumous_minute", resourceCulture);
+                return ResourceManager.GetString("players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Исключить.
-        /// </summary>
         internal static string kick {
             get {
                 return ResourceManager.GetString("kick", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Исключить пользователя.
-        /// </summary>
         internal static string kick_user {
             get {
                 return ResourceManager.GetString("kick_user", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to покинул игру.
-        /// </summary>
-        internal static string leave_from_game {
+        internal static string you_were_kicked {
             get {
-                return ResourceManager.GetString("leave_from_game", resourceCulture);
+                return ResourceManager.GetString("you_were_kicked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ссылка для подключения к комнате.
-        /// </summary>
-        internal static string link {
+        internal static string room_dissolved {
             get {
-                return ResourceManager.GetString("link", resourceCulture);
+                return ResourceManager.GetString("room_dissolved", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В первую ночь мафия получает список соучастников..
-        /// </summary>
-        internal static string mafia_get_mail {
+        internal static string timer {
             get {
-                return ResourceManager.GetString("mafia_get_mail", resourceCulture);
+                return ResourceManager.GetString("timer", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Мафия не смогла договориться..
-        /// </summary>
-        internal static string mafia_not_agree {
+        internal static string enabled {
             get {
-                return ResourceManager.GetString("mafia_not_agree", resourceCulture);
+                return ResourceManager.GetString("enabled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ура! Победила мафия....
-        /// </summary>
-        internal static string mafia_won {
+        internal static string disabled {
             get {
-                return ResourceManager.GetString("mafia_won", resourceCulture);
+                return ResourceManager.GetString("disabled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимальное кол-во игроков.
-        /// </summary>
-        internal static string max_capacity_message {
+        internal static string enable {
             get {
-                return ResourceManager.GetString("max_capacity_message", resourceCulture);
+                return ResourceManager.GetString("enable", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимум - 16 игроков.
-        /// </summary>
-        internal static string maximum_players_count {
+        internal static string disable {
             get {
-                return ResourceManager.GetString("maximum_players_count", resourceCulture);
+                return ResourceManager.GetString("disable", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимум был установлен на.
-        /// </summary>
-        internal static string maximum_was_set_to {
+        internal static string _public {
             get {
-                return ResourceManager.GetString("maximum_was_set_to", resourceCulture);
+                return ResourceManager.GetString("public", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Минимум - 6 игроков.
-        /// </summary>
-        internal static string minimum_players_count {
+        internal static string _private {
             get {
-                return ResourceManager.GetString("minimum_players_count", resourceCulture);
+                return ResourceManager.GetString("private", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to -.
-        /// </summary>
-        internal static string minus {
+        internal static string bot_starting_game {
             get {
-                return ResourceManager.GetString("minus", resourceCulture);
+                return ResourceManager.GetString("bot_starting_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Мои роли.
-        /// </summary>
-        internal static string my_roles {
+        internal static string game_process_started {
             get {
-                return ResourceManager.GetString("my_roles", resourceCulture);
+                return ResourceManager.GetString("game_process_started", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Имя было обновлено на.
-        /// </summary>
-        internal static string name_updated {
+        internal static string connected_to_game {
             get {
-                return ResourceManager.GetString("name_updated", resourceCulture);
+                return ResourceManager.GetString("connected_to_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Данная команда не поддерживается во время игры.
-        /// </summary>
-        internal static string not_supported_in_game {
+        internal static string your_turn_order {
             get {
-                return ResourceManager.GetString("not_supported_in_game", resourceCulture);
+                return ResourceManager.GetString("your_turn_order", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вам некого лечить этой ночью.
-        /// </summary>
-        internal static string nothing_to_heal {
+        internal static string your_role {
             get {
-                return ResourceManager.GetString("nothing_to_heal", resourceCulture);
+                return ResourceManager.GetString("your_role", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас оправдывается.
-        /// </summary>
-        internal static string now_defence {
+        internal static string thanks_for_game {
             get {
-                return ResourceManager.GetString("now_defence", resourceCulture);
+                return ResourceManager.GetString("thanks_for_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас не ваш ход.
-        /// </summary>
-        internal static string now_is_not_your_turn {
+        internal static string link {
             get {
-                return ResourceManager.GetString("now_is_not_your_turn", resourceCulture);
+                return ResourceManager.GetString("link", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас ходит.
-        /// </summary>
-        internal static string now_turn {
+        internal static string you_leave_from_game {
             get {
-                return ResourceManager.GetString("now_turn", resourceCulture);
+                return ResourceManager.GetString("you_leave_from_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас вы не можете разговаривать.
-        /// </summary>
-        internal static string now_you_cant_speak {
+        internal static string your_teammates {
             get {
-                return ResourceManager.GetString("now_you_cant_speak", resourceCulture);
+                return ResourceManager.GetString("your_teammates", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to игроков.
-        /// </summary>
-        internal static string players {
+        internal static string first_day_message {
             get {
-                return ResourceManager.GetString("players", resourceCulture);
+                return ResourceManager.GetString("first_day_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Количество игроков.
-        /// </summary>
-        internal static string players_count {
+        internal static string city_falls_asleep {
             get {
-                return ResourceManager.GetString("players_count", resourceCulture);
+                return ResourceManager.GetString("city_falls_asleep", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Список игроков.
-        /// </summary>
-        internal static string players_list {
+        internal static string now_turn {
             get {
-                return ResourceManager.GetString("players_list", resourceCulture);
+                return ResourceManager.GetString("now_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to +.
-        /// </summary>
-        internal static string plus {
+        internal static string your_turn_ended {
             get {
-                return ResourceManager.GetString("plus", resourceCulture);
+                return ResourceManager.GetString("your_turn_ended", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сначала покиньте комнату.
-        /// </summary>
-        internal static string prefer_leave_from_room {
+        internal static string now_is_not_your_turn {
             get {
-                return ResourceManager.GetString("prefer_leave_from_room", resourceCulture);
+                return ResourceManager.GetString("now_is_not_your_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Нет свободных публичных комнат.
-        /// </summary>
-        internal static string public_rooms_are_not_exist {
+        internal static string your_turn {
             get {
-                return ResourceManager.GetString("public_rooms_are_not_exist", resourceCulture);
+                return ResourceManager.GetString("your_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Кого вы хотите выставить на голосование?.
-        /// </summary>
-        internal static string put_up_vote {
+        internal static string players_list {
             get {
-                return ResourceManager.GetString("put_up_vote", resourceCulture);
+                return ResourceManager.GetString("players_list", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Роль игрока.
-        /// </summary>
-        internal static string role_of_your_target {
+        internal static string you_now_died {
             get {
-                return ResourceManager.GetString("role_of_your_target", resourceCulture);
+                return ResourceManager.GetString("you_now_died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната распущена.
-        /// </summary>
-        internal static string room_dissolved {
+        internal static string villagers_are_sleep {
             get {
-                return ResourceManager.GetString("room_dissolved", resourceCulture);
+                return ResourceManager.GetString("villagers_are_sleep", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната не существует.
-        /// </summary>
-        internal static string room_does_not_exists {
+        internal static string mafia_get_mail {
             get {
-                return ResourceManager.GetString("room_does_not_exists", resourceCulture);
+                return ResourceManager.GetString("mafia_get_mail", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната заполнена.
-        /// </summary>
-        internal static string room_is_filled {
+        internal static string alive {
             get {
-                return ResourceManager.GetString("room_is_filled", resourceCulture);
+                return ResourceManager.GetString("alive", resourceCulture);
+            }
+        }
+        
+        internal static string died {
+            get {
+                return ResourceManager.GetString("died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to владелец комнаты.
-        /// </summary>
         internal static string room_owner {
             get {
                 return ResourceManager.GetString("room_owner", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната с именем.
-        /// </summary>
-        internal static string room_with_name {
+        internal static string put_up_vote {
             get {
-                return ResourceManager.GetString("room_with_name", resourceCulture);
+                return ResourceManager.GetString("put_up_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комнаты.
-        /// </summary>
-        internal static string rooms {
+        internal static string didnt_put_anyone {
             get {
-                return ResourceManager.GetString("rooms", resourceCulture);
+                return ResourceManager.GetString("didnt_put_anyone", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Секретный код для подключения к комнате.
-        /// </summary>
-        internal static string secret_key_is {
+        internal static string skip {
             get {
-                return ResourceManager.GetString("secret_key_is", resourceCulture);
+                return ResourceManager.GetString("skip", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Настройки.
-        /// </summary>
-        internal static string settings {
+        internal static string user_not_choose {
             get {
-                return ResourceManager.GetString("settings", resourceCulture);
+                return ResourceManager.GetString("user_not_choose", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Задайте настройки комнаты.
-        /// </summary>
-        internal static string settings_room {
+        internal static string not_supported_in_game {
             get {
-                return ResourceManager.GetString("settings_room", resourceCulture);
+                return ResourceManager.GetString("not_supported_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Магазин.
-        /// </summary>
-        internal static string shop {
+        internal static string you_skip_vote {
             get {
-                return ResourceManager.GetString("shop", resourceCulture);
+                return ResourceManager.GetString("you_skip_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Пропустить.
-        /// </summary>
-        internal static string skip {
+        internal static string you_vote_player {
             get {
-                return ResourceManager.GetString("skip", resourceCulture);
+                return ResourceManager.GetString("you_vote_player", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Стандартный.
-        /// </summary>
-        internal static string standart {
+        internal static string vote_to {
             get {
-                return ResourceManager.GetString("standart", resourceCulture);
+                return ResourceManager.GetString("vote_to", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Что вы хотите сделать?.
-        /// </summary>
-        internal static string start_message {
+        internal static string vote_to_self {
             get {
-                return ResourceManager.GetString("start_message", resourceCulture);
+                return ResourceManager.GetString("vote_to_self", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Статистика для.
-        /// </summary>
-        internal static string statistics_for {
+        internal static string you_vote_to_self {
             get {
-                return ResourceManager.GetString("statistics_for", resourceCulture);
+                return ResourceManager.GetString("you_vote_to_self", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были добавлены в комнату.
-        /// </summary>
-        internal static string successful_entry_into_room {
+        internal static string choose_player_to_check_role {
             get {
-                return ResourceManager.GetString("successful_entry_into_room", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_check_role", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра окончена, спасибо за игру!.
-        /// </summary>
-        internal static string thanks_for_game {
+        internal static string you_have_not_choosen_target {
             get {
-                return ResourceManager.GetString("thanks_for_game", resourceCulture);
+                return ResourceManager.GetString("you_have_not_choosen_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Время вышло.
-        /// </summary>
-        internal static string time_out {
+        internal static string you_choose_target {
             get {
-                return ResourceManager.GetString("time_out", resourceCulture);
+                return ResourceManager.GetString("you_choose_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Таймер.
-        /// </summary>
-        internal static string timer {
+        internal static string role_of_your_target {
             get {
-                return ResourceManager.GetString("timer", resourceCulture);
+                return ResourceManager.GetString("role_of_your_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игроку.
-        /// </summary>
-        internal static string to_player {
+        internal static string choose_player_to_heal {
             get {
-                return ResourceManager.GetString("to_player", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_heal", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Недостаточно игроков для старта игры.
-        /// </summary>
-        internal static string too_few_players {
+        internal static string you_turn_say {
             get {
-                return ResourceManager.GetString("too_few_players", resourceCulture);
+                return ResourceManager.GetString("you_turn_say", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Количество игроков превышает максимальное.
-        /// </summary>
-        internal static string too_many_players {
+        internal static string doctor_heals_you {
             get {
-                return ResourceManager.GetString("too_many_players", resourceCulture);
+                return ResourceManager.GetString("doctor_heals_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Произошла неожиданная ошибка... Попробуйте ещё раз..
-        /// </summary>
-        internal static string unexpected_error {
+        internal static string dame_block_you {
             get {
-                return ResourceManager.GetString("unexpected_error", resourceCulture);
+                return ResourceManager.GetString("dame_block_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы уже находитесь в игре.
-        /// </summary>
-        internal static string user_already_in_game {
+        internal static string hooker_block_you {
             get {
-                return ResourceManager.GetString("user_already_in_game", resourceCulture);
+                return ResourceManager.GetString("hooker_block_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Иначе вы будете выставлены на голосование.
-        /// </summary>
-        internal static string user_not_choose {
+        internal static string you_save_player {
             get {
-                return ResourceManager.GetString("user_not_choose", resourceCulture);
+                return ResourceManager.GetString("you_save_player", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы не находитесь сейчас в игре.
-        /// </summary>
-        internal static string user_not_in_game {
+        internal static string nothing_to_heal {
             get {
-                return ResourceManager.GetString("user_not_in_game", resourceCulture);
+                return ResourceManager.GetString("nothing_to_heal", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Участники в комнате.
-        /// </summary>
-        internal static string users_list {
+        internal static string doctor_save_you {
             get {
-                return ResourceManager.GetString("users_list", resourceCulture);
+                return ResourceManager.GetString("doctor_save_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В комнате нет игроков, кроме Вас.
-        /// </summary>
-        internal static string users_list_empty {
+        internal static string at_this_night {
             get {
-                return ResourceManager.GetString("users_list_empty", resourceCulture);
+                return ResourceManager.GetString("at_this_night", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Жители ночью спят, а не разговаривают!.
-        /// </summary>
-        internal static string villagers_are_sleep {
+        internal static string city_wakes_up {
             get {
-                return ResourceManager.GetString("villagers_are_sleep", resourceCulture);
+                return ResourceManager.GetString("city_wakes_up", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Жители так и не смогли решить кого казнить....
-        /// </summary>
-        internal static string villagers_could_not_decide {
+        internal static string everyone_survived {
             get {
-                return ResourceManager.GetString("villagers_could_not_decide", resourceCulture);
+                return ResourceManager.GetString("everyone_survived", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Жители хотели повесить игрока.
-        /// </summary>
-        internal static string villagers_want_dispatch {
+        internal static string you_have_ten_seconds {
             get {
-                return ResourceManager.GetString("villagers_want_dispatch", resourceCulture);
+                return ResourceManager.GetString("you_have_ten_seconds", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ура! Победили мирные жители....
-        /// </summary>
-        internal static string villagers_won {
+        internal static string choose_player_to_kill {
             get {
-                return ResourceManager.GetString("villagers_won", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_kill", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to проголосовал против.
-        /// </summary>
-        internal static string vote_to {
+        internal static string villagers_won {
             get {
-                return ResourceManager.GetString("vote_to", resourceCulture);
+                return ResourceManager.GetString("villagers_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to выставил самого себя..
-        /// </summary>
-        internal static string vote_to_self {
+        internal static string mafia_won {
             get {
-                return ResourceManager.GetString("vote_to_self", resourceCulture);
+                return ResourceManager.GetString("mafia_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to была создана.
-        /// </summary>
-        internal static string was_created {
+        internal static string in_this_game_roles {
             get {
-                return ResourceManager.GetString("was_created", resourceCulture);
+                return ResourceManager.GetString("in_this_game_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Что вы хотите настроить?.
-        /// </summary>
-        internal static string what_settings {
+        internal static string now_defence {
             get {
-                return ResourceManager.GetString("what_settings", resourceCulture);
+                return ResourceManager.GetString("now_defence", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to был убит.
-        /// </summary>
-        internal static string will_be_killed {
+        internal static string time_out {
             get {
-                return ResourceManager.GetString("will_be_killed", resourceCulture);
+                return ResourceManager.GetString("time_out", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to был воскрешен.
-        /// </summary>
-        internal static string will_be_ressurected {
+        internal static string villagers_could_not_decide {
             get {
-                return ResourceManager.GetString("will_be_ressurected", resourceCulture);
+                return ResourceManager.GetString("villagers_could_not_decide", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Винрейт:.
-        /// </summary>
-        internal static string winrate {
+        internal static string to_player {
             get {
-                return ResourceManager.GetString("winrate", resourceCulture);
+                return ResourceManager.GetString("to_player", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Число побед:.
-        /// </summary>
-        internal static string wins_count {
+        internal static string issued_posthumous_minute {
             get {
-                return ResourceManager.GetString("wins_count", resourceCulture);
+                return ResourceManager.GetString("issued_posthumous_minute", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы заблокированы.
-        /// </summary>
-        internal static string you_blocked {
+        internal static string you_died {
             get {
-                return ResourceManager.GetString("you_blocked", resourceCulture);
+                return ResourceManager.GetString("you_died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выбрали игрока.
-        /// </summary>
-        internal static string you_choose_target {
+        internal static string villagers_want_dispatch {
             get {
-                return ResourceManager.GetString("you_choose_target", resourceCulture);
+                return ResourceManager.GetString("villagers_want_dispatch", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы убиты.
-        /// </summary>
-        internal static string you_died {
+        internal static string but_he_is_elder {
             get {
-                return ResourceManager.GetString("you_died", resourceCulture);
+                return ResourceManager.GetString("but_he_is_elder", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы не выбрали цель.
-        /// </summary>
-        internal static string you_have_not_choosen_target {
+        internal static string activity_blocked {
             get {
-                return ResourceManager.GetString("you_have_not_choosen_target", resourceCulture);
+                return ResourceManager.GetString("activity_blocked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У вас есть десять секунд, чтобы выставить игрока на голосование.
-        /// </summary>
-        internal static string you_have_ten_seconds {
+        internal static string mafia_not_agree {
             get {
-                return ResourceManager.GetString("you_have_ten_seconds", resourceCulture);
+                return ResourceManager.GetString("mafia_not_agree", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы вылечили сами себя.
-        /// </summary>
         internal static string you_heal_yourself {
             get {
                 return ResourceManager.GetString("you_heal_yourself", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы покинули игру.
-        /// </summary>
-        internal static string you_leave_from_game {
+        internal static string you_save_yourself {
             get {
-                return ResourceManager.GetString("you_leave_from_game", resourceCulture);
+                return ResourceManager.GetString("you_save_yourself", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы мертвы и не можете говорить!.
-        /// </summary>
-        internal static string you_now_died {
+        internal static string change_roles {
             get {
-                return ResourceManager.GetString("you_now_died", resourceCulture);
+                return ResourceManager.GetString("change_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы спасли игрока.
-        /// </summary>
-        internal static string you_save_player {
+        internal static string players_count {
             get {
-                return ResourceManager.GetString("you_save_player", resourceCulture);
+                return ResourceManager.GetString("players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы спасли себя.
-        /// </summary>
-        internal static string you_save_yourself {
+        internal static string what_settings {
             get {
-                return ResourceManager.GetString("you_save_yourself", resourceCulture);
+                return ResourceManager.GetString("what_settings", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы пропустили голосование.
-        /// </summary>
-        internal static string you_skip_vote {
+        internal static string minus {
             get {
-                return ResourceManager.GetString("you_skip_vote", resourceCulture);
+                return ResourceManager.GetString("minus", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У Вас есть минута, чтобы что-то сказать.
-        /// </summary>
-        internal static string you_turn_say {
+        internal static string plus {
             get {
-                return ResourceManager.GetString("you_turn_say", resourceCulture);
+                return ResourceManager.GetString("plus", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выбрали игрока.
-        /// </summary>
-        internal static string you_vote_player {
+        internal static string current_enabled_roles {
             get {
-                return ResourceManager.GetString("you_vote_player", resourceCulture);
+                return ResourceManager.GetString("current_enabled_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выставили самого себя.
-        /// </summary>
-        internal static string you_vote_to_self {
+        internal static string choose_player_to_block_night {
             get {
-                return ResourceManager.GetString("you_vote_to_self", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_block_night", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были исключены.
-        /// </summary>
-        internal static string you_were_kicked {
+        internal static string you_blocked {
             get {
-                return ResourceManager.GetString("you_were_kicked", resourceCulture);
+                return ResourceManager.GetString("you_blocked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваше имя:.
-        /// </summary>
-        internal static string your_name {
+        internal static string now_you_cant_speak {
             get {
-                return ResourceManager.GetString("your_name", resourceCulture);
+                return ResourceManager.GetString("now_you_cant_speak", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваша роль.
-        /// </summary>
-        internal static string your_role {
+        internal static string will_be_ressurected {
             get {
-                return ResourceManager.GetString("your_role", resourceCulture);
+                return ResourceManager.GetString("will_be_ressurected", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Команда мафии на эту игру:.
-        /// </summary>
-        internal static string your_teammates {
+        internal static string will_be_killed {
             get {
-                return ResourceManager.GetString("your_teammates", resourceCulture);
+                return ResourceManager.GetString("will_be_killed", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваш ход.
-        /// </summary>
-        internal static string your_turn {
+        internal static string bodyguard_protected_you {
             get {
-                return ResourceManager.GetString("your_turn", resourceCulture);
+                return ResourceManager.GetString("bodyguard_protected_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваш ход закончился.
-        /// </summary>
-        internal static string your_turn_ended {
+        internal static string bodyguard_save_you {
             get {
-                return ResourceManager.GetString("your_turn_ended", resourceCulture);
+                return ResourceManager.GetString("bodyguard_save_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы ходите под номером.
-        /// </summary>
-        internal static string your_turn_order {
+        internal static string choose_target_to_protect {
             get {
-                return ResourceManager.GetString("your_turn_order", resourceCulture);
+                return ResourceManager.GetString("choose_target_to_protect", resourceCulture);
+            }
+        }
+        
+        internal static string players_not_equal_roles {
+            get {
+                return ResourceManager.GetString("players_not_equal_roles", resourceCulture);
+            }
+        }
+        
+        internal static string you_have_eigty_seconds_to_defence {
+            get {
+                return ResourceManager.GetString("you_have_eigty_seconds_to_defence", resourceCulture);
+            }
+        }
+        
+        internal static string player_not_died_he_has_alibi {
+            get {
+                return ResourceManager.GetString("player_not_died_he_has_alibi", resourceCulture);
             }
         }
     }

+ 12 - 0
MafiaTelegramBot/Resources/strings.resx

@@ -414,4 +414,16 @@
     <data name="bodyguard_save_you" xml:space="preserve">
         <value>Телохранитель спас вас</value>
     </data>
+    <data name="choose_target_to_protect" xml:space="preserve">
+        <value>Выберите цель для защиты</value>
+    </data>
+    <data name="players_not_equal_roles" xml:space="preserve">
+        <value>Количество игроков не равно количеству ролей</value> 
+    </data>
+    <data name="you_have_eigty_seconds_to_defence" xml:space="preserve">
+        <value>У вас есть 90 секунд на оправдание</value>
+    </data>
+    <data name="player_not_died_he_has_alibi" xml:space="preserve">
+        <value>но у него есть алиби</value>
+    </data>
 </root>

+ 2 - 1
MafiaTelegramBot/Utilities.cs

@@ -22,6 +22,7 @@ namespace MafiaTelegramBot
                 ResultCode.UserNotInGame => Bot.SendWithMarkdown2(chatId, strings.user_not_in_game),
                 ResultCode.RoomIsFilled => Bot.SendWithMarkdown2(chatId, strings.room_is_filled),
                 ResultCode.RoomDoesNotExist => Bot.SendWithMarkdown2(chatId, strings.room_does_not_exists),
+                ResultCode.RolesNotEqualPlayers => Bot.SendWithMarkdown2(chatId, strings.players_not_equal_roles),
                 _ => Bot.SendWithMarkdown2(chatId, strings.unexpected_error)
             };
         }
@@ -35,6 +36,7 @@ namespace MafiaTelegramBot
                     .Replace("#", "\\#")
                     .Replace("[", "\\[")
                     .Replace("]", "\\]")
+                    .Replace("|", "\\|")
                     .Replace("!", "\\!")
                     .Replace("-", "\\-");
                 return newStr;
@@ -56,7 +58,6 @@ namespace MafiaTelegramBot
                         .Replace(">", "\\>")
                         .Replace("+", "\\+")
                         .Replace("=", "\\=")
-                        .Replace("|", "\\|")
                         .Replace("{", "\\{")
                         .Replace("}", "\\}")
                         .Replace("@", "\\@")