2025-12-19 17:54:50 +01:00
|
|
|
using System;
|
2026-03-21 21:23:33 +01:00
|
|
|
using System.Diagnostics;
|
2026-02-16 21:48:59 +01:00
|
|
|
using System.Linq;
|
2025-12-19 17:54:50 +01:00
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
2026-03-11 22:35:30 +01:00
|
|
|
using System.Threading;
|
2026-03-22 18:31:05 +01:00
|
|
|
using ONDClient.GUI;
|
2026-02-14 14:35:29 +01:00
|
|
|
using GlobalClassLib;
|
2025-12-19 17:54:50 +01:00
|
|
|
using LiteNetLib;
|
|
|
|
|
using LiteNetLib.Utils;
|
2026-03-22 18:31:05 +01:00
|
|
|
using ONDClient.Map;
|
2025-12-19 17:54:50 +01:00
|
|
|
using PacketLib;
|
|
|
|
|
|
2026-03-22 18:31:05 +01:00
|
|
|
namespace ONDClient;
|
2025-12-19 17:54:50 +01:00
|
|
|
|
2026-03-11 22:35:30 +01:00
|
|
|
public class Client {
|
|
|
|
|
public enum ConnectionState {
|
|
|
|
|
IDLE,
|
|
|
|
|
CONNECTING,
|
|
|
|
|
CONNECTED,
|
|
|
|
|
ACCEPTED,
|
|
|
|
|
GAME_STARTING,
|
2026-03-25 16:37:18 +01:00
|
|
|
DISCONNECTED,
|
2026-03-11 22:35:30 +01:00
|
|
|
GAME_IN_PROGRESS,
|
|
|
|
|
ERROR
|
2026-03-25 16:37:18 +01:00
|
|
|
}
|
|
|
|
|
public static string StatusText{ get; private set; }
|
2026-03-11 22:35:30 +01:00
|
|
|
|
2026-03-25 16:37:18 +01:00
|
|
|
public static ConnectionState State { get; set; } = ConnectionState.IDLE;
|
2026-03-11 22:35:30 +01:00
|
|
|
|
2025-12-19 17:54:50 +01:00
|
|
|
private static EventBasedNetListener listener = new();
|
|
|
|
|
private static NetManager client;
|
|
|
|
|
private static NetPeer server;
|
|
|
|
|
|
|
|
|
|
private static NetDataWriter writer;
|
|
|
|
|
private static NetPacketProcessor processor;
|
|
|
|
|
public static ClientPlayer Player { get; } = new();
|
2026-02-25 17:05:15 +01:00
|
|
|
public static ClientPlayer Opponent { get; } = new();
|
2025-12-19 17:54:50 +01:00
|
|
|
|
2026-02-25 17:05:15 +01:00
|
|
|
public static ClientPlayer GetPlayer(int pid) => Player.state.pid == pid ? Player : Opponent;
|
2026-03-21 21:23:33 +01:00
|
|
|
|
|
|
|
|
public static void Init() {
|
2025-12-19 17:54:50 +01:00
|
|
|
writer = new NetDataWriter();
|
|
|
|
|
processor = new NetPacketProcessor();
|
|
|
|
|
|
|
|
|
|
NestedTypeManager.AutoRegister(processor);
|
|
|
|
|
|
|
|
|
|
processor.SubscribeReusable<JoinAcceptPacket>(OnJoinAccept);
|
|
|
|
|
processor.SubscribeReusable<UpdatePlayerPacket>(OnPlayerUpdate);
|
2026-02-14 14:35:29 +01:00
|
|
|
processor.SubscribeReusable<MapInitPacket>(OnMapInit);
|
2026-03-11 22:35:30 +01:00
|
|
|
processor.SubscribeReusable<OpponentInitPacket>(packet => { // TODO: move this to a method
|
|
|
|
|
Opponent.state = packet.state;
|
|
|
|
|
Opponent.username = packet.username;
|
|
|
|
|
State = ConnectionState.GAME_STARTING;
|
|
|
|
|
});
|
2025-12-19 17:54:50 +01:00
|
|
|
|
|
|
|
|
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;
|
2026-03-11 22:35:30 +01:00
|
|
|
State = ConnectionState.CONNECTED;
|
|
|
|
|
SendPacket(new JoinPacket {username = Player.username == "" ? "Anonymous" : Player.username}, DeliveryMethod.ReliableOrdered);
|
2025-12-19 17:54:50 +01:00
|
|
|
};
|
2026-03-25 16:37:18 +01:00
|
|
|
|
|
|
|
|
listener.PeerDisconnectedEvent += (peer, info) => {
|
|
|
|
|
State = ConnectionState.IDLE;
|
|
|
|
|
Console.WriteLine("Disconnected from Server:\n" + info.Reason);
|
|
|
|
|
State = ConnectionState.DISCONNECTED;
|
|
|
|
|
StatusText = info.Reason.ToString();
|
|
|
|
|
};
|
2026-03-21 21:23:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Connect(string endPoint, int port) {
|
|
|
|
|
State = ConnectionState.CONNECTING;
|
|
|
|
|
|
|
|
|
|
client.Start();
|
|
|
|
|
Console.WriteLine($"Connecting to server @ {endPoint}:{port}");
|
2025-12-19 17:54:50 +01:00
|
|
|
|
2026-03-11 22:35:30 +01:00
|
|
|
new Thread(() => client.Connect(endPoint, port, "")).Start(); // TODO: figure out how keys work
|
2025-12-19 17:54:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2026-02-14 14:35:29 +01:00
|
|
|
|
|
|
|
|
private static void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) {
|
2025-12-19 17:54:50 +01:00
|
|
|
processor.ReadAllPackets(reader, peer);
|
|
|
|
|
}
|
2026-02-14 14:35:29 +01:00
|
|
|
|
|
|
|
|
private static void OnJoinAccept(JoinAcceptPacket packet) {
|
2025-12-19 17:54:50 +01:00
|
|
|
Console.WriteLine($"Accepted by server, pid: {packet.state.pid}");
|
2026-03-11 22:35:30 +01:00
|
|
|
State = ConnectionState.ACCEPTED;
|
2025-12-19 17:54:50 +01:00
|
|
|
Player.state = packet.state;
|
|
|
|
|
}
|
2026-02-14 14:35:29 +01:00
|
|
|
|
2026-03-12 22:33:35 +01:00
|
|
|
#nullable enable
|
2026-02-14 14:35:29 +01:00
|
|
|
private static void OnMapInit(MapInitPacket packet) {
|
2026-03-16 20:43:53 +01:00
|
|
|
ClientMapManager.InitMap(packet.Connectors, packet.YourTiles, packet.OpponentTiles, packet.LitTiles, packet.UpsideDown);
|
2026-02-14 14:35:29 +01:00
|
|
|
}
|
2025-12-19 17:54:50 +01:00
|
|
|
|
|
|
|
|
public static void Update() {
|
|
|
|
|
client.PollEvents();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-29 19:37:40 +01:00
|
|
|
public static void OnPlayerUpdate(UpdatePlayerPacket packet) { // TODO: move this to a separate class
|
2026-02-25 17:05:15 +01:00
|
|
|
EventProcessor.Evaluate(packet.events);
|
2025-12-19 17:54:50 +01:00
|
|
|
//Player.state = Player.state.pid == 0 ? packet.stateP1 : packet.stateP2;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-21 21:23:33 +01:00
|
|
|
public static void Disconnect() {
|
|
|
|
|
if (client == null || client.ConnectedPeersCount == 0) return;
|
|
|
|
|
client.DisconnectAll();
|
|
|
|
|
client.Stop();
|
|
|
|
|
State = ConnectionState.IDLE;
|
|
|
|
|
}
|
2025-12-19 17:54:50 +01:00
|
|
|
|
2026-03-21 21:23:33 +01:00
|
|
|
public static void StartServer() {
|
2026-03-22 18:31:05 +01:00
|
|
|
Process.Start("ONDServer");
|
2026-03-21 21:23:33 +01:00
|
|
|
// new Thread(() => Server.Start(9012)).Start();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 17:54:50 +01:00
|
|
|
}
|