2023-10-09 21:52:00 +02:00
// <copyright file="ConnectionManager.ClientToServer.Custom.cs" company="MUnique">
2023-09-26 23:06:46 +02:00
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
2024-11-19 07:28:51 +01:00
namespace MUnique.Client.Library ;
2023-09-26 23:06:46 +02:00
using System ;
using System.Runtime.InteropServices ;
using System.Text ;
using MUnique.OpenMU.Network ;
using MUnique.OpenMU.Network.Packets.ClientToServer ;
2023-10-09 21:52:00 +02:00
using MUnique.OpenMU.Network.Xor ;
2023-09-26 23:06:46 +02:00
/// <summary>
/// Extension methods to start writing messages of this namespace on a <see cref="IConnection"/>.
/// </summary>
public unsafe partial class ConnectionManager
{
private static readonly Xor3Encryptor Xor3Encryptor = new ( 0 ) ;
/// <summary>
/// Sends a <see cref="LoginLongPassword" /> to this connection.
/// </summary>
/// <param name="handle">The handle of the connection.</param>
/// <param name="username">The user name, "encrypted" with Xor3.</param>
/// <param name="password">The password, "encrypted" with Xor3.</param>
/// <param name="tickCount">The tick count.</param>
/// <param name="clientVersion">The client version.</param>
/// <param name="clientSerial">The client serial.</param>
/// <remarks>
/// 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.
/// </remarks>
2024-11-19 07:28:51 +01:00
[UnmanagedCallersOnly(EntryPoint = "ConnectionManager_SendLogin")]
2023-10-04 07:38:19 +02:00
public static void SendLogin ( int handle , IntPtr username , IntPtr password , uint @tickCount , byte * @clientVersion , byte * @clientSerial )
2023-09-26 23:06:46 +02:00
{
if ( ! Connections . TryGetValue ( handle , out var connection ) )
{
return ;
}
try
{
var usernameStr = Marshal . PtrToStringAuto ( @username ) ;
var passwordStr = Marshal . PtrToStringAuto ( @password ) ;
// todo: check if username or password is too long
connection . CreateAndSend ( pipeWriter = >
{
Span < byte > usernameBytes = stackalloc byte [ 10 ] ;
Span < byte > 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 < byte > ( @clientVersion , packet . ClientVersion . Length ) . CopyTo ( packet . ClientVersion ) ;
new Span < byte > ( @clientSerial , packet . ClientSerial . Length ) . CopyTo ( packet . ClientSerial ) ;
return length ;
} ) ;
}
catch
{
// Log exception
}
}
}