Browse Source

Merge branch 'develop' of https://gogs.veloe.link/Veloe/MafiaTelegramBot into develop

zelpold 4 years ago
parent
commit
785c256a0f
43 changed files with 946 additions and 1034 deletions
  1. 8 8
      MafiaTelegramBot.sln.DotSettings.user
  2. 3 5
      MafiaTelegramBot/Controllers/MessageController.cs
  3. 6 0
      MafiaTelegramBot/CustomCollections/Extensions/ListExtension.cs
  4. 1 1
      MafiaTelegramBot/CustomCollections/StatisticsList.cs
  5. 7 0
      MafiaTelegramBot/DataBase/Entity/OpenedRolesEntity.cs
  6. 1 1
      MafiaTelegramBot/Game/GameRoles/BodyguardRole.cs
  7. 4 2
      MafiaTelegramBot/Game/GameRoles/CopRole.cs
  8. 3 10
      MafiaTelegramBot/Game/GameRoles/DameRole.cs
  9. 3 2
      MafiaTelegramBot/Game/GameRoles/DetectiveRole.cs
  10. 1 1
      MafiaTelegramBot/Game/GameRoles/DoctorRole.cs
  11. 4 10
      MafiaTelegramBot/Game/GameRoles/DonRole.cs
  12. 1 1
      MafiaTelegramBot/Game/GameRoles/ElderRole.cs
  13. 1 1
      MafiaTelegramBot/Game/GameRoles/FoolRole.cs
  14. 4 2
      MafiaTelegramBot/Game/GameRoles/HookerRole.cs
  15. 1 1
      MafiaTelegramBot/Game/GameRoles/JournalistRole.cs
  16. 3 2
      MafiaTelegramBot/Game/GameRoles/LawyerRole.cs
  17. 4 14
      MafiaTelegramBot/Game/GameRoles/MafiaRole.cs
  18. 4 5
      MafiaTelegramBot/Game/GameRoles/NecromancerRole.cs
  19. 1 1
      MafiaTelegramBot/Game/GameRoles/NoneRole.cs
  20. 5 1
      MafiaTelegramBot/Game/GameRoles/ParasiteRole.cs
  21. 1 1
      MafiaTelegramBot/Game/GameRoles/VillagerRole.cs
  22. 4 7
      MafiaTelegramBot/Game/GameRoles/WerewolfRole.cs
  23. 50 4
      MafiaTelegramBot/Game/GameRooms/ExtendedGameRoom.cs
  24. 97 32
      MafiaTelegramBot/Game/GameRooms/GameRoom.GameProcess.cs
  25. 37 14
      MafiaTelegramBot/Game/GameRooms/GameRoom.MessageHandler.cs
  26. 2 0
      MafiaTelegramBot/Game/GameRooms/GameRoom.QueryHandler.cs
  27. 33 19
      MafiaTelegramBot/Game/GameRooms/GameRoom.Role.cs
  28. 1 1
      MafiaTelegramBot/Game/GameRooms/NormalGameRoom.cs
  29. 18 6
      MafiaTelegramBot/Models/Bot.cs
  30. 11 5
      MafiaTelegramBot/Models/Commands/ShowProfileCommand.cs
  31. 65 11
      MafiaTelegramBot/Models/Inlines/ApplyRolesChangeQuery.cs
  32. 9 2
      MafiaTelegramBot/Models/Inlines/ShopMenuQuery.cs
  33. 26 1
      MafiaTelegramBot/Models/Inlines/ShowMyRolesQuery.cs
  34. 29 0
      MafiaTelegramBot/Models/Payments/Payment.cs
  35. 15 0
      MafiaTelegramBot/Models/Payments/RandomRolePayment.cs
  36. 0 22
      MafiaTelegramBot/Models/Replies/Reply.cs
  37. 10 1
      MafiaTelegramBot/Resources/Constants.cs
  38. 4 1
      MafiaTelegramBot/Resources/Keyboard.cs
  39. 7 0
      MafiaTelegramBot/Resources/Payloads.cs
  40. 2 0
      MafiaTelegramBot/Resources/ResultCode.cs
  41. 414 837
      MafiaTelegramBot/Resources/strings.Designer.cs
  42. 44 2
      MafiaTelegramBot/Resources/strings.resx
  43. 2 0
      MafiaTelegramBot/Utilities.cs

+ 8 - 8
MafiaTelegramBot.sln.DotSettings.user

@@ -1,13 +1,13 @@
 <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=0ea868fa_002D7cf8_002D466b_002Dbf25_002Dc540fc960a6b/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="Killing_Player_In_Summing_Up_Phase #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
-  &lt;TestAncestor&gt;&#xD;
-    &lt;TestId&gt;xUnit::BB1857E4-418E-4AE5-8437-43EBD1D903FB::net5.0::MafiaTelegramBotTests.Game.Tests.GameRooms.Tests.GameRoomTests&lt;/TestId&gt;&#xD;
-  &lt;/TestAncestor&gt;&#xD;
+	<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=0ea868fa_002D7cf8_002D466b_002Dbf25_002Dc540fc960a6b/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="Killing_Player_In_Summing_Up_Phase #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
+  &lt;TestAncestor&gt;
+    &lt;TestId&gt;xUnit::BB1857E4-418E-4AE5-8437-43EBD1D903FB::net5.0::MafiaTelegramBotTests.Game.Tests.GameRooms.Tests.GameRoomTests&lt;/TestId&gt;
+  &lt;/TestAncestor&gt;
 &lt;/SessionState&gt;</s:String>
-	<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=fbf9be8e_002Dabe2_002D485d_002Dbae0_002D5fd4fbd8c901/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="Killing_Player_In_Summing_Up_Phase" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
-  &lt;TestAncestor&gt;&#xD;
-    &lt;TestId&gt;xUnit::BB1857E4-418E-4AE5-8437-43EBD1D903FB::net5.0::MafiaTelegramBotTests.Game.Tests.GameRooms.Tests.GameRoomTests.Killing_Player_In_Summing_Up_Phase&lt;/TestId&gt;&#xD;
-  &lt;/TestAncestor&gt;&#xD;
+	<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=fbf9be8e_002Dabe2_002D485d_002Dbae0_002D5fd4fbd8c901/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="Killing_Player_In_Summing_Up_Phase" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
+  &lt;TestAncestor&gt;
+    &lt;TestId&gt;xUnit::BB1857E4-418E-4AE5-8437-43EBD1D903FB::net5.0::MafiaTelegramBotTests.Game.Tests.GameRooms.Tests.GameRoomTests.Killing_Player_In_Summing_Up_Phase&lt;/TestId&gt;
+  &lt;/TestAncestor&gt;
 &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">False</s:Boolean>

+ 3 - 5
MafiaTelegramBot/Controllers/MessageController.cs

@@ -1,9 +1,9 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
+using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Models.Commands;
 using MafiaTelegramBot.Models.Inlines;
-using MafiaTelegramBot.Models.Replies;
 using Telegram.Bot;
 using Telegram.Bot.Exceptions;
 using Telegram.Bot.Types;
@@ -20,11 +20,9 @@ namespace MafiaTelegramBot.Controllers
             {
                 var handle = update.Type switch
                 {
-                    UpdateType.Message => update.Message.ReplyToMessage != null &&
-                                          update.Message.ReplyToMessage.Text != strings.start_message
-                        ? Reply.Update(update)
-                        : Command.Update(update),
+                    UpdateType.Message => Command.Update(update),
                     UpdateType.CallbackQuery => Query.Update(update),
+                    UpdateType.PreCheckoutQuery => Bot.AnswerPreCheckoutQuery(update.PreCheckoutQuery.Id),
                     _ => UnknownUpdateHandlerAsync(update)
                 };
                 await handle;

+ 6 - 0
MafiaTelegramBot/CustomCollections/Extensions/ListExtension.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Linq;
 
 namespace MafiaTelegramBot.CustomCollections.Extensions
 {
@@ -27,5 +28,10 @@ namespace MafiaTelegramBot.CustomCollections.Extensions
             list.Add(item);
             return true;
         }
+
+        public static void ConcatenateUnique<T>(this List<T> list, List<T> list2)
+        {
+            foreach (var item in list2.Where(item => !list.Contains(item))) list.Add(item);
+        }
     }
 }

+ 1 - 1
MafiaTelegramBot/CustomCollections/StatisticsList.cs

@@ -10,7 +10,7 @@ namespace MafiaTelegramBot.CustomCollections
 
         public StatisticsEntity this[Roles role]
         {
-            get => _statistics[role] ?? new StatisticsEntity();
+            get => _statistics.ContainsKey(role) ? _statistics[role] : new StatisticsEntity();
             set => _statistics[role] = value;
         }
 

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

@@ -41,5 +41,12 @@ namespace MafiaTelegramBot.DataBase.Entity
             if(Werewolf) list.Add(Roles.Werewolf);
             return list;
         }
+
+        public bool AllRolesOpened()
+        {
+            return Bodyguard && Dame && Detective
+                   && Elder && Fool && Hooker && Journalist
+                   && Lawyer && Necromancer && Parasite && Werewolf;
+        }
     }
 }

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

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
 
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 4 - 2
MafiaTelegramBot/Game/GameRoles/CopRole.cs

@@ -1,3 +1,4 @@
+using System;
 using System.Linq;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Game.GameRooms;
@@ -11,7 +12,7 @@ namespace MafiaTelegramBot.Game.GameRoles
 
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -37,7 +38,8 @@ namespace MafiaTelegramBot.Game.GameRoles
                         : Room.Players[NightTargetId].GetRole() is Roles.Werewolf && ((WerewolfRole) Room.Players[NightTargetId].CurrentRole).IsMafia
                             ? roles.Mafia
                             : roles.Villager;
-                    KnownRoles.Add(Room.Players[NightTargetId].Id, role);
+                    if (KnownRoles.ContainsKey(NightTargetId)) KnownRoles[NightTargetId] = role;
+                    else KnownRoles.Add(Room.Players[NightTargetId].Id, role);
                     await Room.PlayersCh.EditTo(Player.Id, MessageId,
                         $"{strings.role_of_your_target} {Room.Players[NightTargetId].NickName} - {role}");
                 }

+ 3 - 10
MafiaTelegramBot/Game/GameRoles/DameRole.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 2;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -21,6 +21,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task NightAction()
         {
             NightTargetId = -1;
+            MafiaTargetId = -1;
             Player.IsSpeaker = true;
             var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).ToList();
             NightTargetList = alivePlayers.Where(p=> p.CanBeBlockedDay && p.Id != Player.Id).ToList();
@@ -49,7 +50,7 @@ namespace MafiaTelegramBot.Game.GameRoles
                     await Room.PlayersCh.SendTo(NightTargetId, strings.dame_block_you);
                     await Room.PlayersCh.SendExcept(NightTargetId, $"{strings.dame_block_player} " +
                                                                    $"({Room.Players[NightTargetId].TurnOrder}) " +
-                                                                   $"{Room.Players[NightTargetId].NickName}." +
+                                                                   $"{Room.Players[NightTargetId].NickName}. " +
                                                                    $"{strings.player_cant_talk_and_vote}");
                 }
             }
@@ -79,14 +80,6 @@ namespace MafiaTelegramBot.Game.GameRoles
                 }
             }
         }
-
-        public override async Task Kill()
-        {
-            if (Room.PlayersRole.ContainsKey(Roles.Werewolf)
-                && Room.PlayersRole[Roles.Werewolf].Count == 1)
-                await ((WerewolfRole) Room.PlayersRole[Roles.Werewolf][0].CurrentRole).TransformToMafia();
-            await base.Kill();
-        }
         
         public DameRole(GameRoom room, Player player) : base(room, player) { }
     }

+ 3 - 2
MafiaTelegramBot/Game/GameRoles/DetectiveRole.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         private int _color = 1;
         private string _action = "";
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -46,7 +46,8 @@ namespace MafiaTelegramBot.Game.GameRoles
                             : Room.Players[NightTargetId].GetRole() is Roles.Werewolf && ((WerewolfRole) Room.Players[NightTargetId].CurrentRole).IsMafia
                                 ? roles.Mafia
                                 : roles.Villager;
-                        KnownRoles.Add(Room.Players[NightTargetId].Id, role);
+                        if (KnownRoles.ContainsKey(NightTargetId)) KnownRoles[NightTargetId] = role;
+                        else KnownRoles.Add(Room.Players[NightTargetId].Id, role);
                         await Room.PlayersCh.EditTo(Player.Id, MessageId,
                             $"{strings.role_of_your_target} {Room.Players[NightTargetId].NickName} - {role}");
                     }

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/DoctorRole.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 4 - 10
MafiaTelegramBot/Game/GameRoles/DonRole.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override Roles RoleKey => Roles.Don;
         
         private int _color = 2;
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -19,6 +19,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task NightAction()
         {
             NightTargetId = -1;
+            MafiaTargetId = -1;
             Player.IsSpeaker = true;
             var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).ToList();
             NightTargetList = alivePlayers.Where(p => p.IsAlive && (!KnownRoles.ContainsKey(p.Id) || Room.IsExtended)).ToList();
@@ -45,7 +46,8 @@ namespace MafiaTelegramBot.Game.GameRoles
                     var role = Room.Players[NightTargetId].GetRole() is Roles.Cop or Roles.Detective or Roles.Journalist
                         ? Room.Players[NightTargetId].GetRoleName()
                         : roles.Villager;
