// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.Client.Library; using System; using System.Runtime.InteropServices; using System.Text; using MUnique.OpenMU.Network; using MUnique.OpenMU.Network.Packets.ClientToServer; using MUnique.OpenMU.Network.Xor; /// /// Extension methods to start writing messages of this namespace on a . /// public unsafe partial class ConnectionManager { private static readonly Xor3Encryptor Xor3Encryptor = new(0); /// /// Sends a to this connection. /// /// The handle of the connection. /// The user name, "encrypted" with Xor3. /// The password, "encrypted" with Xor3. /// The tick count. /// The client version. /// The client serial. /// /// Is sent by the client when: The player tries to log into the game. /// Causes reaction on server side: The server is authenticating the sent login name and password. If it's correct, the state of the player is proceeding to be logged in. /// [UnmanagedCallersOnly(EntryPoint = "ConnectionManager_SendLogin")] public static void SendLogin(int handle, IntPtr username, IntPtr password, uint @tickCount, byte* @clientVersion, byte* @clientSerial) { if (!Connections.TryGetValue(handle, out var connection)) { return; } try { var usernameStr = NativeInterop.PtrToWideString(@username); var passwordStr = NativeInterop.PtrToWideString(@password); // todo: check if username or password is too long connection.CreateAndSend(pipeWriter => { Span usernameBytes = stackalloc byte[10]; Span passwordBytes = stackalloc byte[20]; Encoding.UTF8.GetBytes(usernameStr, usernameBytes); Encoding.UTF8.GetBytes(passwordStr, passwordBytes); Xor3Encryptor.Encrypt(usernameBytes); Xor3Encryptor.Encrypt(passwordBytes); var length = LoginLongPasswordRef.Length; var packet = new LoginLongPasswordRef(pipeWriter.GetSpan(length)[..length]); usernameBytes.CopyTo(packet.Username); passwordBytes.CopyTo(packet.Password); packet.TickCount = @tickCount; new Span(@clientVersion, packet.ClientVersion.Length).CopyTo(packet.ClientVersion); new Span(@clientSerial, packet.ClientSerial.Length).CopyTo(packet.ClientSerial); return length; }); } catch { // Log exception } } }