323 lines
14 KiB
C#
323 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Threading;
|
|
using DiscordRPC;
|
|
using MafiaCommon.Packets;
|
|
using MafiaCommon;
|
|
|
|
namespace MafiaClient
|
|
{
|
|
public class ServerConnection
|
|
{
|
|
private readonly String _host = "localhost";
|
|
private readonly int _port = 25743;
|
|
private readonly Socket _socket;
|
|
private readonly Thread _thread;
|
|
private bool _breakFlag;
|
|
private bool _connected;
|
|
|
|
public ServerConnection(String ip)
|
|
{
|
|
if (ip.Contains(':'))
|
|
{
|
|
_host = ip.Split(":")[0];
|
|
_port = Convert.ToInt32(ip.Split(":")[1]);
|
|
}
|
|
else if (_host.Length != 0)
|
|
{
|
|
_host = ip;
|
|
}
|
|
|
|
_thread = new Thread(ServerListener);
|
|
|
|
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
try
|
|
{
|
|
_socket.Connect(_host, _port);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Dispatcher.UIThread.InvokeAsync(() => { MainWindow.Instance.ShowDisconnectScreen(e.Message); });
|
|
return;
|
|
}
|
|
|
|
_socket.Send(PacketConverter.ToBytes(new ConnectPacket(Settings.Config().Nick)));
|
|
_thread.IsBackground = true;
|
|
_thread.Start();
|
|
_connected = true;
|
|
}
|
|
|
|
public void AddMessageToChat(String chatName, ListBoxItem message)
|
|
{
|
|
ItemsRepeater listBoxes = MainWindow.Instance.Find<ItemsRepeater>(chatName);
|
|
if (listBoxes.Items == null || listBoxes.Items.GetType() != typeof(List<ListBoxItem>))
|
|
{
|
|
List<ListBoxItem> items = new List<ListBoxItem>();
|
|
items.Add(message);
|
|
listBoxes.Items = items;
|
|
}
|
|
else
|
|
{
|
|
List<ListBoxItem> items = (List<ListBoxItem>) listBoxes.Items;
|
|
List<ListBoxItem> list = new List<ListBoxItem>();
|
|
list.AddRange(items);
|
|
list.Add(message);
|
|
listBoxes.Items = list;
|
|
}
|
|
MainWindow.Instance.FindControl<ScrollViewer>("QueueChatViewer").ScrollToEnd();
|
|
}
|
|
|
|
public void SendMessage(ChatType chatType, string text)
|
|
{
|
|
_socket.Send(PacketConverter.ToBytes(new MessageSendPacket(chatType, text)));
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
_connected = false;
|
|
_socket.Send(PacketConverter.ToBytes(new DisconnectPlayerPacket()));
|
|
_thread.Interrupt();
|
|
_socket.Close();
|
|
}
|
|
|
|
public void Vote(int id)
|
|
{
|
|
_socket.Send(PacketConverter.ToBytes(new VotePacket(id)));
|
|
}
|
|
|
|
private void ServerListener()
|
|
{
|
|
while (!_breakFlag)
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
byte[] data = new byte[256];
|
|
try
|
|
{
|
|
do
|
|
{
|
|
var bytes = _socket.Receive(data);
|
|
builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
|
|
} while (_socket.Available > 0);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_socket.Close();
|
|
if (_connected)
|
|
{
|
|
MainWindow.Instance.HideAll();
|
|
MainWindow.Instance.ShowDisconnectScreen(e.Message);
|
|
_connected = false;
|
|
}
|
|
_breakFlag = true;
|
|
}
|
|
|
|
if (!_breakFlag)
|
|
{
|
|
Console.WriteLine(builder.ToString());
|
|
|
|
List<Packet> packets = PacketConverter.ToPacket(builder.ToString());
|
|
foreach (Packet packet in packets)
|
|
{
|
|
WorkPacket(packet);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WorkPacket(Packet packet)
|
|
{
|
|
Dispatcher.UIThread.InvokeAsync(() =>
|
|
{
|
|
switch (packet.PacketType)
|
|
{
|
|
case PacketType.Welcome:
|
|
MainWindow.Instance.Find<TextBlock>("QueueOnline").Text = ((WelcomePacket) packet).Players +
|
|
"/" +
|
|
((WelcomePacket) packet).MaxPlayers;
|
|
MainWindow.Instance.ShowGameQueueScreen();
|
|
Party party = new Party
|
|
{
|
|
ID = _host + ":" + _port,
|
|
Size = ((WelcomePacket) packet).Players,
|
|
Max = ((WelcomePacket) packet).MaxPlayers
|
|
};
|
|
Secrets secrets = new Secrets
|
|
{
|
|
JoinSecret = _host + ":" + _port + "/join",
|
|
SpectateSecret = _host + ":" + _port + "/spectate"
|
|
};
|
|
App.Instance.GetRpcClient().SetPresence(new RichPresence()
|
|
{
|
|
State = ((WelcomePacket) packet).ServerName,
|
|
Party = party,
|
|
Secrets = secrets,
|
|
Timestamps = Timestamps.Now,
|
|
Details = "Ожидание старта"
|
|
});
|
|
break;
|
|
case PacketType.Disconnect:
|
|
MainWindow.Instance.ShowDisconnectScreen(((DisconnectPacket) packet).Reason);
|
|
_breakFlag = true;
|
|
break;
|
|
case PacketType.PlayerConnected:
|
|
MainWindow.Instance.Find<TextBlock>("QueueOnline").Text =
|
|
((PlayerConnectedPacket) packet).Players + "/" +
|
|
((PlayerConnectedPacket) packet).MaxPlayers;
|
|
try
|
|
{
|
|
App.Instance.GetRpcClient().UpdatePartySize(((PlayerConnectedPacket) packet).Players);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e.Message);
|
|
}
|
|
|
|
break;
|
|
case PacketType.PlayerDisconnected:
|
|
MainWindow.Instance.Find<TextBlock>("QueueOnline").Text =
|
|
((PlayerDisconnectedPacket) packet).Players + "/" +
|
|
((PlayerDisconnectedPacket) packet).MaxPlayers;
|
|
try
|
|
{
|
|
App.Instance.GetRpcClient().UpdatePartySize(((PlayerDisconnectedPacket) packet).Players);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e.Message);
|
|
}
|
|
|
|
break;
|
|
case PacketType.ServerShutdown:
|
|
MainWindow.Instance.ShowDisconnectScreen("Сервер выключен: " +
|
|
((ServerShutdownPacket) packet).Reason);
|
|
_breakFlag = true;
|
|
break;
|
|
case PacketType.MessageReceivePacket:
|
|
ListBoxItem message = new ListBoxItem();
|
|
if (((MessageReceivePacket) packet).IsSystem)
|
|
{
|
|
message.Content = ((MessageReceivePacket) packet).Text;
|
|
}
|
|
else
|
|
{
|
|
message.Content = ((MessageReceivePacket) packet).Author + ": " +
|
|
((MessageReceivePacket) packet).Text;
|
|
}
|
|
|
|
switch (((MessageReceivePacket) packet).ChatType)
|
|
{
|
|
case ChatType.Queue:
|
|
AddMessageToChat("QueueChat",message);
|
|
break;
|
|
case ChatType.Active:
|
|
AddMessageToChat("GameVotingActiveChat",message);
|
|
break;
|
|
case ChatType.Day:
|
|
AddMessageToChat("GameDayChat",message);
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case PacketType.GameStartPacket:
|
|
List<Player> players = ((GameStartPacket) packet).Players;
|
|
switch (((GameStartPacket) packet).Role)
|
|
{
|
|
case Role.Citizen:
|
|
MainWindow.Instance.HideAll();
|
|
MainWindow.Instance.ShowVotingPassive("Ты Мирный Житель");
|
|
break;
|
|
case Role.Don:
|
|
MainWindow.Instance.HideAll();
|
|
List<ListBoxItem> items = new List<ListBoxItem>();
|
|
MainWindow.Instance.ShowVotingActive("Ты Дон, выбери кого убить!");
|
|
foreach (Player player in players)
|
|
{
|
|
ListBoxItem item = new ListBoxItem
|
|
{
|
|
Content = player.Id.ToString() + ") " + player.Name
|
|
};
|
|
items.Add(item);
|
|
}
|
|
|
|
MainWindow.Instance.FindControl<ListBox>("GameVotingActiveSelect").Items = items;
|
|
break;
|
|
case Role.Mafia:
|
|
MainWindow.Instance.HideAll();
|
|
items = new List<ListBoxItem>();
|
|
MainWindow.Instance.ShowVotingActive("Ты Мафия, выбери кого убить!");
|
|
foreach (Player player in players)
|
|
{
|
|
ListBoxItem item = new ListBoxItem
|
|
{
|
|
Content = player.Id.ToString() + ") " + player.Name
|
|
};
|
|
items.Add(item);
|
|
}
|
|
|
|
MainWindow.Instance.FindControl<ListBox>("GameVotingActiveSelect").Items = items;
|
|
break;
|
|
}
|
|
|
|
App.Instance.GetRpcClient().UpdateDetails("Ночь");
|
|
break;
|
|
case PacketType.EndGame:
|
|
MainWindow.Instance.ShowGameEnd(((EndGamePacket) packet).IsWon,
|
|
((EndGamePacket) packet).PlayerRoles);
|
|
App.Instance.GetRpcClient().UpdateDetails("Ожидание старта");
|
|
break;
|
|
case PacketType.GameStateChanged:
|
|
MainWindow.Instance.HideAll();
|
|
players = ((GameStageChangedPacket) packet).Players;
|
|
switch (((GameStageChangedPacket) packet).GameState)
|
|
{
|
|
case GameState.Day:
|
|
MainWindow.Instance.ShowDay(false, ((GameStageChangedPacket) packet).Role, players);
|
|
App.Instance.GetRpcClient().UpdateDetails("День");
|
|
break;
|
|
case GameState.VotingDay:
|
|
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:
|
|
String rol = ((GameStageChangedPacket) packet).Role == Role.Citizen
|
|
? "Мирный житель"
|
|
: "Мёртв";
|
|
MainWindow.Instance.ShowVotingPassive("Ты " + rol + "!");
|
|
break;
|
|
case Role.Mafia:
|
|
case Role.Don:
|
|
rol = ((GameStageChangedPacket) packet).Role == Role.Mafia
|
|
? "Мафия"
|
|
: "Дон";
|
|
List<ListBoxItem> items = new List<ListBoxItem>();
|
|
MainWindow.Instance.ShowVotingActive("Ты " + rol + ", выбери кого убить!");
|
|
foreach (Player player in players)
|
|
{
|
|
ListBoxItem item = new ListBoxItem
|
|
{
|
|
Content = player.Id.ToString() + ") " + player.Name
|
|
};
|
|
items.Add(item);
|
|
}
|
|
|
|
MainWindow.Instance.FindControl<ListBox>("GameVotingActiveSelect").Items = items;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
} |