Now game know who not voted, count votes and send vote message

This commit is contained in:
Ilya 2021-01-21 23:42:05 +03:00
parent 6d99b0bbee
commit 227372ac3d
12 changed files with 242 additions and 37 deletions

View File

@ -23,5 +23,17 @@ namespace MafiaCommon
tmp.RemoveAt(numIdx); tmp.RemoveAt(numIdx);
return tmp.ToArray(); return tmp.ToArray();
} }
public static void AddEmpty<T>(this Dictionary<T, int> original, T id, int add)
{
if (original.ContainsKey(id))
{
original[id] += add;
}
else
{
original.Add(id,add);
}
}
} }
} }

View File

@ -1,12 +1,16 @@
namespace MafiaCommon.Packets using System.Collections.Generic;
namespace MafiaCommon.Packets
{ {
public class GameStartPacket : Packet public class GameStartPacket : Packet
{ {
public readonly Role Role; public readonly Role Role;
public readonly List<Player> Players;
public GameStartPacket(Role role) : base(PacketType.GameStartPacket) public GameStartPacket(Role role, List<Player> players) : base(PacketType.GameStartPacket)
{ {
Role = role; Role = role;
Players = players;
} }
} }
} }

View File

@ -49,6 +49,12 @@ namespace MafiaCommon.Packets
case PacketType.EndGame: case PacketType.EndGame:
packet = JsonConvert.DeserializeObject<EndGamePacket>(json); packet = JsonConvert.DeserializeObject<EndGamePacket>(json);
break; break;
case PacketType.DisconnectPlayer:
packet = JsonConvert.DeserializeObject<DisconnectPacket>(json);
break;
case PacketType.Vote:
packet = JsonConvert.DeserializeObject<VotePacket>(json);
break;
} }
return packet; return packet;

View File

@ -12,6 +12,7 @@
GameStartPacket=8, GameStartPacket=8,
EndGame=9, EndGame=9,
DisconnectPlayer=10, DisconnectPlayer=10,
Vote=11,
ServerShutdown=99 ServerShutdown=99
} }
} }

View File

@ -0,0 +1,12 @@
namespace MafiaCommon.Packets
{
public class VotePacket : Packet
{
public readonly int Id;
public VotePacket(int id) : base(PacketType.Vote)
{
Id = id;
}
}
}

14
MafiaCommon/Player.cs Normal file
View File

@ -0,0 +1,14 @@
namespace MafiaCommon
{
public class Player
{
public readonly int Id;
public readonly string Name;
public Player(int id, string name)
{
Id = id;
Name = name;
}
}
}

View File

@ -221,7 +221,7 @@
<ListBox Grid.Column="5" Grid.ColumnSpan="5" Grid.Row="2" Grid.RowSpan="8" x:Name="GameVotingActiveChat"></ListBox> <ListBox Grid.Column="5" Grid.ColumnSpan="5" Grid.Row="2" Grid.RowSpan="8" x:Name="GameVotingActiveChat"></ListBox>
<TextBox Grid.Column="5" Grid.ColumnSpan="4" Grid.Row="10" TextWrapping="Wrap" x:Name="GameVotingActiveChatInput"></TextBox> <TextBox Grid.Column="5" Grid.ColumnSpan="4" Grid.Row="10" TextWrapping="Wrap" x:Name="GameVotingActiveChatInput"></TextBox>
<Button Grid.Column="9" Grid.Row="10" Content="Отправить!" Click="GameVotingActiveChatSend_OnClick"></Button> <Button Grid.Column="9" Grid.Row="10" Content="Отправить!" Click="GameVotingActiveChatSend_OnClick"></Button>
<ListBox Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" Grid.RowSpan="8" x:Name="GameVotingActiveSelect"></ListBox> <ListBox Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" Grid.RowSpan="8" x:Name="GameVotingActiveSelect" MouseDoubleClick="GameVotingActiveSelect_OnMouseDoubleClick" SelectionMode="Single"></ListBox>
</Grid> </Grid>
<Grid x:Name="GameEndScreen" Visibility="Hidden"> <Grid x:Name="GameEndScreen" Visibility="Hidden">

