Browse Source

MTB-28 room controller, game room realization, creating public rooms

Tigran 4 years ago
parent
commit
dcad89aa3e

+ 26 - 0
MafiaTelegramBot/Controllers/RoomController.cs

@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using MafiaTelegramBot.DataBase;
+using MafiaTelegramBot.Game;
+using MafiaTelegramBot.Resources;
+
+namespace MafiaTelegramBot.Controllers
+{
+    public static class RoomController
+    {
+        private static readonly Dictionary<string, GameRoom> OpenedGames = new();
+        
+        public static async Task<int> CreateNewGame(User owner, string roomName, string password = null)
+        {
+            var gameExists = await Task.Run(() => OpenedGames.ContainsKey(roomName));
+            if (gameExists) return Constants.GAME_EXISTS;
+            if (!owner.SetCurrentGame(roomName)) return Constants.USER_ALREADY_IN_GAME;
+            var room = new GameRoom {Creator = owner, RoomName = roomName, Password = password};
+            room.Players.Add(owner.Username, owner);
+            OpenedGames.Add(roomName, room);
+            return Constants.CODE_OK;
+        }
+        
+        
+    }
+}

+ 18 - 2
MafiaTelegramBot/DataBase/User.cs

@@ -1,3 +1,4 @@
+#nullable enable
 using System.Collections.Generic;
 using System.Threading.Tasks;
 
@@ -5,17 +6,32 @@ namespace MafiaTelegramBot.DataBase
 {
     public class User
     {
-        public long Id { get; set; } = 0;
-        public string Username { get; set; } = "test";
+        public long Id { get; init; }
+        public long ChatId { get; init; }
+        public string Username { get; set; } = strings.no_name;
         public int Games { get; set; } = 0;
         public int Wins { get; set; } = 0;
         public Dictionary<string, int> RoleGames = new();
         public Dictionary<string, int> RoleWins = new();
 
+        private string? _currentGame;
+
         public async Task UpdateName(string name)
         {
             Username = name;
             await UserDao.Update(this);
         }
+
+        public string? GetCurrentGame()
+        {
+            return _currentGame;
+        }
+
+        public bool SetCurrentGame(string roomName)
+        {
+            if (_currentGame != null) return false;
+            _currentGame = roomName;
+            return true;
+        }
     }
 }

+ 14 - 6
MafiaTelegramBot/DataBase/UserDao.cs

@@ -1,3 +1,4 @@
+#nullable enable
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
@@ -7,13 +8,10 @@ namespace MafiaTelegramBot.DataBase
     public static class UserDao
     {
         private static readonly List<User> DataBase = new();
-        public static async Task<User> GetUserById(long id)
+        public static async Task<User?> GetUserById(long id)
         {
-            User user = null;
+            User? user = null;
             await Task.Run(()=> user = DataBase.FirstOrDefault(user1 => user1.Id == id));
-            if (user != null) return user;
-            user = new User {Id = id};
-            DataBase.Add(user);
             return user;
         }
 
@@ -26,7 +24,17 @@ namespace MafiaTelegramBot.DataBase
         {
             var updateIndex = 0;
             await Task.Run(() => updateIndex = DataBase.FindIndex(user1 => user1.Id == user.Id));
-            DataBase[updateIndex] = user;
+            if (updateIndex != -1) DataBase[updateIndex] = user;
+            else DataBase.Add(user);
+        }
+        //Temporary method
+        public static async Task AddNewUser(long userId, long chatId, string username)
+        {
+            var user = await GetUserById(userId);
+            if (user == null) {
+                user = new User {Id = userId, Username = username, ChatId = chatId};
+                await Update(user);
+            }
         }
     }
 }

+ 33 - 0
MafiaTelegramBot/Game/GameRoom.cs

@@ -0,0 +1,33 @@
+#nullable enable
+using System.Collections.Generic;
+using MafiaTelegramBot.DataBase;
+using MafiaTelegramBot.Resources;
+
+namespace MafiaTelegramBot.Game
+{
+    public class GameRoom
+    {
+        public string? Password { get; init; }
+        private bool _isRunned;
+        public string? RoomName { get; init; }
+        public User Creator { get; init; } = new();
+        public readonly Dictionary<string, User> Players = new();
+        public readonly Dictionary<string, string> Settings = new();
+
+        public int Start()
+        {
+            switch (Players.Count)
+            {
+                case < Constants.PLAYER_LIMITS_MIN: return Constants.TOO_FEW_PLAYERS;
+                case > Constants.PLAYER_LIMITS_MAX: return Constants.TOO_MANY_PLAYERS;
+                default:
+                {
+                    if (_isRunned) return Constants.GAME_ALREADY_RUNNING;
+                    _isRunned = true;
+                    //TODO game start logic
+                    return Constants.CODE_OK;
+                }
+            }
+        }
+    }
+}

