Browse Source

MTB-28 creating private and public rooms, generating connect code for private rooms

Tigran 4 years ago
parent
commit
00b8833116

+ 20 - 6
MafiaTelegramBot/Controllers/RoomController.cs

@@ -1,3 +1,4 @@
+using System;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using MafiaTelegramBot.DataBase;
@@ -10,16 +11,16 @@ namespace MafiaTelegramBot.Controllers
     {
         private static readonly Dictionary<string, GameRoom> OpenedGames = new();
 
-        public static async Task<int> CreateNewGame(User owner, string roomName, string secretPhrase = null)
+        public static async Task<int> CreateNewGame(User owner, string roomName, bool extended, string secretPhrase = null)
         {
             var gameExists = await Task.Run(() => OpenedGames.ContainsKey(roomName));
             return await Task.Run(async () =>
             {
                 if (gameExists) return Constants.GAME_EXISTS;
-                if (! await owner.SetCurrentGame(secretPhrase ?? roomName)) return Constants.USER_ALREADY_IN_GAME;
+                if (!await owner.SetCurrentGame(roomName)) return Constants.USER_ALREADY_IN_GAME;
                 var room = secretPhrase == null
-                    ? new GameRoom {Creator = owner, RoomName = roomName}
-                    : new PrivateGameRoom {Creator = owner, RoomName = roomName};
+                    ? new GameRoom {Creator = owner, RoomName = roomName, IsExtended = extended}
+                    : new PrivateGameRoom {Creator = owner, RoomName = roomName, IsExtended = extended};
                 OpenedGames.Add(secretPhrase ?? roomName, room);
                 room.Players.Add(owner.Username, owner);
                 return Constants.CODE_OK;
@@ -44,8 +45,21 @@ namespace MafiaTelegramBot.Controllers
                 var current = player.GetCurrentGame();
                 if (current == "") return Constants.USER_NOT_IN_GAME;
                 await player.RemoveGame();
-                OpenedGames[current].Players.Remove(player.Username);
-                if (OpenedGames[current].Players.Count == 0) OpenedGames.Remove(current);
+                try
+                {
+                    OpenedGames[current].Players.Remove(player.Username);
+                    if (OpenedGames[current].Players.Count == 0) OpenedGames.Remove(current);
+                }
+                catch (Exception)
+                {
+                    var pass = RoomEncrypter.NameToCode(current);
+                    OpenedGames[pass].Players.Remove(player.Username);
+                    if (OpenedGames[pass].Players.Count == 0)
+                    {
+                        OpenedGames.Remove(pass);
+                        RoomEncrypter.Remove(current);
+                    }
+                }
                 return Constants.CODE_OK;
             });
         }

+ 1 - 0
MafiaTelegramBot/Game/GameRoom.cs

@@ -10,6 +10,7 @@ namespace MafiaTelegramBot.Game
         private int _maxPlayers = Constants.PLAYER_LIMITS_MAX;
         private int _minPlayers = Constants.PLAYER_LIMITS_MIN;
         public virtual bool IsPrivate { get; protected set; } = false;
+        public bool IsExtended { get; init; } = false;
         public string RoomName { get; init; } = "NoNameRoom";
         public User Creator { get; init; } = new();
         public readonly Dictionary<string, User> Players = new();

+ 47 - 0
MafiaTelegramBot/Game/RoomEncrypter.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MafiaTelegramBot.Game
+{
+    public static class RoomEncrypter
+    {
+        private static readonly Dictionary<string, string> ToPassword = new();
+        private static readonly Dictionary<string, string> ToName = new();
+
+        public static string Encrypt(string roomName)
+        {
+            var pass = RandomString();
+            while (ToName.ContainsKey(pass)) pass = RandomString();
+            ToPassword.Add(roomName, pass);
+            ToName.Add(pass,roomName);
+            return pass;
+        }
+
+        public static string CodeToName(string pass)
+        {
+            return ToName.GetValueOrDefault(pass);
+        }
+
+        public static string NameToCode(string name)
+        {
+            return ToPassword.GetValueOrDefault(name);
+        }
+        
+        private static readonly Random Random = new Random();
+
+        private static string RandomString(int length = 6)
+        {
+            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+            return new string(Enumerable.Repeat(chars, length)
+                .Select(s => s[Random.Next(s.Length)]).ToArray());
+        }
+
+        public static void Remove(string name)
+        {
+            var pass = NameToCode(name);
+            ToName.Remove(pass);
+            ToPassword.Remove(name);
+        }
+    }
+}

+ 4 - 1
MafiaTelegramBot/Models/Bot.cs

@@ -23,7 +23,7 @@ namespace MafiaTelegramBot.Models
         public static IReadOnlyList<Reply> Replies => _repliesList.AsReadOnly();
 
         public static readonly List<long> UsersThatChangesNickname = new();
-        public static readonly List<long> UsersThatCreatesPublicRoom = new();
+        public static readonly Dictionary<long, string[]> UsersThatCreatesRoom = new();
 
         public static TelegramBotClient Get()
         {
@@ -64,6 +64,9 @@ namespace MafiaTelegramBot.Models
                 new ShopQuery(),
                 new MakePrivateRoomQuery(),
                 new MakePublicRoomQuery(),
+                new MakeStandartGameQuery(),
+                new MakeExtendedGameQuery(),
+                new MakePublicRoomQuery(),
                 new SettingsQuery(),
                 new ChangeNameQuery(),
                 new LeaveQuery(),

+ 7 - 7
MafiaTelegramBot/Models/Commands/CreateGameCommand.cs

@@ -1,4 +1,5 @@
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
 using Telegram.Bot.Types.ReplyMarkups;
@@ -13,16 +14,15 @@ namespace MafiaTelegramBot.Models.Commands
             var chatId = update.Message.Chat.Id;
             var userId = update.Message.From.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-
-            var message = strings.settings_room;
-            
+            var user = await UserDao.GetUserById(userId);
+            if (user?.GetCurrentGame() != "")
+                return await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_");
             var inlineKeyboard = new InlineKeyboardMarkup(new[]
             {
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_public_room, $"{strings.make_public_room_callback}|{userId}")},
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_private_room, $"{strings.make_private_room_callback}|{userId}")}
+                new[] {InlineKeyboardButton.WithCallbackData(strings.make_public_room, $"{strings.make_public_room_callback}|{userId}|private")},
+                new[] {InlineKeyboardButton.WithCallbackData(strings.make_private_room, $"{strings.make_private_room_callback}|{userId}|private")}
             });