-                    KnownRoles.Add(Room.Players[NightTargetId].Id, role);
+                    if (KnownRoles.ContainsKey(NightTargetId)) KnownRoles[NightTargetId] = role;
+                    else KnownRoles.Add(Room.Players[NightTargetId].Id, role);
                     await Room.PlayersCh.EditTo(Player.Id, MessageId,
                         $"{strings.role_of_your_target} {Room.Players[NightTargetId].NickName} - {role}");
                 }
@@ -78,14 +80,6 @@ namespace MafiaTelegramBot.Game.GameRoles
             }
         }
         
-        public override async Task Kill()
-        {
-            if (Room.PlayersRole.ContainsKey(Roles.Werewolf)
-                && Room.PlayersRole[Roles.Werewolf].Count == 1)
-                await ((WerewolfRole) Room.PlayersRole[Roles.Werewolf][0].CurrentRole).TransformToMafia();
-            await base.Kill();
-        }
-        
         public DonRole(GameRoom room, Player player) : base(room, player) { }
     }
 }

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/ElderRole.cs

@@ -9,7 +9,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override Roles RoleKey => Roles.Elder;
         
         private int _color = 1;
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/FoolRole.cs

@@ -10,7 +10,7 @@ namespace MafiaTelegramBot.Game.GameRoles
 
         private int _color = 3;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 4 - 2
MafiaTelegramBot/Game/GameRoles/HookerRole.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override Roles RoleKey => Roles.Hooker;
 
         private int _color = 1;
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -55,7 +55,9 @@ namespace MafiaTelegramBot.Game.GameRoles
             if (!Room.IsDay)
             {
                 var target = Room.Players[NightTargetId];
-                if (target.CurrentRole.RoleKey != Roles.Mafia) target.IsAlive = false;
+                if (target.GetRole() == Roles.Mafia || target.GetRole() != Roles.Dame || target.GetRole() != Roles.Don) { }
+                else if (target.GetRole() == Roles.Werewolf && ((WerewolfRole) target.CurrentRole).IsMafia) { }
+                else target.IsAlive = false;
             }
             Player.IsAlive = false;
             return Task.CompletedTask;

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/JournalistRole.cs

@@ -13,7 +13,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 3 - 2
MafiaTelegramBot/Game/GameRoles/LawyerRole.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -37,7 +37,8 @@ namespace MafiaTelegramBot.Game.GameRoles
                         : Room.Players[NightTargetId].GetRole() is Roles.Werewolf && ((WerewolfRole) Room.Players[NightTargetId].CurrentRole).IsMafia
                             ? roles.Mafia
                             : roles.Villager;
-                    KnownRoles.Add(Room.Players[NightTargetId].Id, role);
+                    if (KnownRoles.ContainsKey(NightTargetId)) KnownRoles[NightTargetId] = role;
+                    else KnownRoles.Add(Room.Players[NightTargetId].Id, role);
                     await Room.PlayersCh.EditTo(Player.Id, MessageId,
                         $"{strings.role_of_your_target} {Room.Players[NightTargetId].NickName} - {role}");
                 }

+ 4 - 14
MafiaTelegramBot/Game/GameRoles/MafiaRole.cs

@@ -10,7 +10,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override Roles RoleKey => Roles.Mafia;
         private int _color = 2;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -18,6 +18,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task NightAction()
         {
             Player.IsSpeaker = true;
+            MafiaTargetId = -1;
             var targets = Room.Players.Values.Where(p => p.IsAlive).ToList();
             var message = await Room.PlayersCh.SendTo(Player.ChatId, strings.choose_player_to_kill, 
                 Keyboard.NightMafiaTargetKeyboard(targets, Player.Id));
@@ -27,11 +28,8 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task ApplyNightActionResult()
         {
             Player.IsSpeaker = false;
-            if (MafiaTargetId != -2)
-            {
-                if (MafiaTargetId == -1) await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_have_not_choosen_target);
-                else MafiaTargetId = -1;
-            }
+            if (MafiaTargetId == -1)
+                await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_have_not_choosen_target);
         }
 
         public override async Task SetMafiaTarget(long userId)
@@ -47,14 +45,6 @@ namespace MafiaTelegramBot.Game.GameRoles
                 }
             }
         }
-        
-        public override async Task Kill()
-        {
-            if (Room.PlayersRole.ContainsKey(Roles.Werewolf)
-                && Room.PlayersRole[Roles.Werewolf].Count == 1)
-                await ((WerewolfRole) Room.PlayersRole[Roles.Werewolf][0].CurrentRole).TransformToMafia();
-            await base.Kill();
-        }
 
         public MafiaRole(GameRoom room, Player player) : base(room, player) { }
     }

+ 4 - 5
MafiaTelegramBot/Game/GameRoles/NecromancerRole.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
 
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -33,7 +33,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         public override async Task ApplyNightActionResult()
         {
             if (_actionApplied || NightTargetId == -2) { }
-            else if(NightTargetId == -1) await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_have_not_choosen_target);
+            else if(NightTargetId == -1) await Room.PlayersCh.EditTo(Player.Id, MessageId, strings.you_have_not_choosen_target);
             else
             {
                 _actionApplied = true;
@@ -43,8 +43,7 @@ namespace MafiaTelegramBot.Game.GameRoles
                         var parasiteTarget = ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId;
                         if (Room.Players[parasiteTarget].IsAlive) Room.Players[NightTargetId].IsAlive = true;
                         else
-                            await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId,
-                                strings.player_parasit_with_dead_owner);
+                            await Room.PlayersCh.EditTo(Player.Id, MessageId, strings.player_parasit_with_dead_owner);
                     }
                     else Room.Players[NightTargetId].IsAlive = true;
             }
@@ -59,7 +58,7 @@ namespace MafiaTelegramBot.Game.GameRoles
                 if(userId == Player.Id) await Room.PlayersCh.EditTo(Player.Id, MessageId,strings.you_heal_yourself);
                 else await Room.PlayersCh.EditTo(Player.Id, MessageId, $"{strings.you_choose_target} {Room.Players[NightTargetId].NickName}");
             }
-            else await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_skip_vote);
+            else await Room.PlayersCh.EditTo(Player.Id, MessageId, strings.you_skip_vote);
         }
         public NecromancerRole(GameRoom room, Player player) : base(room, player) { }
     }

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/NoneRole.cs

@@ -7,7 +7,7 @@ namespace MafiaTelegramBot.Game.GameRoles
     {
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 5 - 1
MafiaTelegramBot/Game/GameRoles/ParasiteRole.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Game.GameRoles
 
         private int _color = 3;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -42,7 +42,11 @@ namespace MafiaTelegramBot.Game.GameRoles
                 if (NightTargetId == -1) await SetRandomNightTarget();
                 ParentId = NightTargetId;
                 if (NightTargetId != -1)
+                {
                     await Room.PlayersCh.SendTo(NightTargetId, $"{strings.you_have_been_chosen_by_the_parasite} {Player.NickName}");
+                    KnownRoles.Add(NightTargetId, strings.container);
+                    Room.Players[NightTargetId].CurrentRole.KnownRoles.Add(Player.Id, roles.Parasite);
+                }
                 else Player.IsAlive = false;
             }
 

+ 1 - 1
MafiaTelegramBot/Game/GameRoles/VillagerRole.cs

@@ -9,7 +9,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;

+ 4 - 7
MafiaTelegramBot/Game/GameRoles/WerewolfRole.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Game.GameRoles
         
         private int _color = 1;
 
-        public override double ColorRole
+        public override int ColorRole
         {
             get => _color; 
             set => _color = (int) value;
@@ -22,6 +22,7 @@ namespace MafiaTelegramBot.Game.GameRoles
             if (IsMafia)
             {
                 Player.IsSpeaker = true;
+                MafiaTargetId = -1;
                 var targets = Room.Players.Values.Where(p => p.IsAlive).ToList();
                 var message = await Room.PlayersCh.SendTo(Player.ChatId, strings.choose_player_to_kill, 
                     Keyboard.NightMafiaTargetKeyboard(targets, Player.Id));
@@ -34,12 +35,8 @@ namespace MafiaTelegramBot.Game.GameRoles
             if (IsMafia)
             {
                 Player.IsSpeaker = false;
-                if (MafiaTargetId != -2)
-                {
-                    if (MafiaTargetId == -1)
-                        await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_have_not_choosen_target);
-                    else MafiaTargetId = -1;
-                }
+                if (MafiaTargetId == -1)
+                    await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.you_have_not_choosen_target);
             }
         }
 

+ 50 - 4
MafiaTelegramBot/Game/GameRooms/ExtendedGameRoom.cs

@@ -11,6 +11,47 @@ namespace MafiaTelegramBot.Game.GameRooms
 
         public Dictionary<Roles, int> CustomRoomSettings = new();
 
+        public Dictionary<int, int> Min = new Dictionary<int, int>
+            {
+                [1] = 1,
+                [2] = 1,
+                [3] = 1,
+                [4] = 1,
+                [5] = 1,
+                
+                [6] = 2,
+                [7] = 2,
+                [8] = 2,
+                [9] = 2,
+                [10] = 3,
+                [11] = 3,
+                [12] = 4,
+                [13] = 4,
+                [14] = 4,
+                [15] = 5,
+                [16] = 5
+            },
+            Max = new Dictionary<int, int>
+            {
+                [1] = 1,
+                [2] = 2,
+                [3] = 3,
+                [4] = 4,
+                [5] = 5,
+                
+                [6] = 2,
+                [7] = 2,
+                [8] = 3,
+                [9] = 3,
+                [10] = 3,
+                [11] = 4,
+                [12] = 4,
+                [13] = 4,
+                [14] = 5,
+                [15] = 5,
+                [16] = 5
+            };
+
         public override Dictionary<Roles, List<Player>> PlayersRole { get; set; } = new()
         {
             //passive roles
@@ -19,18 +60,18 @@ namespace MafiaTelegramBot.Game.GameRooms
             [Roles.Villager] = new List<Player>(),
             //Active roles
             [Roles.Hooker] = new List<Player>(),
-            [Roles.Parasite] = new List<Player>(),
             [Roles.Mafia] = new List<Player>(),
             [Roles.Don] = new List<Player>(),
             [Roles.Dame] = new List<Player>(),
+            [Roles.Bodyguard] = new List<Player>(),
+            [Roles.Doctor] = new List<Player>(),
+            [Roles.Necromancer] = new List<Player>(),
             [Roles.Cop] = new List<Player>(),
             [Roles.Journalist] = new List<Player>(),
             [Roles.Detective] = new List<Player>(),
             [Roles.Lawyer] = new List<Player>(),
-            [Roles.Bodyguard] = new List<Player>(),
-            [Roles.Doctor] = new List<Player>(),
-            [Roles.Necromancer] = new List<Player>(),
             [Roles.Werewolf] = new List<Player>(),
+            [Roles.Parasite] = new List<Player>(),
         };
 
         protected override async Task<ResultCode> ReadSettings()
@@ -38,7 +79,12 @@ namespace MafiaTelegramBot.Game.GameRooms
             return await Task.Run(() =>
             {
                 var rolesCount = CustomRoomSettings.Values.Sum();
+                var blackRolesCount = CustomRoomSettings.Count(pair => pair.Key
+                    is Roles.Dame or Roles.Don or Roles.Werewolf or Roles.Lawyer);
+                if (CustomRoomSettings.ContainsKey(Roles.Mafia)) blackRolesCount += CustomRoomSettings[Roles.Mafia];
                 if (rolesCount != Players.Count) return ResultCode.RolesNotEqualPlayers;
+                if (blackRolesCount < Min[Players.Count]) return ResultCode.NotEnoughMafia;
+                if (blackRolesCount > Max[Players.Count]) return ResultCode.TooMuchMafia;
                 Settings = CustomRoomSettings.ToDictionary(k=>k.Key, k=>k.Value);
                 return ResultCode.CodeOk;
             });

+ 97 - 32
MafiaTelegramBot/Game/GameRooms/GameRoom.GameProcess.cs

@@ -10,7 +10,6 @@ using MafiaTelegramBot.Game.GameRoles;
 using MafiaTelegramBot.Models;
 using MafiaTelegramBot.Resources;
 using Microsoft.EntityFrameworkCore;
-using Telegram.Bot.Types;
 using Timer = System.Timers.Timer;
 
 namespace MafiaTelegramBot.Game.GameRooms