+ 13 - 0
MafiaTelegramBot/Models/Bot.cs

@@ -1,9 +1,13 @@
 using System.Collections.Generic;
+using System.Threading.Tasks;
 using MafiaTelegramBot.Models.Commands;
 using MafiaTelegramBot.Models.Inlines;
 using MafiaTelegramBot.Models.Replies;
 using MafiaTelegramBot.Resources;
 using Telegram.Bot;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+using Telegram.Bot.Types.ReplyMarkups;
 
 namespace MafiaTelegramBot.Models
 {
@@ -19,6 +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 TelegramBotClient Get()
         {
@@ -58,6 +63,7 @@ namespace MafiaTelegramBot.Models
                 new MyRolesQuery(),
                 new ShopQuery(),
                 new MakePrivateRoom(),
+                new MakePublicRoomQuery(),
                 new SettingsQuery(),
                 new ChangeNameQuery(),
             };
@@ -71,5 +77,12 @@ namespace MafiaTelegramBot.Models
                 
             };
         }
+        
+        public static Task<Message> SendWithMarkdown2(long chatId, string message, IReplyMarkup replyMarkup = null)
+        {
+            return replyMarkup == null
+                ? Get().SendTextMessageAsync(chatId, message, ParseMode.MarkdownV2)
+                : Get().SendTextMessageAsync(chatId, message, ParseMode.MarkdownV2, replyMarkup: replyMarkup);
+        }
     }
 }

+ 1 - 1
MafiaTelegramBot/Models/Commands/ConnectGameCommand.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Models.Commands
         {
             var chatId = update.Message.Chat.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-            return await Bot.Get().SendTextMessageAsync(chatId, Name);
+            return await Bot.SendWithMarkdown2(chatId, Name);
         }
     }
 }

+ 4 - 3
MafiaTelegramBot/Models/Commands/CreateGameCommand.cs

@@ -11,17 +11,18 @@ namespace MafiaTelegramBot.Models.Commands
         public override async Task<Message> Execute(Update update)
         {
             var chatId = update.Message.Chat.Id;
+            var userId = update.Message.From.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
 
             var message = strings.set_room_settings;
             
             var inlineKeyboard = new InlineKeyboardMarkup(new[]
             {
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_public_room, strings.make_public_room_callback)},
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_private_room, strings.make_private_room_callback)}
+                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}")}
             });
             
-            return await Bot.Get().SendTextMessageAsync(chatId, message, replyMarkup: inlineKeyboard);
+            return await Bot.SendWithMarkdown2(chatId, message, replyMarkup: inlineKeyboard);
         }
     }
 }

+ 25 - 6
MafiaTelegramBot/Models/Commands/CustomMessageHandlingCommand.cs

@@ -1,5 +1,7 @@
 using System.Threading.Tasks;
+using MafiaTelegramBot.Controllers;
 using MafiaTelegramBot.DataBase;
+using MafiaTelegramBot.Resources;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
 
@@ -14,13 +16,30 @@ namespace MafiaTelegramBot.Models.Commands
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
             var message = update.Message.Text;
             var userId = update.Message.From.Id;
-            if (Bot.UsersThatChangesNickname.Remove(userId))
+            
+            if (Bot.UsersThatChangesNickname.Remove(userId)) return await ChangeNicknameLogic(userId, chatId, message);
+            if (Bot.UsersThatCreatesPublicRoom.Remove(userId)) return await CreatePublicRoomLogic(userId, chatId, message);
+            
+            return await Bot.SendWithMarkdown2(chatId, $"{strings.command_not_found} _*\\({message}\\)*_");
+        }
+
+        private static async Task<Message> ChangeNicknameLogic(long userId, long chatId, string message)
+        {
+            var user = await UserDao.GetUserById(userId);
+            await user.UpdateName(message);
+            return await Bot.SendWithMarkdown2(chatId, $"{strings.name_updated} _*{message}*_");
+        }
+
+        private static async Task<Message> CreatePublicRoomLogic(long userId, long chatId, string message)
+        {
+            var user = await UserDao.GetUserById(userId);
+            var resultCode = await RoomController.CreateNewGame(user, message);
+            return resultCode switch
             {
-                var user = await UserDao.GetUserById(userId);
-                await user.UpdateName(message);
-                return await Bot.Get().SendTextMessageAsync(chatId, $"{strings.name_updated} {message}");
-            }
-            return await Bot.Get().SendTextMessageAsync(chatId, $"{strings.command_not_found} _*\\({message}\\)*_", ParseMode.MarkdownV2);
+                Constants.CODE_OK => await Bot.SendWithMarkdown2(chatId, $"{strings.room_with_name} _*{message}*_ {strings.was_created}"),
+                Constants.GAME_EXISTS => await Bot.SendWithMarkdown2(chatId, $"{strings.room} _*{message}*_ {strings.already_exists}"),
+                _ => await Bot.SendWithMarkdown2(chatId, strings.unexpected_error)
+            };
         }
     }
 }

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

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

