diff --git a/MafiaCommon/Packets/GameStageChangedPacket.cs b/MafiaCommon/Packets/GameStageChangedPacket.cs index 686c630..b5eb717 100644 --- a/MafiaCommon/Packets/GameStageChangedPacket.cs +++ b/MafiaCommon/Packets/GameStageChangedPacket.cs @@ -1,14 +1,18 @@ -namespace MafiaCommon.Packets +using System.Collections.Generic; + +namespace MafiaCommon.Packets { public class GameStageChangedPacket : Packet { public readonly GameState GameState; public readonly Role Role; + public readonly List Players; - public GameStageChangedPacket(GameState gameState, Role role) : base(PacketType.GameStateChanged) + public GameStageChangedPacket(GameState gameState, Role role, List players) : base(PacketType.GameStateChanged) { GameState = gameState; Role = role; + Players = players; } } } \ No newline at end of file diff --git a/MafiaGame/MainWindow.xaml.cs b/MafiaGame/MainWindow.xaml.cs index 1628903..2696efd 100644 --- a/MafiaGame/MainWindow.xaml.cs +++ b/MafiaGame/MainWindow.xaml.cs @@ -235,7 +235,7 @@ namespace MafiaGame private void GameQueueLeave_OnClick(object sender, RoutedEventArgs e) { App.Instance.Connection.Disconnect(); - GameQueue.Visibility = Visibility.Hidden; + HideAll(); MainMenu.Visibility = Visibility.Visible; App.Instance.GetRpcClient().SetPresence(new RichPresence() { @@ -268,12 +268,12 @@ namespace MafiaGame private void GameDaySelect_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { - + ListBoxItem selected = (ListBoxItem)GameDaySelect.SelectedItem; + App.Instance.Connection.Vote(Convert.ToInt32(((string)selected.Content).Split(")")[0])); } - public void ShowDay(bool voting, Role role) + public void ShowDay(bool voting, Role role, List players) { - HideAll(); GameDaySelect.IsEnabled = voting; if (role == Role.Died) { @@ -284,6 +284,12 @@ namespace MafiaGame if (voting) { GameDayHotBar.Text = "Голосуй и молись"; + foreach (Player player in players) + { + ListBoxItem item = new ListBoxItem(); + item.Content = player.Id.ToString() + ") " + player.Name; + MainWindow.Instance.GameDaySelect.Items.Add(item); + } } else { diff --git a/MafiaGame/ServerConnection.cs b/MafiaGame/ServerConnection.cs index 6566059..ccd5283 100644 --- a/MafiaGame/ServerConnection.cs +++ b/MafiaGame/ServerConnection.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Net.Sockets; using System.Text; using System.Threading; -using System.Windows; using System.Windows.Controls; using DiscordRPC; using MafiaCommon.Packets; @@ -18,6 +17,7 @@ namespace MafiaGame private Socket _socket; private Thread _thread; private bool _breakFlag = false; + private bool connected; public ServerConnection(String ip) { @@ -50,6 +50,7 @@ namespace MafiaGame _socket.Send(PacketConverter.toBytes(new ConnectPacket(Settings.Config().Nick))); _thread.IsBackground = true; _thread.Start(); + connected = true; } public void SendMessage(ChatType chatType, string text) @@ -59,6 +60,7 @@ namespace MafiaGame public void Disconnect() { + connected = false; _socket.Send(PacketConverter.toBytes(new DisconnectPlayerPacket())); _thread.Interrupt(); _socket.Close(); @@ -87,20 +89,27 @@ namespace MafiaGame catch (Exception e) { _socket.Close(); - App.Current.Dispatcher.Invoke((Action) (() => + if (connected) { - MainWindow.Instance.HideAll(); - MainWindow.Instance.ShowDisconnectScreen(e.Message); - })); + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.HideAll(); + MainWindow.Instance.ShowDisconnectScreen(e.Message); + })); + connected = false; + } _breakFlag = true; } - Console.WriteLine(builder.ToString()); - - List packets = PacketConverter.toPacket(builder.ToString()); - foreach (Packet packet in packets) + if (!_breakFlag) { - WorkPacket(packet); + Console.WriteLine(builder.ToString()); + + List packets = PacketConverter.toPacket(builder.ToString()); + foreach (Packet packet in packets) + { + WorkPacket(packet); + } } } } @@ -258,15 +267,56 @@ namespace MafiaGame App.Instance.GetRpcClient().UpdateDetails("Ожидание старта"); break; case PacketType.GameStateChanged: - switch (((GameStageChangedPacket)packet).GameState) + App.Current.Dispatcher.Invoke((Action) (() => { MainWindow.Instance.HideAll(); })); + players = ((GameStageChangedPacket) packet).Players; + switch (((GameStageChangedPacket) packet).GameState) { - case GameState.Day: + case GameState.Day: App.Current.Dispatcher.Invoke((Action) (() => { - MainWindow.Instance.ShowDay(false,((GameStageChangedPacket)packet).Role); + MainWindow.Instance.ShowDay(false, ((GameStageChangedPacket) packet).Role,players); })); App.Instance.GetRpcClient().UpdateDetails("День"); break; + case GameState.VotingDay: + App.Current.Dispatcher.Invoke((Action) (() => + { + MainWindow.Instance.ShowDay(true, ((GameStageChangedPacket) packet).Role,players); + })); + App.Instance.GetRpcClient().UpdateDetails("Голосование!"); + break; + case GameState.VotingNight: + switch (((GameStageChangedPacket)packet).Role) + { + case Role.Citizen: + case Role.Died: + App.Current.Dispatcher.Invoke((Action) (() => + { + String rol; + if (((GameStageChangedPacket)packet).Role == Role.Citizen) rol = "Мирный житель"; + else rol = "Мёртв"; + MainWindow.Instance.ShowVotingPassive("Ты " +rol+ "!"); + })); + break; + case Role.Mafia: + case Role.Don: + App.Current.Dispatcher.Invoke((Action) (() => + { + String rol; + if (((GameStageChangedPacket)packet).Role == Role.Mafia) rol = "Мафия"; + else rol = "Дон"; + MainWindow.Instance.GameVotingActiveSelect.Items.Clear(); + MainWindow.Instance.ShowVotingActive("Ты "+rol+", выбери кого убить!"); + foreach (Player player in players) + { + ListBoxItem item = new ListBoxItem(); + item.Content = player.Id.ToString() + ") " + player.Name; + MainWindow.Instance.GameVotingActiveSelect.Items.Add(item); + } + })); + break; + } + break; } break; } diff --git a/MafiaServer/Game.cs b/MafiaServer/Game.cs index ebb2c1a..1783912 100644 --- a/MafiaServer/Game.cs +++ b/MafiaServer/Game.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using MafiaCommon.Packets; using MafiaCommon; @@ -15,6 +16,7 @@ namespace MafiaServer List _mafia = new List(); private Dictionary _mafiaVotes = new Dictionary(); private Dictionary _dayVote = new Dictionary(); + private Timer _voteStartTimer; public Game() { @@ -55,7 +57,22 @@ namespace MafiaServer } } - private void WorkDeath(PlayerSocketWorker player) + public List GetPlayersRoles() + { + List players = new List(); + + foreach (PlayerSocketWorker player in _players) + { + if (player.Role != Role.Died) + { + players.Add(new Player(player.Id, player.PlayerName)); + } + } + + return players; + } + + private bool WorkDeath(PlayerSocketWorker player) { switch (player.Role) { @@ -65,11 +82,12 @@ namespace MafiaServer { foreach (PlayerSocketWorker p in _players) { - player.sendPacket(new EndGamePacket(true,_playerRolesAtStart)); + p.sendPacket(new EndGamePacket(true,_playerRolesAtStart)); } isStarted = false; _gameState = GameState.NotStarted; + return false; } else { @@ -78,11 +96,32 @@ namespace MafiaServer { _mafia[0].sendPacket(new MessageReceivePacket(ChatType.Active,true,"System","Дон покинул игру, ты новый дон!")); } + _mafia.RemoveAt(0); } break; } + int mafias = _mafia.Count + 1; + int aliveLefts = 0; + + foreach (PlayerSocketWorker pl in _players) + { + if (pl.Role != Role.Died && pl.Role != Role.Don && pl.Role != Role.Mafia) aliveLefts++; + } + + if (mafias >= aliveLefts) + { + foreach (PlayerSocketWorker p in _players) + { + p.sendPacket(new EndGamePacket(p.Role == Role.Mafia || p.Role == Role.Don, _playerRolesAtStart)); + } + isStarted = false; + _gameState = GameState.NotStarted; + return false; + } + player.Role = Role.Died; + return true; } private void PlayerOnOnPlayerVoteEvent(PlayerSocketWorker sender, int id) @@ -129,25 +168,93 @@ namespace MafiaServer if (_votesRemain.Count == 0) { - int selId = 0; - int selVotes = 0; - foreach (KeyValuePair votes in _mafiaVotes) + switch (_gameState) { - if (votes.Value > selVotes) - { - selId = votes.Key; - selVotes = votes.Value; - } - } + case GameState.VotingNight: + int selId = 0; + int selVotes = 0; + foreach (KeyValuePair votes in _mafiaVotes) + { + if (votes.Value > selVotes) + { + selId = votes.Key; + selVotes = votes.Value; + } + } - _gameState = GameState.Day; - - PlayerSocketWorker killed = _players.FindPlayerById(selId); - WorkDeath(killed); - foreach (PlayerSocketWorker player in _players) + PlayerSocketWorker killed = _players.FindPlayerById(selId); + if (WorkDeath(killed)) + { + _gameState = GameState.Day; + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new GameStageChangedPacket(GameState.Day, player.Role, + GetPlayersRoles())); + player.sendPacket(new MessageReceivePacket(ChatType.Day, true, "System", + killed.PlayerName + " был убит!")); + } + + _voteStartTimer = new Timer(StartDayVote, null, 60000, 60000); + } + break; + case GameState.VotingDay: + selId = 0; + selVotes = 0; + foreach (KeyValuePair votes in _dayVote) + { + if (votes.Value > selVotes) + { + selId = votes.Key; selVotes = votes.Value; + } + } + + killed = _players.FindPlayerById(selId); + if (WorkDeath(killed)) + { + _gameState = GameState.VotingNight; + FillNightVotes(); + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new GameStageChangedPacket(GameState.VotingNight, player.Role, + GetPlayersRoles())); + player.sendPacket(new MessageReceivePacket(ChatType.Day, true, "System", + killed.PlayerName + " был повешен!")); + } + } + break; + } + } + } + + private void StartDayVote(object obj) + { + _voteStartTimer.Dispose(); + _gameState = GameState.VotingDay; + _votesRemain.Clear(); + foreach (PlayerSocketWorker player in _players) + { + if (player.Role != Role.Died) { - player.sendPacket(new GameStageChangedPacket(GameState.Day,player.Role)); - player.sendPacket(new MessageReceivePacket(ChatType.Day,true,"System",killed.PlayerName+" был убит!")); + _votesRemain.Add(player); + } + } + foreach (PlayerSocketWorker player in _players) + { + player.sendPacket(new GameStageChangedPacket(GameState.VotingDay,player.Role,GetPlayersRoles())); + player.sendPacket(new MessageReceivePacket(ChatType.Day,true,"System","Начинаем голосование!")); + } + } + + private void FillNightVotes() + { + foreach (PlayerSocketWorker player in _players) + { + switch (player.Role) + { + case Role.Don: + case Role.Mafia: + _votesRemain.Add(player); + break; } } } @@ -156,10 +263,14 @@ namespace MafiaServer { _players.Remove(sender); foreach (PlayerSocketWorker player in _players) - { - player.sendPacket(new PlayerDisconnectedPacket(true,sender.Id,_players.Count,Settings.Config().MaxPlayers)); + { + player.sendPacket(new PlayerDisconnectedPacket(true, sender.Id, _players.Count, + Settings.Config().MaxPlayers)); } - WorkDeath(sender); + if (_gameState != GameState.NotStarted) + { + WorkDeath(sender); + } } public void Start() @@ -219,12 +330,7 @@ namespace MafiaServer don.Role = Role.Don; _mafia.RemoveAt(0); - List players = new List(); - - foreach (PlayerSocketWorker player in _players) - { - players.Add(new Player(player.Id, player.PlayerName)); - } + List players = GetPlayersRoles(); don.sendPacket(new GameStartPacket(Role.Don,players)); _votesRemain.Add(don);