-            
-            return await Bot.SendWithMarkdown2(chatId, message, inlineKeyboard);
+            return await Bot.SendWithMarkdown2(chatId, strings.settings_room, inlineKeyboard);
         }
     }
 }

+ 22 - 7
MafiaTelegramBot/Models/Commands/CustomMessageHandlingCommand.cs

@@ -1,6 +1,7 @@
 using System.Threading.Tasks;
 using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.DataBase;
+using MafiaTelegramBot.Game;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
@@ -18,8 +19,14 @@ namespace MafiaTelegramBot.Models.Commands
             var message = update.Message.Text;
             var userId = update.Message.From.Id;
             
-            if (Bot.UsersThatChangesNickname.Remove(userId)) return await ChangeNicknameLogic(userId, chatId, message);
-            if (Bot.UsersThatCreatesPublicRoom.Remove(userId)) return await CreatePublicRoomLogic(userId, chatId, message);
+            if (Bot.UsersThatChangesNickname.Remove(userId))
+                return await ChangeNicknameLogic(userId, chatId, message);
+            if (Bot.UsersThatCreatesRoom.ContainsKey(userId))
+            {
+                var param = Bot.UsersThatCreatesRoom[userId];
+                Bot.UsersThatCreatesRoom.Remove(userId);
+                return await CreateRoomLogic(userId, chatId, message, param);
+            }
             
             return await Bot.SendWithMarkdown2(chatId, $"{strings.command_not_found} _*\\({message}\\)*_");
         }