+ 6 - 1
MafiaTelegramBot/Models/Commands/StartCommand.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;
@@ -22,7 +23,11 @@ namespace MafiaTelegramBot.Models.Commands
                 },
                 true
             );
-            return await Bot.Get().SendTextMessageAsync(chatId, strings.start_message, replyMarkup: keyboard);
+            var message = await Bot.SendWithMarkdown2(chatId, strings.start_message, keyboard);
+            var userId = update.Message.From.Id;
+            var username = update.Message.From.Username;
+            await UserDao.AddNewUser(userId, chatId, username);
+            return message;
         }
     }
 }

+ 1 - 1
MafiaTelegramBot/Models/Inlines/ChaneNameQuery.cs

@@ -15,7 +15,7 @@ namespace MafiaTelegramBot.Models.Inlines
             var userId = long.Parse(data.Split('|')[1]);
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
             Bot.UsersThatChangesNickname.Add(userId);
-            return await Bot.Get().SendTextMessageAsync(chatId, strings.enter_your_name);
+            return await Bot.SendWithMarkdown2(chatId, strings.enter_your_name);
         }
     }
 }

+ 5 - 3
MafiaTelegramBot/Models/Inlines/MakePrivateRoom.cs

@@ -12,16 +12,18 @@ namespace MafiaTelegramBot.Models.Inlines
         {
             var chatId = update.CallbackQuery.Message.Chat.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
+            var data = update.CallbackQuery.Data;
+            var userId = long.Parse(data.Split('|')[1]);
 
             var message = strings.choose;
             
             var inlineKeyboard = new InlineKeyboardMarkup(new[]
             {
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_public_room, strings.make_public_room_callback)},
-                new[] {InlineKeyboardButton.WithCallbackData(strings.make_private_room, strings.make_private_room_callback)}
+                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}")}
             });
             
-            return await Bot.Get().SendTextMessageAsync(chatId, message, replyMarkup: inlineKeyboard);
+            return await Bot.SendWithMarkdown2(chatId, message, inlineKeyboard);
         }
     }
 }

+ 21 - 0
MafiaTelegramBot/Models/Inlines/MakePublicRoomQuery.cs

@@ -0,0 +1,21 @@
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace MafiaTelegramBot.Models.Inlines
+{
+    public class MakePublicRoomQuery : Query
+    {
+        protected override string Name => strings.make_public_room_callback;
+        public override async Task<Message> Execute(Update update)
+        { 
+            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;
+        }
+    }
+}

+ 1 - 1
MafiaTelegramBot/Models/Inlines/MyRolesQuery.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Models.Inlines
         {
             var chatId = update.CallbackQuery.Message.Chat.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-            return await Bot.Get().SendTextMessageAsync(chatId, Name);
+            return await Bot.SendWithMarkdown2(chatId, Name);
         }
     }
 }

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

@@ -7,9 +7,10 @@ namespace MafiaTelegramBot.Models.Inlines
     {
         public static Task Update(Update update)
         {
-            var queries = Bot.Queries;
             var data = update.CallbackQuery.Data;
-            return FirstOrDefault(queries, data).Execute(update);
+            var command = data.Split('|')[0];
+            var queries = Bot.Queries;
+            return FirstOrDefault(queries, command).Execute(update);
         }
     }
 }

+ 1 - 1
MafiaTelegramBot/Models/Inlines/SettingsQuery.cs