View File

@ -39,6 +39,18 @@ namespace MafiaGame
}); });
} }
public void HideAll()
{
MainMenu.Visibility = Visibility.Hidden;
SettingsGUI.Visibility = Visibility.Hidden;
IpInput.Visibility = Visibility.Hidden;
GameQueue.Visibility = Visibility.Hidden;
DisconnectScreen.Visibility = Visibility.Hidden;
GameVotingPassive.Visibility = Visibility.Hidden;
GameVotingActive.Visibility = Visibility.Hidden;
GameEndScreen.Visibility = Visibility.Hidden;
}
private void Exit_OnClick(object sender, RoutedEventArgs e) private void Exit_OnClick(object sender, RoutedEventArgs e)
{ {
App.Current.Shutdown(0); App.Current.Shutdown(0);
@ -230,5 +242,11 @@ namespace MafiaGame
State = "В главном меню" State = "В главном меню"
}); });
} }
private void GameVotingActiveSelect_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBoxItem selected = (ListBoxItem)GameVotingActiveSelect.SelectedItem;
App.Instance.Connection.Vote(Convert.ToInt32(((string)selected.Content).Split(")")[0]));
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -62,6 +63,11 @@ namespace MafiaGame
_socket.Close(); _socket.Close();
} }
public void Vote(int id)
{
_socket.Send(PacketConverter.toBytes(new VotePacket(id)));
}
private void serverListener() private void serverListener()
{ {
while (!_breakFlag) while (!_breakFlag)
@ -69,11 +75,24 @@ namespace MafiaGame
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
int bytes = 0; int bytes = 0;
byte[] data = new byte[256]; byte[] data = new byte[256];
do try
{ {
bytes = _socket.Receive(data); do
builder.Append(Encoding.UTF8.GetString(data, 0, bytes)); {
} while (_socket.Available > 0); bytes = _socket.Receive(data);
builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
} while (_socket.Available > 0);
}
catch (Exception e)
{
_socket.Close();
App.Current.Dispatcher.Invoke((Action) (() =>
{
MainWindow.Instance.HideAll();
MainWindow.Instance.ShowDisconnectScreen(e.Message);
}));
_breakFlag = true;
}
Console.WriteLine(builder.ToString()); Console.WriteLine(builder.ToString());
@ -178,6 +197,7 @@ namespace MafiaGame
})); }));
break; break;
case PacketType.GameStartPacket: case PacketType.GameStartPacket:
List<Player> players = ((GameStartPacket) packet).Players;
switch (((GameStartPacket) packet).Role) switch (((GameStartPacket) packet).Role)
{ {
case Role.Citizen: case Role.Citizen:
@ -189,13 +209,27 @@ namespace MafiaGame
case Role.Don: case Role.Don:
App.Current.Dispatcher.Invoke((Action) (() => App.Current.Dispatcher.Invoke((Action) (() =>
{ {
MainWindow.Instance.GameVotingActiveSelect.Items.Clear();
MainWindow.Instance.ShowVotingActive("Ты Дон, выбери кого убить!"); MainWindow.Instance.ShowVotingActive("Ты Дон, выбери кого убить!");
foreach (Player player in players)
{
ListBoxItem item = new ListBoxItem();
item.Content = player.Id.ToString() + ") " + player.Name;
MainWindow.Instance.GameVotingActiveSelect.Items.Add(item);
}
})); }));
break; break;
case Role.Mafia: case Role.Mafia:
App.Current.Dispatcher.Invoke((Action) (() => App.Current.Dispatcher.Invoke((Action) (() =>
{ {
MainWindow.Instance.GameVotingActiveSelect.Items.Clear();
MainWindow.Instance.ShowVotingActive("Ты Мафия, выбери кого убить!"); MainWindow.Instance.ShowVotingActive("Ты Мафия, выбери кого убить!");
foreach (Player player in players)
{
ListBoxItem item = new ListBoxItem();
item.Content = player.Id.ToString() + ") " + player.Name;
MainWindow.Instance.GameVotingActiveSelect.Items.Add(item);
}
})); }));
break; break;
} }