@@ -31,10 +38,12 @@ namespace MafiaTelegramBot.Models.Commands
             return await Bot.SendWithMarkdown2(chatId, $"{strings.name_updated} _*{message}*_");
         }
 
-        private static async Task<Message> CreatePublicRoomLogic(long userId, long chatId, string message)
+        private static async Task<Message> CreateRoomLogic(long userId, long chatId, string roomName, string[] param)
         {
             var user = await UserDao.GetUserById(userId);
-            var resultCode = await RoomController.CreateNewGame(user, message);
+            var resultCode = param[0] == "public"
+                ? await RoomController.CreateNewGame(user, roomName, param[1] == strings.extended_callback)
+                : await RoomController.CreateNewGame(user, roomName, param[1] == strings.extended_callback, RoomEncrypter.Encrypt(roomName));
             var keyboard = new InlineKeyboardMarkup(new []
             {
                 new []{
@@ -42,13 +51,19 @@ namespace MafiaTelegramBot.Models.Commands
                     InlineKeyboardButton.WithCallbackData(strings.leave, $"{strings.leave_callback}|{userId}")
                 }
             });
-            return resultCode switch
+            var result = resultCode switch
             {
-                Constants.CODE_OK => await Bot.SendWithMarkdown2(chatId, $"{strings.room_with_name} _*{message}*_ {strings.was_created}", keyboard),
+                Constants.CODE_OK => await Bot.SendWithMarkdown2(chatId, $"{strings.room_with_name} _*{roomName}*_ {strings.was_created}", keyboard),
                 Constants.USER_ALREADY_IN_GAME => await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_"),
-                Constants.GAME_EXISTS => await Bot.SendWithMarkdown2(chatId, $"{strings.room} _*{message}*_ {strings.already_exists}"),
+                Constants.GAME_EXISTS => await Bot.SendWithMarkdown2(chatId, $"{strings.room} _*{roomName}*_ {strings.already_exists}"),
                 _ => await Bot.SendWithMarkdown2(chatId, strings.unexpected_error)
             };
+            if (resultCode == Constants.CODE_OK && param[0] == "private")
+            {
+                await Bot.SendWithMarkdown2(chatId,
+                    $"{strings.secret_key_is} _*{roomName}*_: ```{RoomEncrypter.NameToCode(roomName)}```");
+            }
+            return result;
         }
     }
 }

+ 4 - 2
MafiaTelegramBot/Models/Commands/ShowProfileCommand.cs

@@ -25,8 +25,10 @@ namespace MafiaTelegramBot.Models.Commands
                 $"{strings.winrate} {winRate}%\n";
             var inlineKeyboard = new InlineKeyboardMarkup(new[]
             {
-                new[] {InlineKeyboardButton.WithCallbackData(strings.shop, $"{strings.shop_callback}|{userId}")},
-                new[] {InlineKeyboardButton.WithCallbackData(strings.my_roles, $"{strings.my_roles_callback}|{userId}")},
+                new[] {
+                    InlineKeyboardButton.WithCallbackData(strings.shop, $"{strings.shop_callback}|{userId}"),
+                    InlineKeyboardButton.WithCallbackData(strings.my_roles, $"{strings.my_roles_callback}|{userId}")
+                },
                 new[] {InlineKeyboardButton.WithCallbackData(strings.settings, $"{strings.settings_callback}|{userId}")}
             });
             return await Bot.SendWithMarkdown2(chatId, message, inlineKeyboard);

+ 28 - 0
MafiaTelegramBot/Models/Inlines/MakeExtendedGameQuery.cs

