using Fiesta.Config; using Fiesta.Networking.Packets; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using Villain.Networking.Packets; using Client = Fiesta.Networking.Client; using PacketHandler = Fiesta.Networking.Packets.PacketHandler; namespace World.Login { public static class InterLoginManager { private static byte _worldID; private static PacketHandler _packetHandler; private static ServerInfo.LoginServerInfo _loginServerInfo; private static Client _client; private static bool _hasLoaded = false; private static bool _hasStarted = false; private static bool _isStopping = false; public static void Load(byte worldID) { _worldID = worldID; if (!_hasLoaded) { _hasLoaded = true; try { _packetHandler = new PacketHandler("Login"); } catch (PacketHandlerException exception) { PacketHandlerAttribute attribute = (PacketHandlerAttribute)exception.Handler.Attribute; Console.WriteLine(exception.Message, ConsoleColor.Yellow); Console.WriteLine($"Handler For: {attribute.ForID}, Key: {attribute.Key}", ConsoleColor.Yellow); } } else { throw new Exception("InterLoginManager has already loaded"); } } public static void Start(ServerInfo.LoginServerInfo loginServerInfo) { if (!_hasStarted) { _hasStarted = true; _loginServerInfo = loginServerInfo; EstablishConnection(); } else { throw new Exception("InterLoginManager has already started"); } } public static void Stop() { if (_hasStarted && !_isStopping) { _isStopping = true; _packetHandler.Dispose(); _client?.Dispose(); _hasLoaded = false; _hasStarted = false; _isStopping = false; } } private static void EstablishConnection(Socket socket = null) { if (_hasStarted && !_isStopping) { if (socket == null) { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } socket.BeginConnect(new IPEndPoint(IPAddress.Parse(_loginServerInfo.Host), _loginServerInfo.Ports.Worlds), new AsyncCallback(Connect), socket); } } private static void Connect(IAsyncResult asyncResult) { Socket socket = (Socket)asyncResult.AsyncState; try { socket.EndConnect(asyncResult); _client = new Client(socket); _client.UseEncryption = false; _client.OnDisconnect = Disconnect; _client.OnRecieve = (packet) => { Recieve(_client, packet); }; _client.Send(new Networking.Packets.Misc.Out.Authentication(_worldID)); Console.WriteLine("Connected to Login"); } catch { EstablishConnection(socket); } } private static void Recieve(Client client, InPacket packet) { bool wasHandled = _packetHandler.Handle(client, packet); if (!wasHandled) { string raw = $"Type: 0x{packet.Type.ToString("X4")}, Size: 0x{packet.BinaryReader.BaseStream.Length.ToString("X4")}, Data: {BitConverter.ToString(((MemoryStream)packet.BinaryReader.BaseStream).ToArray())}"; Console.WriteLine($"Unhandled Login packet: {raw}"); packet.Dispose(); } } private static void Disconnect(Client client) { Console.WriteLine("Login disconnected"); EstablishConnection(); } } }