@@ -17,7 +17,7 @@ namespace MafiaTelegramBot.Models.Inlines
             var userId = update.CallbackQuery.From.Id;
             var user = await UserDao.GetUserById(userId);
             var inlineKeyboard = new InlineKeyboardMarkup(InlineKeyboardButton.WithCallbackData(strings.change_name, $"{strings.change_name_callback}|{userId}"));
-            return await Bot.Get().SendTextMessageAsync(chatId, $"{strings.your_name} {user.Username}", replyMarkup: inlineKeyboard);
+            return await Bot.SendWithMarkdown2(chatId, $"{strings.your_name} {user.Username}", inlineKeyboard);
         }
     }
 }

+ 1 - 1
MafiaTelegramBot/Models/Inlines/ShopQuery.cs

@@ -12,7 +12,7 @@ namespace MafiaTelegramBot.Models.Inlines
         {
             var chatId = update.CallbackQuery.Message.Chat.Id;
             await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
-            return await Bot.Get().SendTextMessageAsync(chatId, Name);
+            return await Bot.SendWithMarkdown2(chatId, Name);
         }
     }
 }

+ 1 - 1
MafiaTelegramBot/Models/UpdateModel.cs

@@ -11,7 +11,7 @@ namespace MafiaTelegramBot.Models
         
         public abstract Task<Message> Execute(Update update);
 
-        protected bool Contains(string command)
+        private bool Contains(string command)
         {
             return command.Contains(Name);
         }

+ 17 - 0
MafiaTelegramBot/Resources/Constants.cs

@@ -0,0 +1,17 @@
+namespace MafiaTelegramBot.Resources
+{
+    public static class Constants
+    {
+        public const int PLAYER_LIMITS_MIN = 1;
+        public const int PLAYER_LIMITS_MAX = 16;
+
+        public const int CODE_OK = 0;
+        
+        public const int TOO_MANY_PLAYERS = 1;
+        public const int TOO_FEW_PLAYERS = -1;
+        public const int GAME_ALREADY_RUNNING = 2;
+
+        public const int GAME_EXISTS = 1;
+        public const int USER_ALREADY_IN_GAME = 2;
+    }
+}

+ 63 - 0
MafiaTelegramBot/Resources/strings.Designer.cs

@@ -60,6 +60,15 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to уже существует.
+        /// </summary>
+        internal static string already_exists {
+            get {
+                return ResourceManager.GetString("already_exists", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Сменить имя.
         /// </summary>
@@ -114,6 +123,15 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Введите название комнаты.
+        /// </summary>
+        internal static string enter_room_name {
+            get {
+                return ResourceManager.GetString("enter_room_name", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Введите ваше имя.
         /// </summary>
@@ -195,6 +213,33 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to No name.
+        /// </summary>
+        internal static string no_name {
+            get {
+                return ResourceManager.GetString("no_name", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Комната.
+        /// </summary>
+        internal static string room {
+            get {
+                return ResourceManager.GetString("room", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Комната с именем.
+        /// </summary>
+        internal static string room_with_name {
+            get {
+                return ResourceManager.GetString("room_with_name", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Задайте настройки комнаты.
         /// </summary>
@@ -267,6 +312,24 @@ namespace MafiaTelegramBot {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Произошла неожиданная ошибка... Попробуйте ещё раз..
+        /// </summary>
+        internal static string unexpected_error {
+            get {
+                return ResourceManager.GetString("unexpected_error", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to была создана.
+        /// </summary>
+        internal static string was_created {
+            get {
+                return ResourceManager.GetString("was_created", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Винрейт:.
         /// </summary>

+ 21 - 0
MafiaTelegramBot/Resources/strings.resx

@@ -96,4 +96,25 @@
     <data name="choose" xml:space="preserve">
         <value>Выберите</value>
     </data>
+    <data name="no_name" xml:space="preserve">
+        <value>No name</value>
+    </data>
+    <data name="enter_room_name" xml:space="preserve">
+        <value>Введите название комнаты</value>
+    </data>
+    <data name="room_with_name" xml:space="preserve">
+        <value>Комната с именем</value>
+    </data>
+    <data name="was_created" xml:space="preserve">
+        <value>была создана</value>
+    </data>
+    <data name="unexpected_error" xml:space="preserve">
+        <value>Произошла неожиданная ошибка... Попробуйте ещё раз.</value>
+    </data>
+    <data name="room" xml:space="preserve">
+        <value>Комната</value>
+    </data>
+    <data name="already_exists" xml:space="preserve">
+        <value>уже существует</value>
+    </data>
 </root>