OneNightDuel/ONDClient/Net/Client.cs

135 lines
4.3 KiB
C#
Raw Permalink Normal View History

using System;
using System.Diagnostics;
using System.Threading;
using LiteNetLib;
using LiteNetLib.Utils;
using ONDClient.Map;
using PacketLib;
namespace ONDClient.Net;
public static class Client {
public enum ConnectionState {
IDLE,
CONNECTING,
CONNECTED,
ACCEPTED,
GAME_STARTING,
DISCONNECTED,
GAME_IN_PROGRESS,
ERROR
}
public static string StatusText{ get; private set; }
public static ConnectionState State { get; set; } = ConnectionState.IDLE;
public static ClientPlayer Player { get; } = new();
public static ClientPlayer Opponent { get; } = new();
private static EventBasedNetListener listener = new();
private static NetManager client;
private static NetPeer server;
private static NetDataWriter writer;
private static NetPacketProcessor processor;
public static ClientPlayer GetPlayer(int pid) => Player.State.Pid == pid ? Player : Opponent;
public static void Init() {
writer = new NetDataWriter();
processor = new NetPacketProcessor();
NestedTypeManager.AutoRegister(processor);
processor.SubscribeReusable<JoinAcceptPacket>(OnJoinAccept);
processor.SubscribeReusable<UpdatePlayerPacket>(OnPlayerUpdate);
processor.SubscribeReusable<MapInitPacket>(OnMapInit);
processor.SubscribeReusable<OpponentInitPacket>(OnOpponentInit);
client = new NetManager(listener){
AutoRecycle = true
};
listener.NetworkReceiveEvent += (peer, reader, channel, method) => {
OnNetworkReceive(peer, reader, method);
};
listener.PeerConnectedEvent += peer => {
Console.WriteLine("Connected to Server");
server = peer;
State = ConnectionState.CONNECTED;
SendPacket(new JoinPacket {Username = Player.Username == "" ? "Anonymous" : Player.Username}, DeliveryMethod.ReliableOrdered);
};
listener.PeerDisconnectedEvent += (peer, info) => {
State = ConnectionState.IDLE;
Console.WriteLine("Disconnected from Server:\n" + info.Reason);
State = ConnectionState.DISCONNECTED;
StatusText = info.Reason.ToString();
};
}
public static void Connect(string endPoint, int port) {
State = ConnectionState.CONNECTING;
client.Start();
Console.WriteLine($"Connecting to server @ {endPoint}:{port}");
new Thread(() => client.Connect(endPoint, port, "")).Start();
}
public static void SendPacket<T>(T packet, DeliveryMethod deliveryMethod) where T : class, new() {
if (server != null) {
writer.Reset();
processor.Write(writer, packet);
server.Send(writer, deliveryMethod);
}
}
public static void SendCommands(PlayerCommand[] pCommands) {
SendPacket(new PlayerCommandPacket{Commands = pCommands}, DeliveryMethod.ReliableOrdered);
}
private static void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) {
processor.ReadAllPackets(reader, peer);
}
private static void OnJoinAccept(JoinAcceptPacket packet) {
Console.WriteLine($"Accepted by server, pid: {packet.State.Pid}");
State = ConnectionState.ACCEPTED;
Player.State = packet.State;
}
public static void Update() {
client.PollEvents();
}
public static void OnPlayerUpdate(UpdatePlayerPacket packet) {
EventProcessor.Evaluate(packet.Events);
}
public static void Disconnect() {
if (client == null || client.ConnectedPeersCount == 0) return;
client.DisconnectAll();
client.Stop();
State = ConnectionState.IDLE;
}
public static void StartServer() {
Process.Start("ONDServer");
}
#nullable enable
private static void OnMapInit(MapInitPacket packet) {
ClientMapManager.InitMap(packet.Connectors, packet.YourTiles, packet.OpponentTiles, packet.LitTiles, packet.UpsideDown);
}
private static void OnOpponentInit(OpponentInitPacket packet) {
Opponent.State = packet.State;
Opponent.Username = packet.Username;
State = ConnectionState.GAME_STARTING;
}
}