@@ -57,6 +56,39 @@ namespace MafiaTelegramBot.Game.GameRooms
             IsDay = false;
             await Task.Run(async() =>
             {
+                //Start updating games stats
+                var statsQuery = "SELECT * FROM mafia.statistics WHERE";
+                foreach (var player in Players.Values)
+                {
+                    statsQuery += $" id = {player.Id} AND role = '{player.GetRole().ToString()}' OR role = 'All' OR";
+                }
+
+                statsQuery = statsQuery.Substring(0, statsQuery.Length - 2);
+
+                try
+                {
+                    var statsList = UserDao.DataBase.Statistics.FromSqlRaw(statsQuery).ToArrayAsync().Result;
+
+                    foreach (var player in Players.Values)
+                    {
+                        var userProfile = UserDao.GetPlayerById(player.Id).Result;
+                        foreach (var row in statsList.Where(s => s.UserId == player.Id))
+                            row.Games++;
+
+                        if (userProfile.Statistics.Contains(Roles.All))
+                        {
+                            userProfile.Statistics[player.CurrentRole.RoleKey].Games++;
+                            userProfile.Statistics[Roles.All].Games++;
+                        }
+                    }
+                    UserDao.DataBase.Statistics.UpdateRange(statsList);
+                }
+                catch (Exception e)
+                {
+                    await Console.Out.WriteLineAsync(e.Message);
+                }
+                //Stop updating games stats
+                
                 await PlayersCh.SendSticker(Stickers.Sticker["Night"]);
                 await PlayersCh.Send(strings.city_falls_asleep);
                 var mafia = Players.Values.Where(player => player.GetRole() is Roles.Mafia).ToArray();
@@ -75,6 +107,16 @@ namespace MafiaTelegramBot.Game.GameRooms
                 };
                 timer.Elapsed += (_, _) => resetEvent.Set();
                 timer.Start();
+                
+                try
+                {
+                    await UserDao.DataBase.SaveChangesAsync();
+                }
+                catch (Exception e)
+                {
+                    await Console.Out.WriteLineAsync(e.Message);
+                }
+
                 foreach (var player in Players.Values)
                 {
                     if (player.GetRole() is not (Roles.Don or Roles.Mafia or Roles.Dame)) 
@@ -137,8 +179,8 @@ namespace MafiaTelegramBot.Game.GameRooms
             for (var i = 0; i < turnsCount; ++i)
             {
                 var player = _turnOrder.Dequeue();
-                if(!Players.ContainsKey(player.Id) || !player.IsAlive) continue;
-                if (!player.IsBlocked)
+                if(!Players.ContainsKey(player.Id)) continue;
+                if (!player.IsBlocked && player.IsAlive)
                 {
                     await PlayersCh.Send($"{strings.now_turn} ({player.TurnOrder}) {player.NickName}");
                     if (TimerEnabled) await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
@@ -203,8 +245,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                 foreach (var (role, players) in PlayersRole)
                 {
                     if (role is Roles.Mafia)
-                        foreach (var mafia in players.Where(p=>p.IsAlive)) await mafia.CurrentRole.ApplyNightActionResult();
-                    else if (players.Count == 1 && players[0].IsAlive) await players[0].CurrentRole.ApplyNightActionResult();
+                        foreach (var mafia in players) await mafia.CurrentRole.ApplyNightActionResult();
+                    else if (players.Count == 1) await players[0].CurrentRole.ApplyNightActionResult();
                 }
                 var afterKill = Players.Values.ToDictionary(p=>p.Id,p=>p.IsAlive);
                 var message = strings.city_wakes_up;
@@ -215,6 +257,9 @@ namespace MafiaTelegramBot.Game.GameRooms
                             message += alive
                                 ? $"\n{Players[id].NickName} {strings.will_be_ressurected}"
                                 : $"\n{Players[id].NickName} {strings.will_be_killed}";
+                            if(!alive && Players[id].GetRole() is Roles.Don or Roles.Dame or Roles.Mafia
+                                      && PlayersRole.ContainsKey(Roles.Werewolf) && PlayersRole[Roles.Werewolf].Count == 1)
+                                await ((WerewolfRole) PlayersRole[Roles.Werewolf][0].CurrentRole).TransformToMafia();
                             await PlayersCh.SendTo(id, alive ? strings.you_will_be_ressurected : strings.you_will_be_killed);
                         }
                 message += '\n' + mafiaNotAgree;
@@ -228,22 +273,19 @@ namespace MafiaTelegramBot.Game.GameRooms
             await Task.Run( async () =>
             {
                 var contendersCopy = contenders.ToList();
-                VoteUpList.Clear();
-                VoteKillList.Clear();
-                foreach (var contender in contendersCopy.Where(p => !p.IsBlocked)) await contender.CurrentRole.DefenceAction();
+                foreach (var contender in contendersCopy.Where(p => !p.IsBlocked)) 
+                    if (Players.ContainsKey(contender.Id)) await contender.CurrentRole.DefenceAction();
                 var votersPlayers = Players.Values.Where(p => p.IsAlive && !p.IsBlocked).ToArray();
+                var timers = votersPlayers.Select(
+                    voter => voter.CurrentRole.VotingAction(contendersCopy.Where(p => Players.ContainsKey(p.Id)).ToList()))
+                    .ToList();
                 Timer votingTimer = new() {Interval = 20 * 1000, AutoReset = false};
                 var resetEvent = new ManualResetEvent(false);
                 votingTimer.Elapsed += (_, _) => resetEvent.Set();
-                List<Message> messagesToDelete = new();
-                foreach (var player in votersPlayers)
-                    messagesToDelete.Add(await PlayersCh.SendTo(player.ChatId, strings.you_have_ten_seconds_to_vote,  
-                        Keyboard.VoteKeyboard(contendersCopy.Where(p=>Players.ContainsKey(p.Id)).ToList(), player.Id, false, Callback.VoteToKill)));
                 votingTimer.Start();
                 resetEvent.WaitOne();
                 votingTimer.Stop();
-                foreach (var message in messagesToDelete)
-                    await PlayersCh.EditTo(message.Chat.Id, message.MessageId, strings.time_out);
+                foreach (var timer in timers) timer.Set();
             });
         }
 
@@ -320,10 +362,12 @@ namespace MafiaTelegramBot.Game.GameRooms
             var max = votes.Max(item => item.count);
             var maxObjects = votes.Where(item => item.count == max);
             result.AddRange(from obj in maxObjects select Players[obj.id]);
+            VoteKillList.Clear();
+            VoteUpList.Clear();
             return result;
         }
 
-        private async Task PutUpVote(long playerId, long targetId, int messageId, bool toKill = false)
+        private async Task PutUpVote(long playerId, long targetId, int messageId = -1, bool toKill = false)
         {
             if (Players.ContainsKey(playerId))
             {
@@ -403,45 +447,66 @@ namespace MafiaTelegramBot.Game.GameRooms
                 {
                     rolesMessage += $"\n({player.TurnOrder}) {player.NickName} - {player.GetRoleName()}";
                     statsQuery += $" id = {player.Id} AND role = '{player.GetRole().ToString()}' OR role = 'All' OR";
-                    player.ResetState();
                 }
-
+                
+                await PlayersCh.Send(rolesMessage);
+                
+                //var updatingNotifications = await PlayersCh.SendWithReturn("Update data! Wait until it disappears");
+                
                 statsQuery = statsQuery.Substring(0, statsQuery.Length - 2);
 
                 try
                 {
                     var statsList = UserDao.DataBase.Statistics.FromSqlRaw(statsQuery).ToArrayAsync().Result;
-
-                    foreach (var player in statsList)
+                    
+                    void UpdateWins(Player player)
                     {
+                        var userProfile = UserDao.GetPlayerById(player.Id).Result;
+                        foreach (var row in statsList.Where(s => s.UserId == player.Id))
+                        {
+                            row.Wins++;
+                        }
 
-                        player.Games++;
-                        
-                        //Yellow get Wins++
-
+                        if (userProfile.Statistics.Contains(Roles.All))
+                        {
+                            userProfile.Statistics[player.CurrentRole.RoleKey].Wins++;
+                            userProfile.Statistics[Roles.All].Wins++;
+                        }
+                    }
+                    
+                    foreach (var player in players)
+                    {
                         if (aliveMafia == 0)
                         {
-                            //then civil roles get Wins++;
+                            if ((player.CurrentRole.ColorRole == 1 || !(player.CurrentRole.RoleKey == Roles.Lawyer)) && player.IsAlive)
+                                UpdateWins(player);
                         }
                         else
                         {
-                            //then civil rols get Wins++;
+                            if ((player.CurrentRole.ColorRole == 2 || player.CurrentRole.RoleKey == Roles.Lawyer) && player.IsAlive)
+                                UpdateWins(player);
                         }
-                        
-                        //Check Fool Wins++
-                    }
 
+                        if (player.CurrentRole.ColorRole == 3)
+                        {
+                            if (player.CurrentRole.IsWon().Result != "")
+                                UpdateWins(player);
+                        }
+                        player.ResetState();
+                    }
                     UserDao.DataBase.Statistics.UpdateRange(statsList);
-
                     await UserDao.DataBase.SaveChangesAsync();
-                
                 }
                 catch (Exception e)
                 {
                     await Console.Out.WriteLineAsync(e.Message);
                 }
-                
-                await PlayersCh.Send(rolesMessage);
+                /*
+                foreach (var message in updatingNotifications)
+                {
+                    await Bot.Get().DeleteMessageAsync(message.Chat.Id,message.MessageId);
+                }
+                */
                 IsRunning = false;
                 IsDay = false;
                 _turnOrder.Clear();

+ 37 - 14
MafiaTelegramBot/Game/GameRooms/GameRoom.MessageHandler.cs

@@ -1,3 +1,4 @@
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Controllers;
@@ -11,6 +12,8 @@ namespace MafiaTelegramBot.Game.GameRooms
     {
         public class MessageHandler
         {
+            private readonly List<long> _exitingPlayers = new();
+            
             private readonly GameRoom _room;
 
             public MessageHandler(GameRoom room)
@@ -23,7 +26,8 @@ namespace MafiaTelegramBot.Game.GameRooms
                 var text = update.Message.Text;
                 var userId = update.Message.From.Id;
                 if (!_room.Players.ContainsKey(userId)) return new Message();
-                if (text == keyboard.look_players_list) await LookPlayers(_room.Players[userId]);
+                if(_exitingPlayers.Contains(userId)) await Leave(_room.Players[userId], update.Message.Text);
+                else if (text == keyboard.look_players_list) await LookPlayers(_room.Players[userId]);
                 else if (text == keyboard.leave) await Leave(_room.Players[userId]);
                 else if (text == keyboard.end_turn)
                 {
@@ -49,31 +53,50 @@ namespace MafiaTelegramBot.Game.GameRooms
 
             private async Task LookPlayers(Player player)
             {
-                var players = _room.Players.Values.ToList();
+                var players = _room.Players.Values.ToArray();
+                var nextPlayer = _room._turnOrder.Peek();
                 var knownRoles = player.CurrentRole.KnownRoles;
                 var message = strings.players_list;
-                foreach (var item in players)
+                var stopIndex = -1;
+                for (var i = 0; i != stopIndex; i = (i+1) % players.Length)
                 {
-                    var role =  knownRoles.ContainsKey(item.Id)
-                        ? knownRoles[item.Id]
+                    i %= players.Length;
+                    if (stopIndex == -1 && players[i].Id == nextPlayer.Id) stopIndex = i;
+                    if (stopIndex == -1) continue;
+                    var role =  knownRoles.ContainsKey(players[i].Id)
+                        ? knownRoles[players[i].Id]
                         : "";
                     message +=
-                        $"\n({item.TurnOrder}) " +
-                        $"{item.NickName} " +
-                        $"({(item.IsAlive ? strings.alive : strings.died)}) " +
+                        $"\n{(message == strings.players_list ? strings.next + " - " : "")}" +
+                        $"({players[i].TurnOrder}) " +
+                        $"{(players[i].Id == player.Id ? strings.you : players[i].NickName)} " +
+                        $"({(players[i].IsAlive ? strings.alive : strings.died)}) " +
                         $"{role}";
                 }
                 await _room.PlayersCh.SendTo(player.Id, message);
             }
 
-            private async Task Leave(Player player)
+            private async Task Leave(Player player, string text = "")
             {
                 var roomName = player.GetRoomName();
-                var resultCode = await RoomController.LeaveFromGame(player);
-                if (resultCode == ResultCode.CodeOk)
-                    await Bot.SendWithMarkdown2(player.ChatId, $"{strings.you_leave_from_game} _*{roomName}*_",
-                        Keyboard.MainMenu);
-                else await Utilities.GetResultCodeMessage(resultCode, player.ChatId);
+                if (_room.IsRunning)
+                {
+                    if (_exitingPlayers.Remove(player.Id))
+                    {
+                        if (text == strings.exit)
+                        {
+                            var resultCode = await RoomController.LeaveFromGame(player);
+                            if (resultCode == ResultCode.CodeOk)
+                                await Bot.SendWithMarkdown2(player.ChatId, $"{strings.you_leave_from_game} _*{roomName}*_", Keyboard.MainMenu);
+                            else await Utilities.GetResultCodeMessage(resultCode, player.ChatId);
+                        }
+                    }
+                    else
+                    {
+                        _exitingPlayers.Add(player.Id);
+                        await _room.PlayersCh.SendTo(player.ChatId, $"{strings.confirm_exit} ```{strings.exit}``` {strings.to_confirm_exit}");
+                    }
+                }
             }
         }
     }

+ 2 - 0
MafiaTelegramBot/Game/GameRooms/GameRoom.QueryHandler.cs

@@ -31,10 +31,12 @@ namespace MafiaTelegramBot.Game.GameRooms
                     case Callback.Vote:
                         await _room.PutUpVote(player.Id, long.Parse(data[2]), messageId);
                         player.CurrentRole.VoteActionComplete.Set();
+                        player.CurrentRole.VoteActionComplete.Reset();
                         break;
                     case Callback.VoteToKill:
                         await _room.PutUpVote(player.Id, long.Parse(data[2]), messageId, true);
                         player.CurrentRole.VoteActionComplete.Set();
+                        player.CurrentRole.VoteActionComplete.Reset();
                         break;
                     case Callback.NightTarget:
                         await player.CurrentRole.SetNightTarget(long.Parse(data[2]));

+ 33 - 19
MafiaTelegramBot/Game/GameRooms/GameRoom.Role.cs

@@ -18,7 +18,7 @@ namespace MafiaTelegramBot.Game.GameRooms
             public readonly Dictionary<long, string> KnownRoles = new();
             protected long NightTargetId = -1;
             public long MafiaTargetId = -1;
-            public abstract double ColorRole
+            public abstract int ColorRole
             {
                 get;
                 set;
@@ -80,24 +80,15 @@ namespace MafiaTelegramBot.Game.GameRooms
 
             public virtual async Task Kill()
             {
-                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;
+                if (Room.PlayersRole.ContainsKey(Roles.Parasite)
+                    && Room.PlayersRole[Roles.Parasite].Count == 1
+                    && ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == Player.Id)
                 {
-                    Player.IsAlive = false;
-                    if (Room.PlayersRole.ContainsKey(Roles.Parasite)
-                        && Room.PlayersRole[Roles.Parasite].Count == 1
-                        && ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == Player.Id)
-                    {
-                        await Room.PlayersRole[Roles.Parasite][0].CurrentRole.Kill();
-                        if(Room.IsDay) await Room.PlayersCh.Send($"{strings.for_unknown_reasons_died} {Room.PlayersRole[Roles.Parasite][0].NickName}");
-                        await Room.PlayersCh.SendTo(Room.PlayersRole[Roles.Parasite][0].Id,
-                            strings.your_carrier_player_has_died);
-                    }
-                        
+                    await Room.PlayersRole[Roles.Parasite][0].CurrentRole.Kill();
+                    if(Room.IsDay) await Room.PlayersCh.Send($"{strings.for_unknown_reasons_died} {Room.PlayersRole[Roles.Parasite][0].NickName}");
+                    await Room.PlayersCh.SendTo(Room.PlayersRole[Roles.Parasite][0].Id,
+                        strings.your_carrier_player_has_died);
                 }
             }
 
@@ -142,7 +133,7 @@ namespace MafiaTelegramBot.Game.GameRooms
                 var voteTimer = new Timer(20 * 1000) {AutoReset = false};
                 var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).Except(Room.VoteUpList).ToList();
                 var message = await Room.PlayersCh.SendTo(Player.ChatId,
-                    $"{strings.put_up_vote}\n{strings.you_have_ten_seconds}{(isFirst ? "\n" + strings.user_not_choose : "")}",  
+                    $"{strings.put_up_vote}\n{strings.you_have_twenty_seconds}{(isFirst ? "\n" + strings.user_not_choose : "")}",  
                     Keyboard.VoteKeyboard(alivePlayers, Player.Id, !isFirst));
                 voteTimer.Elapsed += async (_, _) =>
                 {
@@ -156,6 +147,29 @@ namespace MafiaTelegramBot.Game.GameRooms
                 VoteActionComplete.Reset();
             }
 
+            public ManualResetEvent VotingAction(List<Player> targets)
+            {
+                var stopVote = new ManualResetEvent(false);
+                Task.Run(async() =>
+                {
+                    var message = await Room.PlayersCh.SendTo(Player.Id, strings.you_have_ten_seconds_to_vote, 
+                        Keyboard.VoteKeyboard(targets, Player.Id, false, Callback.VoteToKill));
+                    stopVote.WaitOne();
+                    if (!Room.VoteKillList.ContainsKey(Player.Id) && Room.Players.ContainsKey(Player.Id))
+                    {
+                        var players = targets.Where(p => Room.Players.ContainsKey(p.Id)).ToArray();
+                        if(players.Length == 0) await Room.PlayersCh.EditTo(Player.Id, message.MessageId, strings.nothing_to_choose);
+                        else
+                        {
+                            var randomPlayer = players[Utilities.Rnd.Next(players.Length)];
+                            await Room.PutUpVote(Player.Id, randomPlayer.Id, toKill: true);
+                            await Room.PlayersCh.EditTo(Player.Id, message.MessageId, $"{strings.automatically_vote} ({randomPlayer.TurnOrder}) {randomPlayer.NickName}");
+                        }
+                    }
+                });
+                return stopVote;
+            }
+
             public async Task DefenceAction()
             {
                 await Room.PlayersCh.SendExcept(Player.Id, $"{strings.now_defence} ({Player.TurnOrder}) {Player.NickName}");

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

@@ -14,9 +14,9 @@ namespace MafiaTelegramBot.Game.GameRooms
             [Roles.Villager] = new List<Player>(),
             //Active roles
             [Roles.Mafia] = new List<Player>(),
+            [Roles.Doctor] = new List<Player>(),
             [Roles.Don] = new List<Player>(),
             [Roles.Cop] = new List<Player>(),
-            [Roles.Doctor] = new List<Player>(),
         };
 
         protected override async Task<ResultCode> ReadSettings()

+ 18 - 6
MafiaTelegramBot/Models/Bot.cs

@@ -1,9 +1,10 @@
 using System;
 using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Models.Commands;
 using MafiaTelegramBot.Models.Inlines;
-using MafiaTelegramBot.Models.Replies;
+using MafiaTelegramBot.Models.Payments;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot;
 using Telegram.Bot.Types;
@@ -17,11 +18,11 @@ namespace MafiaTelegramBot.Models
         private static TelegramBotClient _client;
         private static List<Command> _commandsList;
         private static List<Query> _queriesList;
-        private static List<Reply> _repliesList;
+        private static List<Payment> _paymentsList;
         
         public static IReadOnlyList<Command> Commands => _commandsList.AsReadOnly();
         public static IReadOnlyList<Query> Queries => _queriesList.AsReadOnly();
-        public static IReadOnlyList<Reply> Replies => _repliesList.AsReadOnly();
+        public static IReadOnlyList<Payment> Payments => _paymentsList.AsReadOnly();
 
         public static readonly List<long> UsersThatChangesNickname = new();
         public static readonly Dictionary<long, string[]> UsersThatCreatesRoom = new();
@@ -32,7 +33,7 @@ namespace MafiaTelegramBot.Models
             if (_client != null) return _client;
             InitCommands();
             InitQueries();
-            InitReplies();
+            InitPayments();
             _client = new TelegramBotClient(AppSettings.Token);
             return _client;
         }
@@ -83,10 +84,13 @@ namespace MafiaTelegramBot.Models
             };
         }
         