@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace MafiaTelegramBot.Models.Inlines
+{
+    public class MakeExtendedGameQuery : Query
+    {
+        protected override string Name => strings.extended_callback;
+        public override async Task<Message> Execute(Update update)
+        {
+            var chatId = update.CallbackQuery.Message.Chat.Id;
+            await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
+            var data = update.CallbackQuery.Data;
+            var param = data.Split('|');
+            var userId = long.Parse(param[1]);
+            var user = await UserDao.GetUserById(userId);
+            if (user?.GetCurrentGame() != "")
+                return await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_");
+            if (Bot.UsersThatCreatesRoom.TryAdd(userId, new[] {param[2], Name}))
+            {
+                Bot.UsersThatCreatesRoom[userId] = new[] {param[2], Name};
+            }
+            return await Bot.SendWithMarkdown2(chatId, strings.enter_room_name);
+        }
+    }
+}

+ 9 - 7
MafiaTelegramBot/Models/Inlines/MakePrivateRoomQuery.cs

@@ -1,4 +1,5 @@
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
 using Telegram.Bot.Types.ReplyMarkups;
@@ -14,16 +15,17 @@ namespace MafiaTelegramBot.Models.Inlines
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
             var data = update.CallbackQuery.Data;
             var userId = long.Parse(data.Split('|')[1]);
-
-            var message = strings.choose;
-            
+            var user = await UserDao.GetUserById(userId);
+            if (user?.GetCurrentGame() != "")
+                return await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_");
             var inlineKeyboard = new InlineKeyboardMarkup(new[]
             {
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_public_room, $"{strings.make_public_room_callback}|{userId}")},
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_private_room, $"{strings.make_private_room_callback}|{userId}")}
+                new[] {
+                    InlineKeyboardButton.WithCallbackData(strings.standart, $"{strings.standart_callback}|{userId}|private"),
+                    InlineKeyboardButton.WithCallbackData(strings.extended, $"{strings.extended_callback}|{userId}|private")
+                }
             });
-            
-            return await Bot.SendWithMarkdown2(chatId, message, inlineKeyboard);
+            return await Bot.SendWithMarkdown2(chatId, strings.choose_game_type, inlineKeyboard);
         }
     }
 }

+ 13 - 3
MafiaTelegramBot/Models/Inlines/MakePublicRoomQuery.cs

@@ -1,6 +1,8 @@
 using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
+using Telegram.Bot.Types.ReplyMarkups;
 
 namespace MafiaTelegramBot.Models.Inlines
 {
@@ -11,11 +13,19 @@ namespace MafiaTelegramBot.Models.Inlines
         { 
             var chatId = update.CallbackQuery.Message.Chat.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-            var message = await Bot.SendWithMarkdown2(chatId, strings.enter_room_name);
             var data = update.CallbackQuery.Data;
             var userId = long.Parse(data.Split('|')[1]);
-            Bot.UsersThatCreatesPublicRoom.Add(userId);
-            return message;
+            var user = await UserDao.GetUserById(userId);
+            if (user?.GetCurrentGame() != "")
+                return await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_");
+            var inlineKeyboard = new InlineKeyboardMarkup(new[]
+            {
+                new[] {
+                    InlineKeyboardButton.WithCallbackData(strings.standart, $"{strings.standart_callback}|{userId}|public"),
+                    InlineKeyboardButton.WithCallbackData(strings.extended, $"{strings.extended_callback}|{userId}|public")
+                }
+            });
+            return await Bot.SendWithMarkdown2(chatId, strings.choose_game_type, inlineKeyboard);
         }
     }
 }

+ 28 - 0
MafiaTelegramBot/Models/Inlines/MakeStandartGameQuery.cs

