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; private List _votesRemain = new List(); List _mafia = new List(); private Dictionary _mafiaVotes = new Dictionary(); private Dictionary _dayVote = new Dictionary(); public Game() { } public void ConnectPlayer(PlayerSocketWorker player) { if (_players.Count >= Settings.Config().MaxPlayers) { player.sendPacket(new DisconnectPacket("Game Full!")); player.disconnect(); } else { if (isStarted) { player.sendPacket(new DisconnectPacket("Game already started!")); player.disconnect(); } else { foreach (PlayerSocketWorker othPlayer in _players) { othPlayer.sendPacket(new PlayerConnectedPacket(player.PlayerName, _players.Count + 1, Settings.Config().MaxPlayers)); } _players.Add(player); player.Id = _players.LastIndexOf(player); player.OnDisconnectByErrorEvent += OnDisconnectByError; player.OnPlayerSendMessageEvent += PlayerOnOnPlayerSendMessageEvent; player.OnDisconnectEvent += PlayerOnOnDisconnectEvent; player.OnPlayerVoteEvent += PlayerOnOnPlayerVoteEvent; player.sendPacket(new WelcomePacket(Settings.Config().ServerName, _players.Count, Settings.Config().MaxPlayers)); } } } private void PlayerOnOnPlayerVoteEvent(PlayerSocketWorker sender, int id) { if (_votesRemain.Contains(sender)) { PlayerSocketWorker voteFor = _players.FindPlayerById(id); switch (_gameState) { case GameState.VotingNight: switch (sender.Role) { case Role.Don: _mafiaVotes.AddEmpty(id,2); _votesRemain.Remove(sender); foreach (PlayerSocketWorker player in _players) { if (player.Role == Role.Mafia || player.Role == Role.Don) { player.sendPacket(new MessageReceivePacket(ChatType.Active,true,"System",sender.PlayerName+" проголосовал за "+voteFor.PlayerName)); } } break; case Role.Mafia: _mafiaVotes.AddEmpty(id,1); _votesRemain.Remove(sender); foreach (PlayerSocketWorker player in _players) { if (player.Role == Role.Mafia || player.Role == Role.Don) { player.sendPacket(new MessageReceivePacket(ChatType.Active,true,"System",sender.PlayerName+" проголосовал за "+voteFor.PlayerName)); } } break; } break; case GameState.VotingDay: _dayVote.AddEmpty(id,1); _votesRemain.Remove(sender); break; } } if (_votesRemain.Count == 0) { 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); killed.Role = Role.Died; foreach (PlayerSocketWorker player in _players) { player.sendPacket(new GameStageChangedPacket(GameState.Day)); player.sendPacket(new MessageReceivePacket(ChatType.Day,true,"System",killed.PlayerName+" был убит!")); } } } 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 < 3) { Console.WriteLine("Not Enough Players"); return; } foreach (PlayerSocketWorker player in _players) { player.Role = Role.Citizen; } _playerRolesAtStart.Clear(); _votesRemain.Clear(); _mafiaVotes.Clear(); _dayVote.Clear(); Random random = new Random(); PlayerSocketWorker[] empty = _players.ToArray(); random.Shuffle(empty); int mafiasNeed = empty.Length / 3; Console.WriteLine("Debug: needs counted"); while (mafiasNeed!=0) { for (var i = 0; i < empty.Length; i++) { switch (random.Next(2)) { case 0: //Мирный break; case 1: //Мафия if (mafiasNeed > 0) { empty[i].Role = Role.Mafia; mafiasNeed--; _mafia.Add(empty[i]); empty = empty.RemoveFromArray(i); } break; } } } Console.WriteLine("Debug: randomazed"); PlayerSocketWorker don = _mafia[0]; don.Role = Role.Don; _mafia.RemoveAt(0); List players = new List(); foreach (PlayerSocketWorker player in _players) { players.Add(new Player(player.Id, player.PlayerName)); } don.sendPacket(new GameStartPacket(Role.Don,players)); _votesRemain.Add(don); foreach (PlayerSocketWorker player in empty) { player.sendPacket(new GameStartPacket(Role.Citizen,players)); } foreach (PlayerSocketWorker player in _mafia) { player.sendPacket(new GameStartPacket(Role.Mafia,players)); _votesRemain.Add(player); } foreach (PlayerSocketWorker player in _players) { _playerRolesAtStart.Add(new PlayerRole(player.PlayerName,player.Role)); } Console.WriteLine("Debug: packets sended"); isStarted = true; _gameState = GameState.VotingNight; } private void OnDisconnectByError(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","Дон покинул игру, ты новый дон!")); } } } } private void PlayerOnOnPlayerSendMessageEvent(PlayerSocketWorker sender, ChatType chatType, string text) { switch (chatType) { case ChatType.Queue: if (!isStarted) { foreach (PlayerSocketWorker player in _players) { player.sendPacket(new MessageReceivePacket(ChatType.Queue,false,sender.PlayerName,text)); } } 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; case ChatType.Day: if (isStarted) { if (sender.Role == Role.Died) { sender.sendPacket(new MessageReceivePacket(ChatType.Day,true,"system","Мёртвое говорить не может")); } else { foreach (PlayerSocketWorker player in _players) { player.sendPacket( new MessageReceivePacket(ChatType.Day, false, sender.PlayerName, text)); } } } break; } } } }