From 6d99b0bbeecb77f1a336aa0ca12b6b5196fdb2c8 Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 19 Jan 2021 21:01:38 +0300 Subject: [PATCH] Working start and game stop on mafia leave --- MafiaCommon/ArrayUtils.cs | 27 ++++ MafiaCommon/ChatType.cs | 8 + MafiaCommon/GameState.cs | 10 ++ MafiaCommon/Packets/ChatType.cs | 7 - MafiaCommon/Packets/DisconnectPlayerPacket.cs | 10 ++ MafiaCommon/Packets/EndGamePacket.cs | 16 ++ MafiaCommon/Packets/GameStartPacket.cs | 12 ++ MafiaCommon/Packets/PacketConverter.cs | 6 + MafiaCommon/Packets/PacketType.cs | 3 + MafiaCommon/PlayerRole.cs | 14 ++ MafiaCommon/Role.cs | 21 +++ MafiaGame/MainWindow.xaml | 97 +++++++++++- MafiaGame/MainWindow.xaml.cs | 89 ++++++++++- MafiaGame/ServerConnection.cs | 97 +++++++++--- MafiaServer/Events/OnDisconnectEvent.cs | 4 + .../Events/OnPlayerSendMessageEvent.cs | 2 +- MafiaServer/Game.cs | 142 ++++++++++++++++++ MafiaServer/PlayerSocketWorker.cs | 7 + 18 files changed, 544 insertions(+), 28 deletions(-) create mode 100644 MafiaCommon/ArrayUtils.cs create mode 100644 MafiaCommon/ChatType.cs create mode 100644 MafiaCommon/GameState.cs delete mode 100644 MafiaCommon/Packets/ChatType.cs create mode 100644 MafiaCommon/Packets/DisconnectPlayerPacket.cs create mode 100644 MafiaCommon/Packets/EndGamePacket.cs create mode 100644 MafiaCommon/Packets/GameStartPacket.cs create mode 100644 MafiaCommon/PlayerRole.cs create mode 100644 MafiaCommon/Role.cs create mode 100644 MafiaServer/Events/OnDisconnectEvent.cs diff --git a/MafiaCommon/ArrayUtils.cs b/MafiaCommon/ArrayUtils.cs new file mode 100644 index 0000000..672e9bc --- /dev/null +++ b/MafiaCommon/ArrayUtils.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace MafiaCommon +{ + public static class ListUtils + { + public static void Shuffle (this Random rng, T[] array) + { + int n = array.Length; + while (n > 1) + { + int k = rng.Next(n--); + T temp = array[n]; + array[n] = array[k]; + array[k] = temp; + } + } + + public static T[] RemoveFromArray (this T[] original, int numIdx) { + if (numIdx == -1) return original; + List tmp = new List(original); + tmp.RemoveAt(numIdx); + return tmp.ToArray(); + } + } +} \ No newline at end of file diff --git a/MafiaCommon/ChatType.cs b/MafiaCommon/ChatType.cs new file mode 100644 index 0000000..4485072 --- /dev/null +++ b/MafiaCommon/ChatType.cs @@ -0,0 +1,8 @@ +namespace MafiaCommon +{ + public enum ChatType + { + Queue=1, + Active=2, + } +} \ No newline at end of file diff --git a/MafiaCommon/GameState.cs b/MafiaCommon/GameState.cs new file mode 100644 index 0000000..0f98771 --- /dev/null +++ b/MafiaCommon/GameState.cs @@ -0,0 +1,10 @@ +namespace MafiaCommon +{ + public enum GameState + { + NotStarted=1, + VotingNight=2, + Day=3, + VotingDay=4 + } +} \ No newline at end of file diff --git a/MafiaCommon/Packets/ChatType.cs b/MafiaCommon/Packets/ChatType.cs deleted file mode 100644 index 119228d..0000000 --- a/MafiaCommon/Packets/ChatType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MafiaCommon.Packets -{ - public enum ChatType - { - Queue=1 - } -} \ No newline at end of file diff --git a/MafiaCommon/Packets/DisconnectPlayerPacket.cs b/MafiaCommon/Packets/DisconnectPlayerPacket.cs new file mode 100644 index 0000000..c32f02c --- /dev/null +++ b/MafiaCommon/Packets/DisconnectPlayerPacket.cs @@ -0,0 +1,10 @@ +namespace MafiaCommon.Packets +{ + public class DisconnectPlayerPacket : Packet + { + public DisconnectPlayerPacket() : base(PacketType.DisconnectPlayer) + { + + } + } +} \ No newline at end of file diff --git a/MafiaCommon/Packets/EndGamePacket.cs b/MafiaCommon/Packets/EndGamePacket.cs new file mode 100644 index 0000000..44af628 --- /dev/null +++ b/MafiaCommon/Packets/EndGamePacket.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace MafiaCommon.Packets +{ + public class EndGamePacket : Packet + { + public readonly bool IsWon; + public readonly List PlayerRoles; + + public EndGamePacket(bool isWon, List playerRoles) : base(PacketType.EndGame) + { + IsWon = isWon; + PlayerRoles = playerRoles; + } + } +} \ No newline at end of file diff --git a/MafiaCommon/Packets/GameStartPacket.cs b/MafiaCommon/Packets/GameStartPacket.cs new file mode 100644 index 0000000..975f24f --- /dev/null +++ b/MafiaCommon/Packets/GameStartPacket.cs @@ -0,0 +1,12 @@ +namespace MafiaCommon.Packets +{ + public class GameStartPacket : Packet + { + public readonly Role Role; + + public GameStartPacket(Role role) : base(PacketType.GameStartPacket) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/MafiaCommon/Packets/PacketConverter.cs b/MafiaCommon/Packets/PacketConverter.cs index f11a208..8729c3a 100644 --- a/MafiaCommon/Packets/PacketConverter.cs +++ b/MafiaCommon/Packets/PacketConverter.cs @@ -43,6 +43,12 @@ namespace MafiaCommon.Packets case PacketType.MessageSendPacket: packet = JsonConvert.DeserializeObject(json); break; + case PacketType.GameStartPacket: + packet = JsonConvert.DeserializeObject(json); + break; + case PacketType.EndGame: + packet = JsonConvert.DeserializeObject(json); + break; } return packet; diff --git a/MafiaCommon/Packets/PacketType.cs b/MafiaCommon/Packets/PacketType.cs index f549539..e68a0be 100644 --- a/MafiaCommon/Packets/PacketType.cs +++ b/MafiaCommon/Packets/PacketType.cs @@ -9,6 +9,9 @@ PlayerDisconnected=5, MessageReceivePacket=6, MessageSendPacket=7, + GameStartPacket=8, + EndGame=9, + DisconnectPlayer=10, ServerShutdown=99 } } \ No newline at end of file diff --git a/MafiaCommon/PlayerRole.cs b/MafiaCommon/PlayerRole.cs new file mode 100644 index 0000000..5ef6f56 --- /dev/null +++ b/MafiaCommon/PlayerRole.cs @@ -0,0 +1,14 @@ +namespace MafiaCommon +{ + public class PlayerRole + { + public readonly string Name; + public readonly Role Role; + + public PlayerRole(string name, Role role) + { + Name = name; + Role = role; + } + } +} \ No newline at end of file diff --git a/MafiaCommon/Role.cs b/MafiaCommon/Role.cs new file mode 100644 index 0000000..125fbc0 --- /dev/null +++ b/MafiaCommon/Role.cs @@ -0,0 +1,21 @@ +namespace MafiaCommon +{ + public enum Role + { + Citizen=1, + Commissar=2, + Don=3, + Doctor=4, + Sheriff=5, + Mafia=6, + Deathless=7, + Putana=8, + BlackJudge=9, + BlackLawyer=10, + YakuzaFighter=11, + Ninja=12, + Maniac=13, + Werewolf=14, + RedJudge=15 + } +} \ No newline at end of file diff --git a/MafiaGame/MainWindow.xaml b/MafiaGame/MainWindow.xaml index b16bd9a..ca96dc4 100644 --- a/MafiaGame/MainWindow.xaml +++ b/MafiaGame/MainWindow.xaml @@ -6,7 +6,7 @@ mc:Ignorable="d" Title="RMafia" Height="450" Width="800"> - + @@ -127,6 +127,7 @@ + @@ -152,5 +153,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MafiaGame/MainWindow.xaml.cs b/MafiaGame/MainWindow.xaml.cs index 51800e5..0efe5cd 100644 --- a/MafiaGame/MainWindow.xaml.cs +++ b/MafiaGame/MainWindow.xaml.cs @@ -14,7 +14,7 @@ using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using DiscordRPC; -using MafiaCommon.Packets; +using MafiaCommon; namespace MafiaGame { @@ -143,5 +143,92 @@ namespace MafiaGame QueueChatInput.Clear(); } } + + public void ShowVotingPassive(string name) + { + GameQueue.Visibility = Visibility.Hidden; + GameVotingPassive.Visibility = Visibility.Visible; + GameVotingPassiveRole.Text = name; + } + + public void ShowVotingActive(string name) + { + GameQueue.Visibility = Visibility.Hidden; + GameVotingActive.Visibility = Visibility.Visible; + GameVotingActiveRole.Text = name; + } + + private void GameVotingActiveChatSend_OnClick(object sender, RoutedEventArgs e) + { + if (GameVotingActiveChatInput.Text.Trim() != "") + { + App.Instance.Connection.SendMessage(ChatType.Active, GameVotingActiveChatInput.Text); + GameVotingActiveChatInput.Clear(); + } + } + + private void GameVotingActive_OnKeyUp(object sender, KeyEventArgs e) + { + if (e.Key == Key.Enter) + { + GameVotingActiveChatSend_OnClick(null, null); + } + } + + public void ShowGameEnd(bool isWon, List playerRoles) + { + if (isWon) + { + GameEndScreenWon.Text = "Ты победил!"; + } + else + { + GameEndScreenWon.Text = "Ты проиграл!"; + } + + string text = ""; + + foreach (PlayerRole playerRole in playerRoles) + { + string role = "Роль"; + switch (playerRole.Role) + { + case Role.Citizen: + role = "Мирный житель"; + break; + case Role.Mafia: + role = "Мафия"; + break; + case Role.Don: + role = "Дон"; + break; + } + + text += playerRole.Name + " - " + role + Environment.NewLine; + } + + GameEndScreenRoles.Text = text; + + GameVotingActive.Visibility = Visibility.Hidden; + GameVotingPassive.Visibility = Visibility.Hidden; + GameEndScreen.Visibility = Visibility.Visible; + } + + private void GameEndScreenBack_OnClick(object sender, RoutedEventArgs e) + { + GameEndScreen.Visibility = Visibility.Hidden; + GameQueue.Visibility = Visibility.Visible; + } + + private void GameQueueLeave_OnClick(object sender, RoutedEventArgs e) + { + App.Instance.Connection.Disconnect(); + GameQueue.Visibility = Visibility.Hidden; + MainMenu.Visibility = Visibility.Visible; + App.Instance.GetRpcClient().SetPresence(new RichPresence() + { + State = "В главном меню" + }); + } } } \ No newline at end of file diff --git a/MafiaGame/ServerConnection.cs b/MafiaGame/ServerConnection.cs index 9ca2d39..91e6a54 100644 --- a/MafiaGame/ServerConnection.cs +++ b/MafiaGame/ServerConnection.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Windows.Controls; using DiscordRPC; using MafiaCommon.Packets; +using MafiaCommon; namespace MafiaGame { @@ -15,7 +16,7 @@ namespace MafiaGame private Socket _socket; private Thread _thread; private bool _breakFlag = false; - + public ServerConnection(String ip) { if (ip.Contains(':')) @@ -29,7 +30,7 @@ namespace MafiaGame } _thread = new Thread(serverListener); - + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { @@ -37,12 +38,13 @@ namespace MafiaGame } catch (Exception e) { - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { MainWindow.Instance.ShowDisconnectScreen(e.Message); })); return; } + _socket.Send(PacketConverter.toBytes(new ConnectPacket(Settings.Config().Nick))); _thread.IsBackground = true; _thread.Start(); @@ -53,6 +55,13 @@ namespace MafiaGame _socket.Send(PacketConverter.toBytes(new MessageSendPacket(chatType, text))); } + public void Disconnect() + { + _socket.Send(PacketConverter.toBytes(new DisconnectPlayerPacket())); + _thread.Interrupt(); + _socket.Close(); + } + private void serverListener() { while (!_breakFlag) @@ -64,16 +73,15 @@ namespace MafiaGame { bytes = _socket.Receive(data); builder.Append(Encoding.UTF8.GetString(data, 0, bytes)); - } - while (_socket.Available>0); + } while (_socket.Available > 0); Console.WriteLine(builder.ToString()); - + Packet packet = PacketConverter.toPacket(builder.ToString()); switch (packet.PacketType) { case PacketType.Welcome: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { MainWindow.Instance.QueueOnline.Text = ((WelcomePacket) packet).Players + "/" + ((WelcomePacket) packet).MaxPlayers; @@ -87,7 +95,7 @@ namespace MafiaGame secrets.SpectateSecret = _host + ":" + _port + "/spectate"; App.Instance.GetRpcClient().SetPresence(new RichPresence() { - State = ((WelcomePacket)packet).ServerName, + State = ((WelcomePacket) packet).ServerName, Party = party, Secrets = secrets, Timestamps = Timestamps.Now, @@ -96,37 +104,54 @@ namespace MafiaGame })); break; case PacketType.Disconnect: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { - MainWindow.Instance.ShowDisconnectScreen(((DisconnectPacket)packet).Reason); + MainWindow.Instance.ShowDisconnectScreen(((DisconnectPacket) packet).Reason); })); _breakFlag = true; break; case PacketType.PlayerConnected: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { MainWindow.Instance.QueueOnline.Text = ((PlayerConnectedPacket) packet).Players + "/" + ((PlayerConnectedPacket) packet).MaxPlayers; })); - App.Instance.GetRpcClient().UpdatePartySize(((PlayerConnectedPacket) packet).Players); + try + { + App.Instance.GetRpcClient().UpdatePartySize(((PlayerConnectedPacket) packet).Players); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + break; case PacketType.PlayerDisconnected: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { MainWindow.Instance.QueueOnline.Text = ((PlayerDisconnectedPacket) packet).Players + "/" + ((PlayerDisconnectedPacket) packet).MaxPlayers; })); - App.Instance.GetRpcClient().UpdatePartySize(((PlayerDisconnectedPacket) packet).Players); + try + { + App.Instance.GetRpcClient().UpdatePartySize(((PlayerDisconnectedPacket) packet).Players); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + break; case PacketType.ServerShutdown: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { - MainWindow.Instance.ShowDisconnectScreen("Сервер выключен: "+((ServerShutdownPacket)packet).Reason); + MainWindow.Instance.ShowDisconnectScreen("Сервер выключен: " + + ((ServerShutdownPacket) packet).Reason); })); _breakFlag = true; break; case PacketType.MessageReceivePacket: - App.Current.Dispatcher.Invoke((Action)(() => + App.Current.Dispatcher.Invoke((Action) (() => { ListBoxItem message = new ListBoxItem(); if (((MessageReceivePacket) packet).IsSystem) @@ -139,15 +164,51 @@ namespace MafiaGame ((MessageReceivePacket) packet).Text; } - switch (((MessageReceivePacket)packet).ChatType) + switch (((MessageReceivePacket) packet).ChatType) { case ChatType.Queue: MainWindow.Instance.QueueChat.Items.Add(message); MainWindow.Instance.QueueChat.ScrollIntoView(message); break; + case ChatType.Active: + MainWindow.Instance.GameVotingActiveChat.Items.Add(message); + MainWindow.Instance.GameVotingActiveChat.ScrollIntoView(message); + break; } })); break; + case PacketType.GameStartPacket: + switch (((GameStartPacket) packet).Role) + { + case Role.Citizen: + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.ShowVotingPassive("Ты Мирный Житель"); + })); + break; + case Role.Don: + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.ShowVotingActive("Ты Дон, выбери кого убить!"); + })); + break; + case Role.Mafia: + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.ShowVotingActive("Ты Мафия, выбери кого убить!"); + })); + break; + } + + App.Instance.GetRpcClient().UpdateDetails("Голосование"); + break; + case PacketType.EndGame: + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.ShowGameEnd(((EndGamePacket)packet).IsWon,((EndGamePacket)packet).PlayerRoles); + })); + App.Instance.GetRpcClient().UpdateDetails("Ожидание старта"); + break; } } } diff --git a/MafiaServer/Events/OnDisconnectEvent.cs b/MafiaServer/Events/OnDisconnectEvent.cs new file mode 100644 index 0000000..4346f94 --- /dev/null +++ b/MafiaServer/Events/OnDisconnectEvent.cs @@ -0,0 +1,4 @@ +namespace MafiaServer.Events +{ + public delegate void OnDisconnectEvent(PlayerSocketWorker player); +} \ No newline at end of file diff --git a/MafiaServer/Events/OnPlayerSendMessageEvent.cs b/MafiaServer/Events/OnPlayerSendMessageEvent.cs index 2797730..ce8c4ab 100644 --- a/MafiaServer/Events/OnPlayerSendMessageEvent.cs +++ b/MafiaServer/Events/OnPlayerSendMessageEvent.cs @@ -1,4 +1,4 @@ -using MafiaCommon.Packets; +using MafiaCommon; namespace MafiaServer.Events { diff --git a/MafiaServer/Game.cs b/MafiaServer/Game.cs index ccca371..9c46b09 100644 --- a/MafiaServer/Game.cs +++ b/MafiaServer/Game.cs @@ -1,13 +1,19 @@ using System; using System.Collections.Generic; +using System.Linq; using MafiaCommon.Packets; +using MafiaCommon; namespace MafiaServer { public class Game { private List _players = new List(); + private List _playerRolesAtStart = new List(); private bool isStarted = false; + private GameState _gameState = GameState.NotStarted; + + List _mafia = new List(); public Game() { @@ -31,17 +37,112 @@ namespace MafiaServer player.Id = _players.LastIndexOf(player); player.OnDisconnectByErrorEvent += OnDisconnectByError; player.OnPlayerSendMessageEvent += PlayerOnOnPlayerSendMessageEvent; + player.OnDisconnectEvent += PlayerOnOnDisconnectEvent; player.sendPacket(new WelcomePacket(Settings.Config().ServerName,_players.Count,Settings.Config().MaxPlayers)); } } + private void PlayerOnOnDisconnectEvent(PlayerSocketWorker sender) + { + _players.Remove(sender); + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new PlayerDisconnectedPacket(true,sender.Id,_players.Count,Settings.Config().MaxPlayers)); + } + if (sender.Role == Role.Don) + { + _mafia.Remove(sender); + if (_mafia.Count == 0) + { + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new EndGamePacket(true,_playerRolesAtStart)); + } + + isStarted = false; + _gameState = GameState.NotStarted; + } + else + { + _mafia[0].Role = Role.Don; + if (_gameState == GameState.VotingNight) + { + _mafia[0].sendPacket(new MessageReceivePacket(ChatType.Active,true,"System","Дон покинул игру, ты новый дон!")); + } + } + } + } + public void Start() { + if (isStarted) + { + return; + } if (_players.Count < 2) { Console.WriteLine("Not Enough Players"); return; } + + foreach (PlayerSocketWorker player in _players) + { + player.Role = Role.Citizen; + } + _playerRolesAtStart.Clear(); + + Random random = new Random(); + + PlayerSocketWorker[] empty = _players.ToArray(); + random.Shuffle(empty); + + int mafiasNeed = 1; + if (empty.Length > 5) + { + mafiasNeed = empty.Length / 3; + } + + while (mafiasNeed!=0) + { + for (var i = 0; i < empty.Length; i++) + { + switch (random.Next(2)) + { + case 0: //Мирный + break; + case 1: //Мафия + empty[i].Role = Role.Mafia; + mafiasNeed--; + _mafia.Add(empty[i]); + empty = empty.RemoveFromArray(i); + break; + } + } + } + + PlayerSocketWorker don = _mafia[0]; + don.Role = Role.Don; + _mafia.RemoveAt(0); + + don.sendPacket(new GameStartPacket(Role.Don)); + + foreach (PlayerSocketWorker player in empty) + { + player.sendPacket(new GameStartPacket(Role.Citizen)); + } + + foreach (PlayerSocketWorker player in _mafia) + { + player.sendPacket(new GameStartPacket(Role.Mafia)); + } + + foreach (PlayerSocketWorker player in _players) + { + _playerRolesAtStart.Add(new PlayerRole(player.PlayerName,player.Role)); + } + + isStarted = true; + _gameState = GameState.VotingNight; } private void OnDisconnectByError(PlayerSocketWorker sender) @@ -51,6 +152,28 @@ namespace MafiaServer { player.sendPacket(new PlayerDisconnectedPacket(true,sender.Id,_players.Count,Settings.Config().MaxPlayers)); } + if (sender.Role == Role.Don) + { + _mafia.Remove(sender); + if (_mafia.Count == 0) + { + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new EndGamePacket(true,_playerRolesAtStart)); + } + + isStarted = false; + _gameState = GameState.NotStarted; + } + else + { + _mafia[0].Role = Role.Don; + if (_gameState == GameState.VotingNight) + { + _mafia[0].sendPacket(new MessageReceivePacket(ChatType.Active,true,"System","Дон покинул игру, ты новый дон!")); + } + } + } } private void PlayerOnOnPlayerSendMessageEvent(PlayerSocketWorker sender, ChatType chatType, string text) @@ -66,6 +189,25 @@ namespace MafiaServer } } break; + case ChatType.Active: + if (isStarted) + { + switch (sender.Role) + { + case Role.Mafia: + case Role.Don: + foreach (PlayerSocketWorker player in _players) + { + if (player.Role == Role.Mafia || player.Role == Role.Don) + { + player.sendPacket(new MessageReceivePacket(ChatType.Active, false, sender.PlayerName, + text)); + } + } + break; + } + } + break; } } } diff --git a/MafiaServer/PlayerSocketWorker.cs b/MafiaServer/PlayerSocketWorker.cs index feb83ae..2b59c4d 100644 --- a/MafiaServer/PlayerSocketWorker.cs +++ b/MafiaServer/PlayerSocketWorker.cs @@ -3,6 +3,7 @@ using System.Net.Sockets; using System.Text; using MafiaCommon.Packets; using MafiaServer.Events; +using MafiaCommon; namespace MafiaServer { @@ -12,7 +13,9 @@ namespace MafiaServer public readonly string PlayerName; public event OnDisconnectByErrorEvent OnDisconnectByErrorEvent; public event OnPlayerSendMessageEvent OnPlayerSendMessageEvent; + public event OnDisconnectEvent OnDisconnectEvent; public int Id; + public Role Role = Role.Citizen; public PlayerSocketWorker(Socket socket) { _socket = socket; @@ -71,6 +74,10 @@ namespace MafiaServer case PacketType.MessageSendPacket: OnPlayerSendMessageEvent.Invoke(this,((MessageSendPacket)packet).ChatType,((MessageSendPacket)packet).Text); break; + case PacketType.DisconnectPlayer: + _socket.Close(); + OnDisconnectEvent.Invoke(this); + break; } } catch (SocketException e)