View File

@ -0,0 +1,6 @@
using MafiaCommon;
namespace MafiaServer.Events
{
public delegate void OnPlayerVoteEvent(PlayerSocketWorker sender, int id);
}

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MafiaCommon.Packets; using MafiaCommon.Packets;
using MafiaCommon; using MafiaCommon;
@ -12,8 +11,10 @@ namespace MafiaServer
private List<PlayerRole> _playerRolesAtStart = new List<PlayerRole>(); private List<PlayerRole> _playerRolesAtStart = new List<PlayerRole>();
private bool isStarted = false; private bool isStarted = false;
private GameState _gameState = GameState.NotStarted; private GameState _gameState = GameState.NotStarted;
private List<PlayerSocketWorker> _votesRemain = new List<PlayerSocketWorker>();
List<PlayerSocketWorker> _mafia = new List<PlayerSocketWorker>(); List<PlayerSocketWorker> _mafia = new List<PlayerSocketWorker>();
private Dictionary<int, int> _mafiaVotes = new Dictionary<int, int>();
private Dictionary<int, int> _dayVote = new Dictionary<int, int>();
public Game() public Game()
{ {
@ -22,23 +23,78 @@ namespace MafiaServer
public void ConnectPlayer(PlayerSocketWorker player) public void ConnectPlayer(PlayerSocketWorker player)
{ {
if (isStarted) if (_players.Count >= Settings.Config().MaxPlayers)
{ {
player.sendPacket(new DisconnectPacket("Game already started!")); player.sendPacket(new DisconnectPacket("Game Full!"));
player.disconnect(); player.disconnect();
} }
else else
{ {
foreach (PlayerSocketWorker othPlayer in _players) if (isStarted)
{ {
othPlayer.sendPacket(new PlayerConnectedPacket(player.PlayerName,_players.Count+1,Settings.Config().MaxPlayers)); 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;
} }
_players.Add(player);
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));
} }
} }
@ -79,7 +135,7 @@ namespace MafiaServer
{ {
return; return;
} }
if (_players.Count < 2) if (_players.Count < 3)
{ {
Console.WriteLine("Not Enough Players"); Console.WriteLine("Not Enough Players");
return; return;
@ -90,17 +146,18 @@ namespace MafiaServer
player.Role = Role.Citizen; player.Role = Role.Citizen;
} }
_playerRolesAtStart.Clear(); _playerRolesAtStart.Clear();
_votesRemain.Clear();
_mafiaVotes.Clear();
_dayVote.Clear();
Random random = new Random(); Random random = new Random();
PlayerSocketWorker[] empty = _players.ToArray(); PlayerSocketWorker[] empty = _players.ToArray();
random.Shuffle(empty); random.Shuffle(empty);
int mafiasNeed = 1; int mafiasNeed = empty.Length / 3;
if (empty.Length > 5)
{ Console.WriteLine("Debug: needs counted");
mafiasNeed = empty.Length / 3;
}
while (mafiasNeed!=0) while (mafiasNeed!=0)
{ {
@ -111,29 +168,43 @@ namespace MafiaServer
case 0: //Мирный case 0: //Мирный
break; break;
case 1: //Мафия case 1: //Мафия
empty[i].Role = Role.Mafia; if (mafiasNeed > 0)
mafiasNeed--; {
_mafia.Add(empty[i]); empty[i].Role = Role.Mafia;
empty = empty.RemoveFromArray(i); mafiasNeed--;
_mafia.Add(empty[i]);
empty = empty.RemoveFromArray(i);
}
break; break;
} }
} }
} }
Console.WriteLine("Debug: randomazed");
PlayerSocketWorker don = _mafia[0]; PlayerSocketWorker don = _mafia[0];
don.Role = Role.Don; don.Role = Role.Don;
_mafia.RemoveAt(0); _mafia.RemoveAt(0);
don.sendPacket(new GameStartPacket(Role.Don)); List<Player> players = new List<Player>();
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) foreach (PlayerSocketWorker player in empty)
{ {
player.sendPacket(new GameStartPacket(Role.Citizen)); player.sendPacket(new GameStartPacket(Role.Citizen,players));
} }
foreach (PlayerSocketWorker player in _mafia) foreach (PlayerSocketWorker player in _mafia)
{ {
player.sendPacket(new GameStartPacket(Role.Mafia)); player.sendPacket(new GameStartPacket(Role.Mafia,players));
_votesRemain.Add(player);
} }
foreach (PlayerSocketWorker player in _players) foreach (PlayerSocketWorker player in _players)
@ -141,6 +212,8 @@ namespace MafiaServer
_playerRolesAtStart.Add(new PlayerRole(player.PlayerName,player.Role)); _playerRolesAtStart.Add(new PlayerRole(player.PlayerName,player.Role));
} }
Console.WriteLine("Debug: packets sended");
isStarted = true; isStarted = true;
_gameState = GameState.VotingNight; _gameState = GameState.VotingNight;
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using MafiaCommon.Packets; using MafiaCommon.Packets;
@ -14,8 +15,10 @@ namespace MafiaServer
public event OnDisconnectByErrorEvent OnDisconnectByErrorEvent; public event OnDisconnectByErrorEvent OnDisconnectByErrorEvent;
public event OnPlayerSendMessageEvent OnPlayerSendMessageEvent; public event OnPlayerSendMessageEvent OnPlayerSendMessageEvent;
public event OnDisconnectEvent OnDisconnectEvent; public event OnDisconnectEvent OnDisconnectEvent;
public event OnPlayerVoteEvent OnPlayerVoteEvent;
public int Id; public int Id;
public Role Role = Role.Citizen; public Role Role = Role.Citizen;
public PlayerSocketWorker(Socket socket) public PlayerSocketWorker(Socket socket)
{ {
_socket = socket; _socket = socket;
@ -26,8 +29,7 @@ namespace MafiaServer
{ {
bytes = _socket.Receive(data); bytes = _socket.Receive(data);
builder.Append(Encoding.UTF8.GetString(data, 0, bytes)); builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
} } while (_socket.Available > 0);
while (_socket.Available>0);
var packet = PacketConverter.toPacket(builder.ToString()); var packet = PacketConverter.toPacket(builder.ToString());
if (packet.GetType() == typeof(ConnectPacket)) if (packet.GetType() == typeof(ConnectPacket))
@ -43,7 +45,14 @@ namespace MafiaServer
public void sendPacket(Packet packet) public void sendPacket(Packet packet)
{ {
_socket.Send(PacketConverter.toBytes(packet)); try
{
_socket.Send(PacketConverter.toBytes(packet));
}
catch (Exception e)
{
}
} }
public void disconnect() public void disconnect()
@ -72,12 +81,16 @@ namespace MafiaServer
switch (packet.PacketType) switch (packet.PacketType)
{ {
case PacketType.MessageSendPacket: case PacketType.MessageSendPacket:
OnPlayerSendMessageEvent.Invoke(this,((MessageSendPacket)packet).ChatType,((MessageSendPacket)packet).Text); OnPlayerSendMessageEvent.Invoke(this, ((MessageSendPacket) packet).ChatType,
((MessageSendPacket) packet).Text);
break; break;
case PacketType.DisconnectPlayer: case PacketType.DisconnectPlayer:
_socket.Close(); _socket.Close();
OnDisconnectEvent.Invoke(this); OnDisconnectEvent.Invoke(this);
break; break;
case PacketType.Vote:
OnPlayerVoteEvent.Invoke(this, ((VotePacket) packet).Id);
break;
} }
} }
catch (SocketException e) catch (SocketException e)
@ -87,4 +100,16 @@ namespace MafiaServer
} }
} }
} }
public static class PlayerSocketWorkerUtils {
public static PlayerSocketWorker FindPlayerById(this List<PlayerSocketWorker> original, int id)
{
foreach (PlayerSocketWorker player in original)
{
if (player.Id == id) return player;
}
return null;
}
}
} }