-        private static void InitReplies()
+        private static void InitPayments()
         {
             //TODO fill inline keyboard array
-            _repliesList = new List<Reply>();
+            _paymentsList = new List<Payment>
+            {
+                new RandomRolePayment()
+            };
         }
 
         public static async Task<Message> SendStickerAsync(long chatId, string fileId)
@@ -143,5 +147,13 @@ namespace MafiaTelegramBot.Models
                 return new Message();
             }
         }
+
+        public static async Task AnswerPreCheckoutQuery(string preCheckoutQueryId)
+        {
+            Console.WriteLine(preCheckoutQueryId);
+            var token = new CancellationToken();
+            await Get().AnswerPreCheckoutQueryAsync(preCheckoutQueryId, token);
+            Console.WriteLine(token.IsCancellationRequested);
+        }
     }
 }

+ 11 - 5
MafiaTelegramBot/Models/Commands/ShowProfileCommand.cs

@@ -1,3 +1,5 @@
+using System;
+using System.Linq;
 using System.Threading.Tasks;
 using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Resources;
@@ -12,13 +14,17 @@ namespace MafiaTelegramBot.Models.Commands
         protected override async Task<Message> Execute(Update update)
         { 
             var user = await UserDao.GetPlayerById(UserId);
-            if(!user.Statistics.Contains(Roles.All)) user.Statistics.AddNew(Roles.All, UserId);
-            var result = user.Statistics[Roles.All];
+            var rolesList = Enum.GetValues(typeof(Roles)).Cast<Roles>().ToList();
+            rolesList.Remove(Roles.None);
+            rolesList.Remove(Roles.All);
+            if (!user.Statistics.Contains(Roles.All))
+                await UserDao.ActiveUsers[UserId].LoadStatistics();
+            var allStatsRow = user.Statistics[Roles.All];
             var message =
                 $"__*{strings.statistics_for} _{user.NickName}_*__\n" +
-                $"{strings.games_count} {result.Games}\n" +
-                $"{strings.wins_count} {result.Wins}\n" +
-                $"{strings.winrate} {result.GetWinrate()}%\n";
+                $"{strings.games_count} {allStatsRow.Games}\n" +
+                $"{strings.wins_count} {allStatsRow.Wins}\n" +
+                $"{strings.winrate} {(int)(allStatsRow.GetWinrate()*100)}%\n \n";
             return await Bot.SendWithMarkdown2(ChatId, message, Keyboard.ProfileKeyboard(UserId));
             
         }

+ 65 - 11
MafiaTelegramBot/Models/Inlines/ApplyRolesChangeQuery.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Linq;
 using System.Threading.Tasks;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.Game.GameRooms;
@@ -30,22 +31,30 @@ namespace MafiaTelegramBot.Models.Inlines
             switch (action)
             {
                 case "+":
-                    if(!_room.CustomRoomSettings.ContainsKey(role)) _room.CustomRoomSettings.Add(role, 1);
-                    else if (_room.CustomRoomSettings[role] < _room.MaxPlayers)
+                    if (role is Roles.Mafia)
                     {
-                        if (role is Roles.Mafia)
+                        var blackRolesCount = _room.CustomRoomSettings.Count(pair => pair.Key
+                            is Roles.Dame or Roles.Don or Roles.Werewolf or Roles.Lawyer);
+                        if (_room.CustomRoomSettings.ContainsKey(Roles.Mafia))
+                            blackRolesCount += _room.CustomRoomSettings[Roles.Mafia];
+                        if (blackRolesCount < _room.Max[_room.Players.Count])
                         {
-                            var maximum = _room.Players.Count % 3 == 0
-                                ? _room.Players.Count / 3
-                                : _room.Players.Count / 3 - 1;
-                            if(_room.CustomRoomSettings[role] < maximum) _room.CustomRoomSettings[role]++;
+                            if(!_room.CustomRoomSettings.ContainsKey(role)) _room.CustomRoomSettings.Add(role, 1);
+                            else _room.CustomRoomSettings[role]++;
                         }
-                        else _room.CustomRoomSettings[role]++;
+                    }
+                    else
+                    {
+                        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);
+                    if (_room.CustomRoomSettings.ContainsKey(role))
+                    {
+                        if (_room.CustomRoomSettings[role] > 1) _room.CustomRoomSettings[role]--;
+                        else _room.CustomRoomSettings.Remove(role);
+                    }
                     break;
             }
         }
@@ -53,7 +62,52 @@ namespace MafiaTelegramBot.Models.Inlines
         private void SwitchRole(Roles role)
         {
             if (_room.CustomRoomSettings.ContainsKey(role)) _room.CustomRoomSettings.Remove(role);
-            else _room.CustomRoomSettings.Add(role, 1);
+            else
+            {
+                switch (role)
+                {
+                    case Roles.Don:
+                        _room.CustomRoomSettings.Remove(Roles.Dame);
+                        break;
+                    case Roles.Dame:
+                        _room.CustomRoomSettings.Remove(Roles.Don);
+                        break;
+                    case Roles.Cop:
+                        _room.CustomRoomSettings.Remove(Roles.Journalist);
+                        _room.CustomRoomSettings.Remove(Roles.Detective);
+                        break;
+                    case Roles.Journalist:
+                        _room.CustomRoomSettings.Remove(Roles.Cop);
+                        _room.CustomRoomSettings.Remove(Roles.Detective);
+                        break;
+                    case Roles.Detective:
+                        _room.CustomRoomSettings.Remove(Roles.Cop);
+                        _room.CustomRoomSettings.Remove(Roles.Journalist);
+                        break;
+                    case Roles.Doctor:
+                        _room.CustomRoomSettings.Remove(Roles.Necromancer);
+                        break;
+                    case Roles.Necromancer:
+                        _room.CustomRoomSettings.Remove(Roles.Doctor);
+                        break;
+                }
+                if (role is Roles.Dame or Roles.Don or Roles.Werewolf or Roles.Lawyer)
+                {
+                    var blackRolesCount = _room.CustomRoomSettings.Count(pair => pair.Key
+                        is Roles.Dame or Roles.Don or Roles.Werewolf or Roles.Lawyer);
+                    if (_room.CustomRoomSettings.ContainsKey(Roles.Mafia)) blackRolesCount += _room.CustomRoomSettings[Roles.Mafia];
+                    if (blackRolesCount < _room.Max[_room.Players.Count])
+                    {
+                        if (role is Roles.Werewolf)
+                        {
+                            if(_room.CustomRoomSettings.Keys.Any(k => k
+                                is Roles.Dame or Roles.Don or Roles.Mafia)) _room.CustomRoomSettings.Add(role, 1);
+                        }
+                        else _room.CustomRoomSettings.Add(role, 1);
+                    }
+                }
+                else _room.CustomRoomSettings.Add(role, 1);
+            }
         }
     }
 }

