using System; using System.Linq; using System.Net; using System.Net.Sockets; using FNAF_Clone.GUI; using FNAF_Clone.Map; using GlobalClassLib; using LiteNetLib; using LiteNetLib.Utils; using PacketLib; namespace FNAF_Clone; public class Client { 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(); public static ClientPlayer Opponent { get; } = new(); public static ClientPlayer GetPlayer(int pid) => Player.state.pid == pid ? Player : Opponent; public static void Connect(string endPoint, int port) { writer = new NetDataWriter(); processor = new NetPacketProcessor(); NestedTypeManager.AutoRegister(processor); processor.SubscribeReusable(OnJoinAccept); processor.SubscribeReusable(OnPlayerUpdate); processor.SubscribeReusable(OnMapInit); processor.SubscribeReusable(packet => Opponent.state = packet.state); client = new NetManager(listener){ AutoRecycle = true }; client.Start(); Console.WriteLine($"Connecting to server @ {endPoint}:{port}"); listener.NetworkReceiveEvent += (peer, reader, channel, method) => { OnNetworkReceive(peer, reader, method); }; listener.PeerConnectedEvent += peer => { Console.WriteLine("Connected to Server"); server = peer; SendPacket(new JoinPacket {username = "Player1"}, DeliveryMethod.ReliableOrdered); }; client.Connect(endPoint, port, ""); // TODO: figure out how keys work } public static void SendPacket(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}"); Player.state = packet.state; } private static void OnMapInit(MapInitPacket packet) { (int id1, int id2, ConnectorType type)[] connectorsData = new (int id1, int id2, ConnectorType type)[packet.Connectors.Length / 3]; for (int i = 0; i < packet.Connectors.Length / 3; i++){ connectorsData[i] = (packet.Connectors[i * 3], packet.Connectors[i * 3 + 1], (ConnectorType)packet.Connectors[i * 3 + 2]); } ClientMapManager.InitMap(packet.UpsideDown); TileConnectorProjection[] connectors = connectorsData.Select(c => new TileConnectorProjection(ClientMapManager.Get(c.id1), ClientMapManager.Get(c.id2), c.type)).ToArray(); ClientMapManager.InitConnectors(connectors); UIManager.InitUI(); UIManager.SpawnDoors(connectors.Where(c => c.Type == ConnectorType.DOOR_REMOTE).ToArray()); } public static void Update() { client.PollEvents(); } public static void OnPlayerUpdate(UpdatePlayerPacket packet) { // TODO: move this to a separate class EventProcessor.Evaluate(packet.events); //Player.state = Player.state.pid == 0 ? packet.stateP1 : packet.stateP2; } }