@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace MafiaTelegramBot.Models.Inlines
+{
+    public class MakeStandartGameQuery : Query
+    {
+        protected override string Name => strings.standart_callback;
+        public override async Task<Message> Execute(Update update)
+        {
+            var chatId = update.CallbackQuery.Message.Chat.Id;
+            await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
+            var data = update.CallbackQuery.Data;
+            var param = data.Split('|');
+            var userId = long.Parse(param[1]);
+            var user = await UserDao.GetUserById(userId);
+            if (user?.GetCurrentGame() != "")
+                return await Bot.SendWithMarkdown2(chatId, $"{strings.user_already_playing} _*{user?.GetCurrentGame()}*_");
+            if (Bot.UsersThatCreatesRoom.TryAdd(userId, new[] {param[2], Name}))
+            {
+                Bot.UsersThatCreatesRoom[userId] = new[] {param[2], Name};
+            }
+            return await Bot.SendWithMarkdown2(chatId, strings.enter_room_name);
+        }
+    }
+}

+ 3 - 0
MafiaTelegramBot/Models/Inlines/Query.cs

@@ -13,6 +13,9 @@ namespace MafiaTelegramBot.Models.Inlines
         {
             var data = update.CallbackQuery.Data;
             var command = data.Split('|')[0];
+            var messageId = update.CallbackQuery.Message.MessageId;
+            var chatId = update.CallbackQuery.Message.Chat.Id;
+            Bot.Get().DeleteMessageAsync(chatId, messageId);
             var queries = Bot.Queries;
             return FirstOrDefault(queries, command).Execute(update);
         }

+ 48 - 3
MafiaTelegramBot/Resources/strings.Designer.cs

@@ -88,11 +88,11 @@ namespace MafiaTelegramBot {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Выберите.
+        ///   Looks up a localized string similar to Выберите режим игры.
         /// </summary>
-        internal static string choose {
+        internal static string choose_game_type {
             get {
-                return ResourceManager.GetString("choose", resourceCulture);
+                return ResourceManager.GetString("choose_game_type", resourceCulture);
             }
         }
         
@@ -141,6 +141,24 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Расширенный.
+        /// </summary>
+        internal static string extended {
+            get {
+                return ResourceManager.GetString("extended", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to extended.
+        /// </summary>
+        internal static string extended_callback {
+            get {
+                return ResourceManager.GetString("extended_callback", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Число игр:.
         /// </summary>
@@ -276,6 +294,15 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Секретный код для подключения к комнате.
+        /// </summary>
+        internal static string secret_key_is {
+            get {
+                return ResourceManager.GetString("secret_key_is", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Настройки.
         /// </summary>
@@ -339,6 +366,24 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Стандартный.
+        /// </summary>
+        internal static string standart {
+            get {
+                return ResourceManager.GetString("standart", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to standart.
+        /// </summary>
+        internal static string standart_callback {
+            get {
+                return ResourceManager.GetString("standart_callback", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Что вы хотите сделать?.
         /// </summary>

+ 17 - 2
MafiaTelegramBot/Resources/strings.resx

@@ -93,8 +93,8 @@
     <data name="settings_room" xml:space="preserve">
         <value>Задайте настройки комнаты</value>
     </data>
-    <data name="choose" xml:space="preserve">
-        <value>Выберите</value>
+    <data name="choose_game_type" xml:space="preserve">
+        <value>Выберите режим игры</value>
     </data>
     <data name="no_name" xml:space="preserve">
         <value>No name</value>
@@ -135,4 +135,19 @@
     <data name="not_in_game" xml:space="preserve">
         <value>Вы не находитесь сейчас в игре!</value>
     </data>
+    <data name="standart" xml:space="preserve">
+        <value>Стандартный</value>
+    </data>
+    <data name="extended" xml:space="preserve">
+        <value>Расширенный</value>
+    </data>
+    <data name="standart_callback" xml:space="preserve">
+        <value>standart</value>
+    </data>
+    <data name="extended_callback" xml:space="preserve">
+        <value>extended</value>
+    </data>
+    <data name="secret_key_is" xml:space="preserve">
+        <value>Секретный код для подключения к комнате</value>
+    </data>
 </root>