+ 9 - 2
MafiaTelegramBot/Models/Inlines/ShopMenuQuery.cs

@@ -1,4 +1,5 @@
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 
@@ -10,8 +11,14 @@ namespace MafiaTelegramBot.Models.Inlines
 
         protected override async Task<Message> Execute(Update update)
         {
-            await DeletePreviousMessage(ChatId, update.CallbackQuery.Message.MessageId);
-            return await Bot.SendWithMarkdown2(ChatId, strings.shop);
+            /*await DeletePreviousMessage(ChatId, update.CallbackQuery.Message.MessageId);
+            var user = await UserDao.GetPlayerById(UserId);
+            if (user.OpenedRoles.AllRolesOpened())
+                return await Bot.SendWithMarkdown2(ChatId, strings.you_already_open_all_roles);
+            return await Bot.Get().SendInvoiceAsync(ChatId, strings.random_role_payment,
+                strings.random_role_description, $"{Payloads.RandomRole}|{UserId}",
+                AppSettings.ProviderToken, Constants.SHOP_CURRENCY, Constants.RANDOM_ROLE_PRICE);*/
+            return await Bot.SendWithMarkdown2(ChatId, strings.work_in_progress);
         }
     }
 }

+ 26 - 1
MafiaTelegramBot/Models/Inlines/ShowMyRolesQuery.cs

@@ -1,4 +1,7 @@
+using System;
+using System.Linq;
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase.EntityDao;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 
@@ -11,7 +14,29 @@ namespace MafiaTelegramBot.Models.Inlines
         protected override async Task<Message> Execute(Update update)
         {
             await DeletePreviousMessage(ChatId, update.CallbackQuery.Message.MessageId);
-            return await Bot.SendWithMarkdown2(ChatId, strings.my_roles);
+            var user = await UserDao.GetPlayerById(UserId);
+            var rolesList = Enum.GetValues(typeof(Roles)).Cast<Roles>().ToList();
+            rolesList.Remove(Roles.None);
+            rolesList.Remove(Roles.All);
+            if (!user.Statistics.Contains(Roles.All))
+                await UserDao.ActiveUsers[UserId].LoadStatistics();
+            var allStatsRow = user.Statistics[Roles.All];
+            var message = "";
+            user = await UserDao.GetPlayerById(UserId);
+            if (allStatsRow.Games > 0)
+                foreach (var role in rolesList)
+                {
+                    if (user.Statistics.Contains(role) && user.Statistics[role].Games > 0)
+                    {
+                        var statsRow = user.Statistics[role];
+                        message += String.Format(strings.role_string, roles.ResourceManager.GetString(role.ToString()), statsRow.Wins, statsRow.Games, (int) (statsRow.GetWinrate()*100)) + '\n';
+                    }
+                }
+            else
+            {
+                message += strings.no_stats_by_roles;
+            }
+            return await Bot.SendWithMarkdown2(ChatId, message);
         }
     }
 }

+ 29 - 0
MafiaTelegramBot/Models/Payments/Payment.cs

@@ -0,0 +1,29 @@
+#nullable enable
+using System;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace MafiaTelegramBot.Models.Payments
+{
+    public abstract class Payment : UpdateModel<string>
+    {
+
+        protected override bool IsMatches(string command)
+        {
+            return command == Name;
+        }
+        public static async Task<Message> Update(Update update)
+        {
+            throw new NotImplementedException();
+            /*var payments = Bot.Payments;
+            var message = update.PreCheckoutQuery;
+            var userId = update.Message.From.Id;
+            var chatId = update.Message.Chat.Id;
+            await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
+            var command = FirstOrDefault(payments, message);
+            if(command != null) return await ((Payment?) command.Clone(chatId, userId))!.Execute(update);
+            return await Bot.SendWithMarkdown2(chatId, $"{strings.command_not_found} _*({"message"})*_");*/
+        }
+    }
+}

+ 15 - 0
MafiaTelegramBot/Models/Payments/RandomRolePayment.cs

@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+using MafiaTelegramBot.Resources;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Payments
+{
+    public class RandomRolePayment : Payment
+    {
+        protected override string Name => Payloads.RandomRole.ToString();
+        protected override Task<Message> Execute(Update update)
+        {
+            throw new System.NotImplementedException();
+        }
+    }
+}

+ 0 - 22
MafiaTelegramBot/Models/Replies/Reply.cs

@@ -1,22 +0,0 @@
-#nullable enable
-using System.Threading.Tasks;
-using Telegram.Bot.Types;
-using Telegram.Bot.Types.Enums;
-
-namespace MafiaTelegramBot.Models.Replies
-{
-    public abstract class Reply : UpdateModel<string>
-    {
-        public static async Task<Message> Update(Update update)
-        {
-            var commands = Bot.Replies;
-            var message = update.Message.ReplyToMessage.Text;
-            var userId = update.Message.From.Id;
-            var chatId = update.Message.Chat.Id;
-            await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-            var command = FirstOrDefault(commands, message);
-            if(command != null) return await ((Reply?) command.Clone(chatId, userId))!.Execute(update);
-            return await Bot.SendWithMarkdown2(chatId, $"{strings.command_not_found} _*({message})*_");
-        }
-    }
-}

+ 10 - 1
MafiaTelegramBot/Resources/Constants.cs

