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);
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 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;
Players = players;
}
}
}

View File

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

View File

@ -12,6 +12,7 @@
GameStartPacket=8,
EndGame=9,
DisconnectPlayer=10,
Vote=11,
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>
<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>
<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 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)
{
App.Current.Shutdown(0);
@ -230,5 +242,11 @@ namespace MafiaGame
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.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
@ -62,6 +63,11 @@ namespace MafiaGame
_socket.Close();
}
public void Vote(int id)
{
_socket.Send(PacketConverter.toBytes(new VotePacket(id)));
}
private void serverListener()
{
while (!_breakFlag)
@ -69,11 +75,24 @@ namespace MafiaGame
StringBuilder builder = new StringBuilder();
int bytes = 0;
byte[] data = new byte[256];
try
{
do
{
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());
@ -178,6 +197,7 @@ namespace MafiaGame
}));
break;
case PacketType.GameStartPacket:
List<Player> players = ((GameStartPacket) packet).Players;
switch (((GameStartPacket) packet).Role)
{
case Role.Citizen:
@ -189,13 +209,27 @@ namespace MafiaGame
case Role.Don:
App.Current.Dispatcher.Invoke((Action) (() =>
{
MainWindow.Instance.GameVotingActiveSelect.Items.Clear();
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;
case Role.Mafia:
App.Current.Dispatcher.Invoke((Action) (() =>
{
MainWindow.Instance.GameVotingActiveSelect.Items.Clear();
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;
}

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.Collections.Generic;
using System.Linq;
using MafiaCommon.Packets;
using MafiaCommon;
@ -12,8 +11,10 @@ namespace MafiaServer
private List<PlayerRole> _playerRolesAtStart = new List<PlayerRole>();
private bool isStarted = false;
private GameState _gameState = GameState.NotStarted;
private List<PlayerSocketWorker> _votesRemain = 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()
{
@ -21,6 +22,13 @@ namespace MafiaServer
}
public void ConnectPlayer(PlayerSocketWorker player)
{
if (_players.Count >= Settings.Config().MaxPlayers)
{
player.sendPacket(new DisconnectPacket("Game Full!"));
player.disconnect();
}
else
{
if (isStarted)
{
@ -31,14 +39,62 @@ namespace MafiaServer
{
foreach (PlayerSocketWorker othPlayer in _players)
{
othPlayer.sendPacket(new PlayerConnectedPacket(player.PlayerName,_players.Count+1,Settings.Config().MaxPlayers));
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.sendPacket(new WelcomePacket(Settings.Config().ServerName,_players.Count,Settings.Config().MaxPlayers));
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;
}
}
}
@ -79,7 +135,7 @@ namespace MafiaServer
{
return;
}
if (_players.Count < 2)
if (_players.Count < 3)
{
Console.WriteLine("Not Enough Players");
return;
@ -90,17 +146,18 @@ namespace MafiaServer
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 = 1;
if (empty.Length > 5)
{
mafiasNeed = empty.Length / 3;
}
int mafiasNeed = empty.Length / 3;
Console.WriteLine("Debug: needs counted");
while (mafiasNeed!=0)
{
@ -111,29 +168,43 @@ namespace MafiaServer
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);
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)
{
player.sendPacket(new GameStartPacket(Role.Citizen));
player.sendPacket(new GameStartPacket(Role.Citizen,players));
}
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)
@ -141,6 +212,8 @@ namespace MafiaServer
_playerRolesAtStart.Add(new PlayerRole(player.PlayerName,player.Role));
}
Console.WriteLine("Debug: packets sended");
isStarted = true;
_gameState = GameState.VotingNight;
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using MafiaCommon.Packets;
@ -14,8 +15,10 @@ namespace MafiaServer
public event OnDisconnectByErrorEvent OnDisconnectByErrorEvent;
public event OnPlayerSendMessageEvent OnPlayerSendMessageEvent;
public event OnDisconnectEvent OnDisconnectEvent;
public event OnPlayerVoteEvent OnPlayerVoteEvent;
public int Id;
public Role Role = Role.Citizen;
public PlayerSocketWorker(Socket socket)
{
_socket = socket;
@ -26,8 +29,7 @@ namespace MafiaServer
{
bytes = _socket.Receive(data);
builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
}
while (_socket.Available>0);
} while (_socket.Available > 0);
var packet = PacketConverter.toPacket(builder.ToString());
if (packet.GetType() == typeof(ConnectPacket))
@ -42,9 +44,16 @@ namespace MafiaServer
}
public void sendPacket(Packet packet)
{
try
{
_socket.Send(PacketConverter.toBytes(packet));
}
catch (Exception e)
{
}
}
public void disconnect()
{
@ -72,12 +81,16 @@ namespace MafiaServer
switch (packet.PacketType)
{
case PacketType.MessageSendPacket:
OnPlayerSendMessageEvent.Invoke(this,((MessageSendPacket)packet).ChatType,((MessageSendPacket)packet).Text);
OnPlayerSendMessageEvent.Invoke(this, ((MessageSendPacket) packet).ChatType,
((MessageSendPacket) packet).Text);
break;
case PacketType.DisconnectPlayer:
_socket.Close();
OnDisconnectEvent.Invoke(this);
break;
case PacketType.Vote:
OnPlayerVoteEvent.Invoke(this, ((VotePacket) packet).Id);
break;
}
}
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;
}
}
}