diff --git a/src/client/NP/NPClient.cs b/src/client/NP/NPClient.cs
index e507850..78cc750 100644
--- a/src/client/NP/NPClient.cs
+++ b/src/client/NP/NPClient.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using log4net;
using NPSharp.RPC;
using NPSharp.RPC.Messages.Client;
+using NPSharp.RPC.Messages.Data;
using NPSharp.RPC.Messages.Server;
namespace NPSharp.NP
@@ -38,7 +39,7 @@ namespace NPSharp.NP
///
/// The internal RPC client.
///
- public RPCClientStream RPCClient { get { return _rpc; } }
+ public RPCClientStream RPCClient { get; private set; }
///
/// The assigned NP user ID. Will be set on successful authentication.
@@ -155,7 +156,7 @@ namespace NPSharp.NP
{
var tcs = new TaskCompletionSource();
- _rpc.AttachHandlerForNextMessage(packet =>
+ RPC.AttachHandlerForNextMessage(packet =>
{
var result = packet as AuthenticateResultMessage;
if (result == null)
@@ -172,31 +173,34 @@ namespace NPSharp.NP
SessionToken = result.SessionToken;
tcs.SetResult(true);
});
- _rpc.Send(new AuthenticateWithKeyMessage { LicenseKey = key });
+ RPC.Send(new AuthenticateWithKeyMessage { LicenseKey = key });
return await tcs.Task;
}
- public async Task ValidateTicket(uint clientIP, ulong npID, byte[] ticket)
+ ///
+ /// Authenticates a server ticket.
+ ///
+ /// True if the ticket validation succeeded, otherwise false.
+ public async Task ValidateTicket(IPAddress clientIP, Ticket ticket)
{
var tcs = new TaskCompletionSource();
- _rpc.AttachHandlerForNextMessage(packet =>
+ RPC.AttachHandlerForNextMessage(packet =>
{
var result = packet as AuthenticateValidateTicketResultMessage;
if (result == null)
return;
- if (result.Result != 0)
- {
- tcs.SetResult(false);
- }
- else
- {
- tcs.SetResult(true);
- }
+ tcs.SetResult(result.Result == 0);
+ });
+
+ RPC.Send(new AuthenticateValidateTicketMessage
+ {
+ ClientIP = (uint)IPAddress.HostToNetworkOrder((int)BitConverter.ToUInt32(clientIP.GetAddressBytes(), 0)),
+ Ticket = ticket.Serialize(),
+ NPID = ticket.ClientID
});
- _rpc.Send(new AuthenticateValidateTicketMessage { ClientIP = clientIP, Ticket = ticket, NPID = npID });
return await tcs.Task;
}
diff --git a/src/client/RPC/Messages/Data/Ticket.cs b/src/client/RPC/Messages/Data/Ticket.cs
index 0f79f3a..886a96b 100644
--- a/src/client/RPC/Messages/Data/Ticket.cs
+++ b/src/client/RPC/Messages/Data/Ticket.cs
@@ -3,8 +3,15 @@ using System.IO;
namespace NPSharp.RPC.Messages.Data
{
- internal class Ticket
+ ///
+ /// Represents a ticket which is used to validate client-to-gameserver connections.
+ ///
+ public class Ticket
{
+ ///
+ /// Reconstructs the ticket from raw byte data.
+ ///
+ /// The ticket's raw data
public Ticket(byte[] data)
{
if (data.Length < sizeof (uint) + (sizeof (ulong)*2) + sizeof (uint))
@@ -22,27 +29,45 @@ namespace NPSharp.RPC.Messages.Data
}
}
- // TODO: Maybe leave out arguments which are supposed to be autofilled
- public Ticket(uint version, ulong clientID, ulong serverID, uint? time = null)
+ ///
+ /// Constructs a ticket from given parameters.
+ ///
+ /// The client NPID
+ /// The server NPID
+ /// The ticket's structure version
+ /// The ticket time
+ public Ticket(ulong clientID, ulong serverID, uint version = 1, uint? time = null)
{
- Version = version;
ClientID = clientID;
ServerID = serverID;
+ Version = version;
if (time.HasValue)
Time = time.Value;
else
Time = (uint) DateTime.Now.ToUniversalTime().ToBinary();
}
+ ///
+ /// Ticket structure version.
+ ///
public uint Version { get; private set; }
+ ///
+ /// The client's ID on the NP server.
+ ///
public ulong ClientID { get; private set; }
+ ///
+ /// The gameserver's ID on the NP server.
+ ///
public ulong ServerID { get; private set; }
+ ///
+ /// The creation time of the ticket.
+ ///
public uint Time { get; private set; }
- public byte[] Serialize()
+ internal byte[] Serialize()
{
using (var ms = new MemoryStream(sizeof (uint) + (sizeof (ulong)*2) + sizeof (uint)))
{