@@ -1,12 +1,21 @@
+using System.Collections.Generic;
+using Telegram.Bot.Types.Payments;
+
 namespace MafiaTelegramBot.Resources
 {
     public static class Constants
     {
-        public const int PLAYER_LIMITS_MIN = 1;
+        public const int PLAYER_LIMITS_MIN = 6;
         public const int PLAYER_DISABLE_TIMER = 3;
         public const int MINUTES_UNTIL_DISSOLVE = 10;
         public const int PLAYER_LIMITS_MAX = 16;
         public const int MAX_SHOWING_ROOMS = 10;
+        
+        public const string SHOP_CURRENCY = "RUB";
+        public static List<LabeledPrice> RANDOM_ROLE_PRICE = new()
+        {
+            new LabeledPrice {Label = "100 рублей", Amount = 10000}
+        };
 
         public const int ROOM_CODE_LENGTH = 6;
     }

+ 4 - 1
MafiaTelegramBot/Resources/Keyboard.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using MafiaTelegramBot.CustomCollections.Extensions;
 using MafiaTelegramBot.Game;
 using MafiaTelegramBot.Game.GameRoles;
 using MafiaTelegramBot.Game.GameRooms;
@@ -226,7 +227,9 @@ namespace MafiaTelegramBot.Resources
 
         public static InlineKeyboardMarkup ChangeRolesKeyboard(long userId, string roomKey, ExtendedGameRoom room)
         {
-            var openedRoles = room.Owner.OpenedRoles.ToList();
+            List<Roles> openedRoles = new();
+            foreach (var player in room.Players.Values)
+                openedRoles.ConcatenateUnique(player.OpenedRoles.ToList());
             var keyboard = new InlineKeyboardButton[3+openedRoles.Count][];
             keyboard[0] = new[]
             {

+ 7 - 0
MafiaTelegramBot/Resources/Payloads.cs

@@ -0,0 +1,7 @@
+namespace MafiaTelegramBot.Resources
+{
+    public enum Payloads
+    {
+        RandomRole,
+    }
+}

+ 2 - 0
MafiaTelegramBot/Resources/ResultCode.cs

@@ -11,6 +11,8 @@ namespace MafiaTelegramBot.Resources
         RoomIsFilled,
         RoomDoesNotExist,
         RolesNotEqualPlayers,
+        NotEnoughMafia,
+        TooMuchMafia,
         CodeOk,
     }
 }

+ 414 - 837
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,1479 +45,1071 @@ 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 automatically_choosed_target {
+        internal static string winrate {
             get {
-                return ResourceManager.GetString("automatically_choosed_target", resourceCulture);
+                return ResourceManager.GetString("winrate", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра начинается....
-        /// </summary>
-        internal static string bot_starting_game {
+        internal static string shop {
             get {
-                return ResourceManager.GetString("bot_starting_game", resourceCulture);
+                return ResourceManager.GetString("shop", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to но он оказался старейшийной.
-        /// </summary>
-        internal static string but_he_is_elder {
+        internal static string my_roles {
             get {
-                return ResourceManager.GetString("but_he_is_elder", resourceCulture);
+                return ResourceManager.GetString("my_roles", resourceCulture);
+            }
+        }
+        
+        internal static string settings {
+            get {
+                return ResourceManager.GetString("settings", resourceCulture);
+            }
+        }
+        
+        internal static string your_name {
+            get {
+                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 check {
+        internal static string name_updated {
             get {
-                return ResourceManager.GetString("check", resourceCulture);
+                return ResourceManager.GetString("name_updated", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите первую цель для сравнения.
-        /// </summary>
-        internal static string choose_first {
+        internal static string command_not_found {
             get {
-                return ResourceManager.GetString("choose_first", resourceCulture);
+                return ResourceManager.GetString("command_not_found", resourceCulture);
+            }
+        }
+        
+        internal static string settings_room {
+            get {
+                return ResourceManager.GetString("settings_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите режим игры.
-        /// </summary>
         internal static string choose_game_type {
             get {
                 return ResourceManager.GetString("choose_game_type", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите цель для блокировки.
-        /// </summary>
-        internal static string choose_player_to_block {
+        internal static string enter_room_name {
             get {
-                return ResourceManager.GetString("choose_player_to_block", resourceCulture);
+                return ResourceManager.GetString("enter_room_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для проверки роли или убийства.
-        /// </summary>
-        internal static string choose_player_to_check_or_kill {
+        internal static string room_with_name {
             get {
-                return ResourceManager.GetString("choose_player_to_check_or_kill", resourceCulture);
+                return ResourceManager.GetString("room_with_name", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для проверки роли.
-        /// </summary>
-        internal static string choose_player_to_check_role {
+        internal static string was_created {
             get {
-                return ResourceManager.GetString("choose_player_to_check_role", resourceCulture);
+                return ResourceManager.GetString("was_created", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для лечения.
-        /// </summary>
-        internal static string choose_player_to_heal {
+        internal static string unexpected_error {
             get {
-                return ResourceManager.GetString("choose_player_to_heal", resourceCulture);
+                return ResourceManager.GetString("unexpected_error", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите свою жертву.
-        /// </summary>
-        internal static string choose_player_to_kill {
+        internal static string game_already_exists {
             get {
-                return ResourceManager.GetString("choose_player_to_kill", resourceCulture);
+                return ResourceManager.GetString("game_already_exists", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите игрока для воскрешения. Внимание, вы можете воскресить только одного игрока за игру!.
-        /// </summary>
-        internal static string choose_player_to_ressurect {
+        internal static string leave_from_game {
             get {
-                return ResourceManager.GetString("choose_player_to_ressurect", resourceCulture);
+                return ResourceManager.GetString("leave_from_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выбрите вторую цель для сравнения.
-        /// </summary>
-        internal static string choose_second {
+        internal static string user_not_in_game {
             get {
-                return ResourceManager.GetString("choose_second", resourceCulture);
+                return ResourceManager.GetString("user_not_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите цель для защиты.
-        /// </summary>
-        internal static string choose_target_to_protect {
+        internal static string standart {
             get {
-                return ResourceManager.GetString("choose_target_to_protect", resourceCulture);
+                return ResourceManager.GetString("standart", resourceCulture);
+            }
+        }
+        
+        internal static string extended {
+            get {
+                return ResourceManager.GetString("extended", resourceCulture);
+            }
+        }
+        
+        internal static string secret_key_is {
+            get {
+                return ResourceManager.GetString("secret_key_is", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите тип комнаты.
-        /// </summary>
         internal static string choose_type_room {
             get {
                 return ResourceManager.GetString("choose_type_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выберите вашего носителя.
-        /// </summary>
-        internal static string choose_your_container {
+        internal static string enter_private_code {
             get {
-                return ResourceManager.GetString("choose_your_container", resourceCulture);
+                return ResourceManager.GetString("enter_private_code", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Выбранные цели.
-        /// </summary>
-        internal static string choosed_targets {
+        internal static string room_is_filled {
             get {
-                return ResourceManager.GetString("choosed_targets", resourceCulture);
+                return ResourceManager.GetString("room_is_filled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Город засыпает.
-        /// </summary>
-        internal static string city_falls_asleep {
+        internal static string user_already_in_game {
             get {
-                return ResourceManager.GetString("city_falls_asleep", resourceCulture);
+                return ResourceManager.GetString("user_already_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Город просыпается и обнаруживает, что... .
-        /// </summary>
-        internal static string city_wakes_up {
+        internal static string successful_entry_into_room {
             get {
-                return ResourceManager.GetString("city_wakes_up", resourceCulture);
+                return ResourceManager.GetString("successful_entry_into_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to их цвет ролей не совпадает.
-        /// </summary>
-        internal static string color_is_different {
+        internal static string users_list {
             get {
-                return ResourceManager.GetString("color_is_different", resourceCulture);
+                return ResourceManager.GetString("users_list", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to их цвет ролей совпадает.
-        /// </summary>
-        internal static string color_is_same {
+        internal static string users_list_empty {
             get {
-                return ResourceManager.GetString("color_is_same", resourceCulture);
+                return ResourceManager.GetString("users_list_empty", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Команда не найдена.
-        /// </summary>
-        internal static string command_not_found {
+        internal static string max_capacity_message {
             get {
-                return ResourceManager.GetString("command_not_found", resourceCulture);
+                return ResourceManager.GetString("max_capacity_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to подключился к игре.
-        /// </summary>
-        internal static string connected_to_game {
+        internal static string prefer_leave_from_room {
             get {
-                return ResourceManager.GetString("connected_to_game", resourceCulture);
+                return ResourceManager.GetString("prefer_leave_from_room", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Запустить игру или настроить рассадку?.
-        /// </summary>
-        internal static string continue_question {
+        internal static string room_does_not_exists {
             get {
-                return ResourceManager.GetString("continue_question", resourceCulture);
+                return ResourceManager.GetString("room_does_not_exists", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Текущая рассадка в комнате:.
-        /// </summary>
-        internal static string current_enabled_roles {
+        internal static string public_rooms_are_not_exist {
             get {
-                return ResourceManager.GetString("current_enabled_roles", resourceCulture);
+                return ResourceManager.GetString("public_rooms_are_not_exist", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Дама заткнула рот кляпом игроку.
-        /// </summary>
-        internal static string dame_block_player {
+        internal static string rooms {
             get {
-                return ResourceManager.GetString("dame_block_player", resourceCulture);
+                return ResourceManager.GetString("rooms", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Дама заткнула вам рот кляпом. Вы не сможете разговаривать и голосовать в этот день..
-        /// </summary>
-        internal static string dame_block_you {
+        internal static string too_many_players {
             get {
-                return ResourceManager.GetString("dame_block_you", resourceCulture);
+                return ResourceManager.GetString("too_many_players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Дневное обсуждение окончено.
-        /// </summary>
-        internal static string day_discussion_ended {
+        internal static string too_few_players {
             get {
-                return ResourceManager.GetString("day_discussion_ended", resourceCulture);
+                return ResourceManager.GetString("too_few_players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to мертвый.
-        /// </summary>
-        internal static string died {
+        internal static string game_already_running {
             get {
-                return ResourceManager.GetString("died", resourceCulture);
+                return ResourceManager.GetString("game_already_running", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to отключен.
-        /// </summary>
-        internal static string disabled {
+        internal static string minimum_players_count {
             get {
-                return ResourceManager.GetString("disabled", resourceCulture);
+                return ResourceManager.GetString("minimum_players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to казнен.
-        /// </summary>
-        internal static string dispatched {
+        internal static string maximum_players_count {
             get {
-                return ResourceManager.GetString("dispatched", resourceCulture);
+                return ResourceManager.GetString("maximum_players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Время обсуждения! У всех игроков есть минута, чтобы что-то сказать..
-        /// </summary>
-        internal static string disscution_time {
+        internal static string maximum_was_set_to {
             get {
-                return ResourceManager.GetString("disscution_time", resourceCulture);
+                return ResourceManager.GetString("maximum_was_set_to", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Если не наберется минимальное количество игроков, комната будет распущена через 2 минуты!.
-        /// </summary>
-        internal static string dissolve_warning {
+        internal static string players {
             get {
-                return ResourceManager.GetString("dissolve_warning", resourceCulture);
+                return ResourceManager.GetString("players", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to включен.
-        /// </summary>
-        internal static string enabled {
+        internal static string kick {
             get {
-                return ResourceManager.GetString("enabled", resourceCulture);
+                return ResourceManager.GetString("kick", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите код от комнаты.
-        /// </summary>
-        internal static string enter_private_code {
+        internal static string kick_user {
             get {
-                return ResourceManager.GetString("enter_private_code", resourceCulture);
+                return ResourceManager.GetString("kick_user", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите название комнаты.
-        /// </summary>
-        internal static string enter_room_name {
+        internal static string you_were_kicked {
             get {
-                return ResourceManager.GetString("enter_room_name", resourceCulture);
+                return ResourceManager.GetString("you_were_kicked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Введите ваше имя.
-        /// </summary>
-        internal static string enter_your_name {
+        internal static string room_dissolved {
             get {
-                return ResourceManager.GetString("enter_your_name", resourceCulture);
+                return ResourceManager.GetString("room_dissolved", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to все игроки остались в живых!.
-        /// </summary>
-        internal static string everyone_survived {
+        internal static string timer {
             get {
-                return ResourceManager.GetString("everyone_survived", resourceCulture);
+                return ResourceManager.GetString("timer", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Расширенный.
-        /// </summary>
-        internal static string extended {
+        internal static string enabled {
             get {
-                return ResourceManager.GetString("extended", resourceCulture);
+                return ResourceManager.GetString("enabled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Пока мирные жители спали, в городе завелась мафия. Город собрался на главной площади и жители решают, кто среди них предатель..
-        /// </summary>
-        internal static string first_day_message {
+        internal static string disabled {
             get {
-                return ResourceManager.GetString("first_day_message", resourceCulture);
+                return ResourceManager.GetString("disabled", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to По неизвестным причинам умер игрок.
-        /// </summary>
-        internal static string for_unknown_reasons_died {
+        internal static string _public {
             get {
-                return ResourceManager.GetString("for_unknown_reasons_died", resourceCulture);
+                return ResourceManager.GetString("public", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната с таким именем уже существует.
-        /// </summary>
-        internal static string game_already_exists {
+        internal static string _private {
             get {
-                return ResourceManager.GetString("game_already_exists", resourceCulture);
+                return ResourceManager.GetString("private", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра уже запущена.
-        /// </summary>
-        internal static string game_already_running {
+        internal static string bot_starting_game {
             get {
-                return ResourceManager.GetString("game_already_running", resourceCulture);
+                return ResourceManager.GetString("bot_starting_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Процесс подготовки комнаты начался.
-        /// </summary>
         internal static string game_process_started {
             get {
                 return ResourceManager.GetString("game_process_started", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Число игр:.
-        /// </summary>
-        internal static string games_count {
+        internal static string connected_to_game {
             get {
-                return ResourceManager.GetString("games_count", resourceCulture);
+                return ResourceManager.GetString("connected_to_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Проститутка переспала с вами. Ваши действия этой ночью ограничены..
-        /// </summary>
-        internal static string hooker_block_you {
+        internal static string your_turn_order {
             get {
-                return ResourceManager.GetString("hooker_block_you", resourceCulture);
+                return ResourceManager.GetString("your_turn_order", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В этой игре участвовали:.
-        /// </summary>
-        internal static string in_this_game_roles {
+        internal static string your_role {
             get {
-                return ResourceManager.GetString("in_this_game_roles", resourceCulture);
+                return ResourceManager.GetString("your_role", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В этой игре имеются следующие роли:.
-        /// </summary>
-        internal static string in_this_game_we_have {
+        internal static string thanks_for_game {
             get {
-                return ResourceManager.GetString("in_this_game_we_have", resourceCulture);
+                return ResourceManager.GetString("thanks_for_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to выдается посмертная минута..
-        /// </summary>
-        internal static string issued_posthumous_minute {
+        internal static string link {
             get {
-                return ResourceManager.GetString("issued_posthumous_minute", resourceCulture);
+                return ResourceManager.GetString("link", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Исключить.
-        /// </summary>
-        internal static string kick {
+        internal static string you_leave_from_game {
             get {
-                return ResourceManager.GetString("kick", resourceCulture);
+                return ResourceManager.GetString("you_leave_from_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Исключить пользователя.
-        /// </summary>
-        internal static string kick_user {
+        internal static string your_teammates {
             get {
-                return ResourceManager.GetString("kick_user", resourceCulture);
+                return ResourceManager.GetString("your_teammates", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to убить.
-        /// </summary>
-        internal static string kill {
+        internal static string first_day_message {
             get {
-                return ResourceManager.GetString("kill", resourceCulture);
+                return ResourceManager.GetString("first_day_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to покинул игру.
-        /// </summary>
-        internal static string leave_from_game {
+        internal static string city_falls_asleep {
             get {
-                return ResourceManager.GetString("leave_from_game", resourceCulture);
+                return ResourceManager.GetString("city_falls_asleep", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ссылка для подключения к комнате.
-        /// </summary>
-        internal static string link {
+        internal static string now_turn {
             get {
-                return ResourceManager.GetString("link", resourceCulture);
+                return ResourceManager.GetString("now_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Мафия не смогла выбрать жертву.
-        /// </summary>
-        internal static string mafia_not_kill_message {
+        internal static string your_turn_ended {
             get {
-                return ResourceManager.GetString("mafia_not_kill_message", resourceCulture);
+                return ResourceManager.GetString("your_turn_ended", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ура! Победила мафия....
-        /// </summary>
-        internal static string mafia_won {
+        internal static string now_is_not_your_turn {
             get {
-                return ResourceManager.GetString("mafia_won", resourceCulture);
+                return ResourceManager.GetString("now_is_not_your_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимальное кол-во игроков.
-        /// </summary>
-        internal static string max_capacity_message {
+        internal static string your_turn {
             get {
-                return ResourceManager.GetString("max_capacity_message", resourceCulture);
+                return ResourceManager.GetString("your_turn", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимум - 16 игроков.
-        /// </summary>
-        internal static string maximum_players_count {
+        internal static string players_list {
             get {
-                return ResourceManager.GetString("maximum_players_count", resourceCulture);
+                return ResourceManager.GetString("players_list", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Максимум был установлен на.
-        /// </summary>
-        internal static string maximum_was_set_to {
+        internal static string you_now_died {
             get {
-                return ResourceManager.GetString("maximum_was_set_to", resourceCulture);
+                return ResourceManager.GetString("you_now_died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Минимум - 6 игроков.
-        /// </summary>
-        internal static string minimum_players_count {
+        internal static string alive {
             get {
-                return ResourceManager.GetString("minimum_players_count", resourceCulture);
+                return ResourceManager.GetString("alive", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Мои роли.
-        /// </summary>
-        internal static string my_roles {
+        internal static string died {
             get {
-                return ResourceManager.GetString("my_roles", resourceCulture);
+                return ResourceManager.GetString("died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Имя было обновлено на.
-        /// </summary>
-        internal static string name_updated {
+        internal static string room_owner {
             get {
-                return ResourceManager.GetString("name_updated", resourceCulture);
+                return ResourceManager.GetString("room_owner", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Никто ни за кого не проголосовал.
-        /// </summary>
-        internal static string no_one_voted {
+        internal static string put_up_vote {
             get {
-                return ResourceManager.GetString("no_one_voted", resourceCulture);
+                return ResourceManager.GetString("put_up_vote", resourceCulture);
+            }
+        }
+        
+        internal static string skip_vote {
+            get {
+                return ResourceManager.GetString("skip_vote", resourceCulture);
+            }
+        }
+        
+        internal static string skip {
+            get {
+                return ResourceManager.GetString("skip", resourceCulture);
+            }
+        }
+        
+        internal static string user_not_choose {
+            get {
+                return ResourceManager.GetString("user_not_choose", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Данная команда не поддерживается во время игры.
-        /// </summary>
         internal static string not_supported_in_game {
             get {
                 return ResourceManager.GetString("not_supported_in_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Не из кого выбирать.
-        /// </summary>
-        internal static string nothing_to_choose {
+        internal static string you_skip_vote {
             get {
-                return ResourceManager.GetString("nothing_to_choose", resourceCulture);
+                return ResourceManager.GetString("you_skip_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вам некого лечить этой ночью.
-        /// </summary>
-        internal static string nothing_to_heal {
+        internal static string you_vote_player {
             get {
-                return ResourceManager.GetString("nothing_to_heal", resourceCulture);
+                return ResourceManager.GetString("you_vote_player", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Некого воскрешать.
-        /// </summary>
-        internal static string nothing_to_ressurect {
+        internal static string put_up_vote_to {
             get {
-                return ResourceManager.GetString("nothing_to_ressurect", resourceCulture);
+                return ResourceManager.GetString("put_up_vote_to", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Некого казнить.
-        /// </summary>
-        internal static string nothing_up_to_dispatch {
+        internal static string vote_to_self {
             get {
-                return ResourceManager.GetString("nothing_up_to_dispatch", resourceCulture);
+                return ResourceManager.GetString("vote_to_self", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Никто не выставлен на голосование.
-        /// </summary>
-        internal static string nothing_up_to_vote {
+        internal static string you_vote_to_self {
             get {
-                return ResourceManager.GetString("nothing_up_to_vote", resourceCulture);
+                return ResourceManager.GetString("you_vote_to_self", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас оправдывается.
-        /// </summary>
-        internal static string now_defence {
+        internal static string choose_player_to_check_role {
             get {
-                return ResourceManager.GetString("now_defence", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_check_role", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас не ваш ход.
-        /// </summary>
-        internal static string now_is_not_your_turn {
+        internal static string you_have_not_choosen_target {
             get {
-                return ResourceManager.GetString("now_is_not_your_turn", resourceCulture);
+                return ResourceManager.GetString("you_have_not_choosen_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас ходит.
-        /// </summary>
-        internal static string now_turn {
+        internal static string you_choose_target {
             get {
-                return ResourceManager.GetString("now_turn", resourceCulture);
+                return ResourceManager.GetString("you_choose_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сейчас вы не можете разговаривать.
-        /// </summary>
-        internal static string now_you_cant_speak {
+        internal static string role_of_your_target {
             get {
-                return ResourceManager.GetString("now_you_cant_speak", resourceCulture);
+                return ResourceManager.GetString("role_of_your_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Он не сможет разговаривать и голосовать в этот день..
-        /// </summary>
-        internal static string player_cant_talk_and_vote {
+        internal static string choose_player_to_heal {
             get {
-                return ResourceManager.GetString("player_cant_talk_and_vote", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_heal", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to но у него есть алиби.
-        /// </summary>
-        internal static string player_not_died_he_has_alibi {
+        internal static string you_turn_say {
             get {
-                return ResourceManager.GetString("player_not_died_he_has_alibi", resourceCulture);
+                return ResourceManager.GetString("you_turn_say", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игрок паразит с мертвой целью, воскрешние прошло неудачно!.
-        /// </summary>
-        internal static string player_parasit_with_dead_owner {
+        internal static string dame_block_you {
             get {
-                return ResourceManager.GetString("player_parasit_with_dead_owner", resourceCulture);
+                return ResourceManager.GetString("dame_block_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to игроков.
-        /// </summary>
-        internal static string players {
+        internal static string hooker_block_you {
             get {
-                return ResourceManager.GetString("players", resourceCulture);
+                return ResourceManager.GetString("hooker_block_you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Количество игроков.
-        /// </summary>
-        internal static string players_count {
+        internal static string nothing_to_heal {
             get {
-                return ResourceManager.GetString("players_count", resourceCulture);
+                return ResourceManager.GetString("nothing_to_heal", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Список игроков.
-        /// </summary>
-        internal static string players_list {
+        internal static string city_wakes_up {
             get {
-                return ResourceManager.GetString("players_list", resourceCulture);
+                return ResourceManager.GetString("city_wakes_up", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Количество игроков не равно количеству ролей.
-        /// </summary>
-        internal static string players_not_equal_roles {
+        internal static string everyone_survived {
             get {
-                return ResourceManager.GetString("players_not_equal_roles", resourceCulture);
+                return ResourceManager.GetString("everyone_survived", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Сначала покиньте комнату.
-        /// </summary>
-        internal static string prefer_leave_from_room {
+        internal static string you_have_twenty_seconds {
             get {
-                return ResourceManager.GetString("prefer_leave_from_room", resourceCulture);
+                return ResourceManager.GetString("you_have_twenty_seconds", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Нет свободных публичных комнат.
-        /// </summary>
-        internal static string public_rooms_are_not_exist {
+        internal static string choose_player_to_kill {
             get {
-                return ResourceManager.GetString("public_rooms_are_not_exist", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_kill", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Кого вы хотите выставить на голосование?.
-        /// </summary>
-        internal static string put_up_vote {
+        internal static string villagers_won {
             get {
-                return ResourceManager.GetString("put_up_vote", resourceCulture);
+                return ResourceManager.GetString("villagers_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to выставил на голосование игрока.
-        /// </summary>
-        internal static string put_up_vote_to {
+        internal static string mafia_won {
             get {
-                return ResourceManager.GetString("put_up_vote_to", resourceCulture);
+                return ResourceManager.GetString("mafia_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Итоги голосования:.
-        /// </summary>
-        internal static string results_of_voting {
+        internal static string in_this_game_roles {
             get {
-                return ResourceManager.GetString("results_of_voting", resourceCulture);
+                return ResourceManager.GetString("in_this_game_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Роль игрока.
-        /// </summary>
-        internal static string role_of_your_target {
+        internal static string now_defence {
             get {
-                return ResourceManager.GetString("role_of_your_target", resourceCulture);
+                return ResourceManager.GetString("now_defence", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната распущена.
-        /// </summary>
-        internal static string room_dissolved {
+        internal static string time_out {
+            get {
+                return ResourceManager.GetString("time_out", resourceCulture);
+            }
+        }
+        
+        internal static string villagers_could_not_decide {
+            get {
+                return ResourceManager.GetString("villagers_could_not_decide", resourceCulture);
+            }
+        }
+        
+        internal static string to_player {
+            get {
+                return ResourceManager.GetString("to_player", resourceCulture);
+            }
+        }
+        
+        internal static string issued_posthumous_minute {
+            get {
+                return ResourceManager.GetString("issued_posthumous_minute", resourceCulture);
+            }
+        }
+        
+        internal static string villagers_want_dispatch {
+            get {
+                return ResourceManager.GetString("villagers_want_dispatch", resourceCulture);
+            }
+        }
+        
+        internal static string but_he_is_elder {
+            get {
+                return ResourceManager.GetString("but_he_is_elder", resourceCulture);
+            }
+        }
+        
+        internal static string activity_blocked {
             get {
-                return ResourceManager.GetString("room_dissolved", resourceCulture);
+                return ResourceManager.GetString("activity_blocked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната не существует.
-        /// </summary>
-        internal static string room_does_not_exists {
+        internal static string you_heal_yourself {
             get {
-                return ResourceManager.GetString("room_does_not_exists", resourceCulture);
+                return ResourceManager.GetString("you_heal_yourself", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната заполнена.
-        /// </summary>
-        internal static string room_is_filled {
+        internal static string change_roles {
             get {
-                return ResourceManager.GetString("room_is_filled", resourceCulture);
+                return ResourceManager.GetString("change_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to владелец комнаты.
-        /// </summary>
-        internal static string room_owner {
+        internal static string players_count {
             get {
-                return ResourceManager.GetString("room_owner", resourceCulture);
+                return ResourceManager.GetString("players_count", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комната с именем.
-        /// </summary>
-        internal static string room_with_name {
+        internal static string what_settings {
             get {
-                return ResourceManager.GetString("room_with_name", resourceCulture);
+                return ResourceManager.GetString("what_settings", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Комнаты.
-        /// </summary>
-        internal static string rooms {
+        internal static string current_enabled_roles {
             get {
-                return ResourceManager.GetString("rooms", resourceCulture);
+                return ResourceManager.GetString("current_enabled_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Запустить игру.
-        /// </summary>
-        internal static string run_game {
+        internal static string choose_player_to_block {
             get {
-                return ResourceManager.GetString("run_game", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_block", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Секретный код для подключения к комнате.
-        /// </summary>
-        internal static string secret_key_is {
+        internal static string you_blocked {
             get {
-                return ResourceManager.GetString("secret_key_is", resourceCulture);
+                return ResourceManager.GetString("you_blocked", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Настройки.
-        /// </summary>
-        internal static string settings {
+        internal static string now_you_cant_speak {
             get {
-                return ResourceManager.GetString("settings", resourceCulture);
+                return ResourceManager.GetString("now_you_cant_speak", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Задайте настройки комнаты.
-        /// </summary>
-        internal static string settings_room {
+        internal static string will_be_ressurected {
             get {
-                return ResourceManager.GetString("settings_room", resourceCulture);
+                return ResourceManager.GetString("will_be_ressurected", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Магазин.
-        /// </summary>
-        internal static string shop {
+        internal static string will_be_killed {
             get {
-                return ResourceManager.GetString("shop", resourceCulture);
+                return ResourceManager.GetString("will_be_killed", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Пропустить.
-        /// </summary>
-        internal static string skip {
+        internal static string choose_target_to_protect {
             get {
-                return ResourceManager.GetString("skip", resourceCulture);
+                return ResourceManager.GetString("choose_target_to_protect", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to пропустил голосование.
-        /// </summary>
-        internal static string skip_vote {
+        internal static string players_not_equal_roles {
             get {
-                return ResourceManager.GetString("skip_vote", resourceCulture);
+                return ResourceManager.GetString("players_not_equal_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Стандартный.
-        /// </summary>
-        internal static string standart {
+        internal static string you_have_eigty_seconds_to_defence {
             get {
-                return ResourceManager.GetString("standart", resourceCulture);
+                return ResourceManager.GetString("you_have_eigty_seconds_to_defence", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Что вы хотите сделать?.
-        /// </summary>
-        internal static string start_message {
+        internal static string player_not_died_he_has_alibi {
             get {
-                return ResourceManager.GetString("start_message", resourceCulture);
+                return ResourceManager.GetString("player_not_died_he_has_alibi", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Статистика для.
-        /// </summary>
-        internal static string statistics_for {
+        internal static string in_this_game_we_have {
             get {
-                return ResourceManager.GetString("statistics_for", resourceCulture);
+                return ResourceManager.GetString("in_this_game_we_have", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были добавлены в комнату.
-        /// </summary>
-        internal static string successful_entry_into_room {
+        internal static string mafia_not_kill_message {
             get {
-                return ResourceManager.GetString("successful_entry_into_room", resourceCulture);
+                return ResourceManager.GetString("mafia_not_kill_message", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игра окончена, спасибо за игру!.
-        /// </summary>
-        internal static string thanks_for_game {
+        internal static string you_will_be_ressurected {
             get {
-                return ResourceManager.GetString("thanks_for_game", resourceCulture);
+                return ResourceManager.GetString("you_will_be_ressurected", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Дурачок оказался там, где ему и следовало.
-        /// </summary>
-        internal static string the_fool_won {
+        internal static string you_will_be_killed {
             get {
-                return ResourceManager.GetString("the_fool_won", resourceCulture);
+                return ResourceManager.GetString("you_will_be_killed", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Паразит остался при своём носителе.
-        /// </summary>
-        internal static string the_parasite_won {
+        internal static string vote_to {
             get {
-                return ResourceManager.GetString("the_parasite_won", resourceCulture);
+                return ResourceManager.GetString("vote_to", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Этот игрок покинул игру.
-        /// </summary>
-        internal static string this_player_left_from_game {
+        internal static string results_of_voting {
             get {
-                return ResourceManager.GetString("this_player_left_from_game", resourceCulture);
+                return ResourceManager.GetString("results_of_voting", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Время вышло.
-        /// </summary>
-        internal static string time_out {
+        internal static string no_one_voted {
             get {
-                return ResourceManager.GetString("time_out", resourceCulture);
+                return ResourceManager.GetString("no_one_voted", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Таймер.
-        /// </summary>
-        internal static string timer {
+        internal static string run_game {
             get {
-                return ResourceManager.GetString("timer", resourceCulture);
+                return ResourceManager.GetString("run_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Игроку.
-        /// </summary>
-        internal static string to_player {
+        internal static string continue_question {
             get {
-                return ResourceManager.GetString("to_player", resourceCulture);
+                return ResourceManager.GetString("continue_question", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Недостаточно игроков для старта игры.
-        /// </summary>
-        internal static string too_few_players {
+        internal static string disscution_time {
             get {
-                return ResourceManager.GetString("too_few_players", resourceCulture);
+                return ResourceManager.GetString("disscution_time", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Количество игроков превышает максимальное.
-        /// </summary>
-        internal static string too_many_players {
+        internal static string you {
             get {
-                return ResourceManager.GetString("too_many_players", resourceCulture);
+                return ResourceManager.GetString("you", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Произошла неожиданная ошибка... Попробуйте ещё раз..
-        /// </summary>
-        internal static string unexpected_error {
+        internal static string day_discussion_ended {
             get {
-                return ResourceManager.GetString("unexpected_error", resourceCulture);
+                return ResourceManager.GetString("day_discussion_ended", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы уже находитесь в игре.
-        /// </summary>
-        internal static string user_already_in_game {
+        internal static string you_will_be_dispatched {
             get {
-                return ResourceManager.GetString("user_already_in_game", resourceCulture);
+                return ResourceManager.GetString("you_will_be_dispatched", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Иначе вы будете выставлены на голосование.
-        /// </summary>
-        internal static string user_not_choose {
+        internal static string you_have_ten_seconds_to_vote {
             get {
-                return ResourceManager.GetString("user_not_choose", resourceCulture);
+                return ResourceManager.GetString("you_have_ten_seconds_to_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы не находитесь сейчас в игре.
-        /// </summary>
-        internal static string user_not_in_game {
+        internal static string automatically_choosed_target {
             get {
-                return ResourceManager.GetString("user_not_in_game", resourceCulture);
+                return ResourceManager.GetString("automatically_choosed_target", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Участники в комнате.
-        /// </summary>
-        internal static string users_list {
+        internal static string you_won {
             get {
-                return ResourceManager.GetString("users_list", resourceCulture);
+                return ResourceManager.GetString("you_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to В комнате нет игроков, кроме Вас.
-        /// </summary>
-        internal static string users_list_empty {
+        internal static string dissolve_warning {
             get {
-                return ResourceManager.GetString("users_list_empty", resourceCulture);
+                return ResourceManager.GetString("dissolve_warning", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Жители так и не смогли решить кого казнить....
-        /// </summary>
-        internal static string villagers_could_not_decide {
+        internal static string the_fool_won {
             get {
-                return ResourceManager.GetString("villagers_could_not_decide", resourceCulture);
+                return ResourceManager.GetString("the_fool_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Жители хотели повесить игрока.
-        /// </summary>
-        internal static string villagers_want_dispatch {
+        internal static string nothing_up_to_vote {
             get {
-                return ResourceManager.GetString("villagers_want_dispatch", resourceCulture);
+                return ResourceManager.GetString("nothing_up_to_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ура! Победили мирные жители....
-        /// </summary>
-        internal static string villagers_won {
+        internal static string nothing_up_to_dispatch {
             get {
-                return ResourceManager.GetString("villagers_won", resourceCulture);
+                return ResourceManager.GetString("nothing_up_to_dispatch", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to проголосовал против.
-        /// </summary>
-        internal static string vote_to {
+        internal static string this_player_left_from_game {
             get {
-                return ResourceManager.GetString("vote_to", resourceCulture);
+                return ResourceManager.GetString("this_player_left_from_game", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to выставил самого себя..
-        /// </summary>
-        internal static string vote_to_self {
+        internal static string you_vote_to_kill {
             get {
-                return ResourceManager.GetString("vote_to_self", resourceCulture);
+                return ResourceManager.GetString("you_vote_to_kill", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to была создана.
-        /// </summary>
-        internal static string was_created {
+        internal static string you_vote_to_kill_self {
             get {
-                return ResourceManager.GetString("was_created", resourceCulture);
+                return ResourceManager.GetString("you_vote_to_kill_self", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Что вы хотите настроить?.
-        /// </summary>
-        internal static string what_settings {
+        internal static string you_have_been_chosen_by_the_parasite {
             get {
-                return ResourceManager.GetString("what_settings", resourceCulture);
+                return ResourceManager.GetString("you_have_been_chosen_by_the_parasite", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to был убит.
-        /// </summary>
-        internal static string will_be_killed {
+        internal static string the_parasite_won {
             get {
-                return ResourceManager.GetString("will_be_killed", resourceCulture);
+                return ResourceManager.GetString("the_parasite_won", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to был воскрешен.
-        /// </summary>
-        internal static string will_be_ressurected {
+        internal static string choose_player_to_ressurect {
             get {
-                return ResourceManager.GetString("will_be_ressurected", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_ressurect", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Винрейт:.
-        /// </summary>
-        internal static string winrate {
+        internal static string nothing_to_ressurect {
             get {
-                return ResourceManager.GetString("winrate", resourceCulture);
+                return ResourceManager.GetString("nothing_to_ressurect", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Число побед:.
-        /// </summary>
-        internal static string wins_count {
+        internal static string choose_your_container {
             get {
-                return ResourceManager.GetString("wins_count", resourceCulture);
+                return ResourceManager.GetString("choose_your_container", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы.
-        /// </summary>
-        internal static string you {
+        internal static string nothing_to_choose {
             get {
-                return ResourceManager.GetString("you", resourceCulture);
+                return ResourceManager.GetString("nothing_to_choose", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы заблокированы, у вас кляп во рту.
-        /// </summary>
-        internal static string you_blocked {
+        internal static string dame_block_player {
             get {
-                return ResourceManager.GetString("you_blocked", resourceCulture);
+                return ResourceManager.GetString("dame_block_player", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выбрали игрока.
-        /// </summary>
-        internal static string you_choose_target {
+        internal static string player_cant_talk_and_vote {
             get {
-                return ResourceManager.GetString("you_choose_target", resourceCulture);
+                return ResourceManager.GetString("player_cant_talk_and_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вас выбрал паразит -.
-        /// </summary>
-        internal static string you_have_been_chosen_by_the_parasite {
+        internal static string dispatched {
             get {
-                return ResourceManager.GetString("you_have_been_chosen_by_the_parasite", resourceCulture);
+                return ResourceManager.GetString("dispatched", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У вас есть 90 секунд на оправдание.
-        /// </summary>
-        internal static string you_have_eigty_seconds_to_defence {
+        internal static string choose_first {
             get {
-                return ResourceManager.GetString("you_have_eigty_seconds_to_defence", resourceCulture);
+                return ResourceManager.GetString("choose_first", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы не выбрали цель.
-        /// </summary>
-        internal static string you_have_not_choosen_target {
+        internal static string choose_second {
             get {
-                return ResourceManager.GetString("you_have_not_choosen_target", resourceCulture);
+                return ResourceManager.GetString("choose_second", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У вас есть 20 секунд, чтобы выставить игрока на голосование.
-        /// </summary>
-        internal static string you_have_ten_seconds {
+        internal static string color_is_same {
             get {
-                return ResourceManager.GetString("you_have_ten_seconds", resourceCulture);
+                return ResourceManager.GetString("color_is_same", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У вас есть 20 секунд, чтобы проголосовать за игрока.
-        /// </summary>
-        internal static string you_have_ten_seconds_to_vote {
+        internal static string color_is_different {
             get {
-                return ResourceManager.GetString("you_have_ten_seconds_to_vote", resourceCulture);
+                return ResourceManager.GetString("color_is_different", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы вылечили сами себя.
-        /// </summary>
-        internal static string you_heal_yourself {
+        internal static string choose_player_to_check_or_kill {
             get {
-                return ResourceManager.GetString("you_heal_yourself", resourceCulture);
+                return ResourceManager.GetString("choose_player_to_check_or_kill", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы покинули игру.
-        /// </summary>
-        internal static string you_leave_from_game {
+        internal static string check {
             get {
-                return ResourceManager.GetString("you_leave_from_game", resourceCulture);
+                return ResourceManager.GetString("check", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы мертвы и не можете говорить!.
-        /// </summary>
-        internal static string you_now_died {
+        internal static string kill {
             get {
-                return ResourceManager.GetString("you_now_died", resourceCulture);
+                return ResourceManager.GetString("kill", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы пропустили голосование.
-        /// </summary>
-        internal static string you_skip_vote {
+        internal static string for_unknown_reasons_died {
             get {
-                return ResourceManager.GetString("you_skip_vote", resourceCulture);
+                return ResourceManager.GetString("for_unknown_reasons_died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to У Вас есть минута, чтобы что-то сказать.
-        /// </summary>
-        internal static string you_turn_say {
+        internal static string your_carrier_player_has_died {
             get {
-                return ResourceManager.GetString("you_turn_say", resourceCulture);
+                return ResourceManager.GetString("your_carrier_player_has_died", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выбрали игрока.
-        /// </summary>
-        internal static string you_vote_player {
+        internal static string choosed_targets {
             get {
-                return ResourceManager.GetString("you_vote_player", resourceCulture);
+                return ResourceManager.GetString("choosed_targets", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы проголосовали за.
-        /// </summary>
-        internal static string you_vote_to_kill {
+        internal static string player_parasit_with_dead_owner {
             get {
-                return ResourceManager.GetString("you_vote_to_kill", resourceCulture);
+                return ResourceManager.GetString("player_parasit_with_dead_owner", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы проголосовали за себя.
-        /// </summary>
-        internal static string you_vote_to_kill_self {
+        internal static string automatically_vote {
             get {
-                return ResourceManager.GetString("you_vote_to_kill_self", resourceCulture);
+                return ResourceManager.GetString("automatically_vote", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы выставили самого себя.
-        /// </summary>
-        internal static string you_vote_to_self {
+        internal static string exit {
             get {
-                return ResourceManager.GetString("you_vote_to_self", resourceCulture);
+                return ResourceManager.GetString("exit", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были исключены.
-        /// </summary>
-        internal static string you_were_kicked {
+        internal static string confirm_exit {
             get {
-                return ResourceManager.GetString("you_were_kicked", resourceCulture);
+                return ResourceManager.GetString("confirm_exit", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы будете казнены, у вас есть минута на прощание..
-        /// </summary>
-        internal static string you_will_be_dispatched {
+        internal static string to_confirm_exit {
             get {
-                return ResourceManager.GetString("you_will_be_dispatched", resourceCulture);
+                return ResourceManager.GetString("to_confirm_exit", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были убиты.
-        /// </summary>
-        internal static string you_will_be_killed {
+        internal static string too_much_mafia {
             get {
-                return ResourceManager.GetString("you_will_be_killed", resourceCulture);
+                return ResourceManager.GetString("too_much_mafia", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы были воскрешены.
-        /// </summary>
-        internal static string you_will_be_ressurected {
+        internal static string not_enogh_mafia {
             get {
-                return ResourceManager.GetString("you_will_be_ressurected", resourceCulture);
+                return ResourceManager.GetString("not_enogh_mafia", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы победили.
-        /// </summary>
-        internal static string you_won {
+        internal static string next {
             get {
-                return ResourceManager.GetString("you_won", resourceCulture);
+                return ResourceManager.GetString("next", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваш игрок-носитель умер, вследствие этого, Вы умираете.
-        /// </summary>
-        internal static string your_carrier_player_has_died {
+        internal static string container {
             get {
-                return ResourceManager.GetString("your_carrier_player_has_died", resourceCulture);
+                return ResourceManager.GetString("container", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваше имя:.
-        /// </summary>
-        internal static string your_name {
+        internal static string role_string {
             get {
-                return ResourceManager.GetString("your_name", resourceCulture);
+                return ResourceManager.GetString("role_string", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваша роль.
-        /// </summary>
-        internal static string your_role {
+        internal static string no_stats_by_roles {
             get {
-                return ResourceManager.GetString("your_role", resourceCulture);
+                return ResourceManager.GetString("no_stats_by_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Команда мафии на эту игру:.
-        /// </summary>
-        internal static string your_teammates {
+        internal static string random_role_payment {
             get {
-                return ResourceManager.GetString("your_teammates", resourceCulture);
+                return ResourceManager.GetString("random_role_payment", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваш ход.
-        /// </summary>
-        internal static string your_turn {
+        internal static string random_role_description {
             get {
-                return ResourceManager.GetString("your_turn", resourceCulture);
+                return ResourceManager.GetString("random_role_description", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Ваш ход закончился.
-        /// </summary>
-        internal static string your_turn_ended {
+        internal static string you_already_open_all_roles {
             get {
-                return ResourceManager.GetString("your_turn_ended", resourceCulture);
+                return ResourceManager.GetString("you_already_open_all_roles", resourceCulture);
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Вы ходите под номером.
-        /// </summary>
-        internal static string your_turn_order {
+        internal static string work_in_progress {
             get {
-                return ResourceManager.GetString("your_turn_order", resourceCulture);
+                return ResourceManager.GetString("work_in_progress", resourceCulture);
             }
         }
     }

+ 44 - 2
MafiaTelegramBot/Resources/strings.resx

@@ -300,7 +300,7 @@
     <data name="everyone_survived" xml:space="preserve">
         <value>все игроки остались в живых!</value>
     </data>
-    <data name="you_have_ten_seconds" xml:space="preserve">
+    <data name="you_have_twenty_seconds" xml:space="preserve">
         <value>У вас есть 20 секунд, чтобы выставить игрока на голосование</value>
     </data>
     <data name="choose_player_to_kill" xml:space="preserve">
@@ -334,7 +334,7 @@
         <value>Жители хотели повесить игрока</value>
     </data>
     <data name="but_he_is_elder" xml:space="preserve">
-        <value>но он оказался старейшийной</value>
+        <value>но он оказался старейшиной</value>
     </data>
     <data name="activity_blocked" xml:space="preserve">
         <value>Действие заблокировано</value>
@@ -510,4 +510,46 @@
     <data name="player_parasit_with_dead_owner" xml:space="preserve">
         <value>Игрок паразит с мертвой целью, воскрешние прошло неудачно!</value>
     </data>
+    <data name="automatically_vote" xml:space="preserve">
+        <value>Автоматически был выбран игрок</value>
+    </data>
+    <data name="exit" xml:space="preserve">
+        <value>Выйти</value>
+    </data>
+    <data name="confirm_exit" xml:space="preserve">
+        <value>Вы действительно хотите выйти из игры? Напишите</value>
+    </data>
+    <data name="to_confirm_exit" xml:space="preserve">
+        <value>чтобы подтвердить выход. Или любое другое сообщение для отмены</value>
+    </data>
+    <data name="too_much_mafia" xml:space="preserve">
+        <value>Количество черных игроков больше, чем возможно при текущем количестве игроков</value>
+    </data>
+    <data name="not_enogh_mafia" xml:space="preserve">
+        <value>Количество черных ролей меньше, чем необходимо</value>
+    </data>
+    <data name="next" xml:space="preserve">
+        <value>Следующий</value>
+    </data>
+    <data name="container" xml:space="preserve">
+        <value>Носитель</value>
+    </data>
+    <data name="role_string" xml:space="preserve">
+        <value>{0}: {1}/{2} - {3}%</value>
+    </data>
+    <data name="no_stats_by_roles" xml:space="preserve">
+        <value>Вы не отыграли ни одной ролью</value>
+    </data>
+    <data name="random_role_payment" xml:space="preserve">
+        <value>Открытие рандомной роли</value>
+    </data>
+    <data name="random_role_description" xml:space="preserve">
+        <value>После покупки вы откроете случайную роль. Совершая покупку вы поддерживаете разработчика.</value>
+    </data>
+    <data name="you_already_open_all_roles" xml:space="preserve">
+        <value>Вы уже открыли все роли</value>
+    </data>
+    <data name="work_in_progress" xml:space="preserve">
+        <value>Скоро...</value>
+    </data>
 </root>

+ 2 - 0
MafiaTelegramBot/Utilities.cs

@@ -24,6 +24,8 @@ namespace MafiaTelegramBot
                 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),
+                ResultCode.NotEnoughMafia => Bot.SendWithMarkdown2(chatId, strings.not_enogh_mafia),
+                ResultCode.TooMuchMafia => Bot.SendWithMarkdown2(chatId, strings.too_much_mafia),
                 _ => Bot.SendWithMarkdown2(chatId, strings.unexpected_error)
             };
         }