mirror of https://github.com/icedream/npsharp.git
add validateticket call
parent
612fd05702
commit
ac7e1b1a78
|
@ -1,147 +1,147 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using log4net;
|
using log4net;
|
||||||
using NPSharp.RPC;
|
using NPSharp.RPC;
|
||||||
using NPSharp.RPC.Messages.Client;
|
using NPSharp.RPC.Messages.Client;
|
||||||
using NPSharp.RPC.Messages.Server;
|
using NPSharp.RPC.Messages.Server;
|
||||||
|
|
||||||
namespace NPSharp.NP
|
namespace NPSharp.NP
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a high-level network platform client.
|
/// Represents a high-level network platform client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NPClient
|
public class NPClient
|
||||||
{
|
{
|
||||||
private readonly string _host;
|
private readonly string _host;
|
||||||
private readonly ILog _log;
|
private readonly ILog _log;
|
||||||
private readonly ushort _port;
|
private readonly ushort _port;
|
||||||
private CancellationToken _cancellationToken;
|
private CancellationToken _cancellationToken;
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
private RPCClientStream _rpc;
|
private RPCClientStream _rpc;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the NP client with a specified host and port.
|
/// Initializes the NP client with a specified host and port.
|
||||||
/// </summary>
|
|
||||||
/// <param name="host">The host to connect to.</param>
|
|
||||||
/// <param name="port">The port to use. Default: 3025.</param>
|
|
||||||
public NPClient(string host, ushort port = 3025)
|
|
||||||
{
|
|
||||||
_host = host;
|
|
||||||
_port = port;
|
|
||||||
_log = LogManager.GetLogger("NPClient");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The internal RPC client.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RPCClientStream RPCClient { get { return _rpc; } }
|
/// <param name="host">The host to connect to.</param>
|
||||||
|
/// <param name="port">The port to use. Default: 3025.</param>
|
||||||
/// <summary>
|
public NPClient(string host, ushort port = 3025)
|
||||||
/// The assigned NP user ID. Will be set on successful authentication.
|
{
|
||||||
/// </summary>
|
_host = host;
|
||||||
public ulong LoginId { get; private set; }
|
_port = port;
|
||||||
|
_log = LogManager.GetLogger("NPClient");
|
||||||
/// <summary>
|
}
|
||||||
/// The assigned session token for this client. Will be set on successful authentication.
|
|
||||||
/// </summary>
|
/// <summary>
|
||||||
public string SessionToken { get; private set; }
|
/// The internal RPC client.
|
||||||
|
/// </summary>
|
||||||
// TODO: Handle connection failures via exception
|
public RPCClientStream RPCClient { get { return _rpc; } }
|
||||||
/// <summary>
|
|
||||||
/// Connects the client to the NP server.
|
/// <summary>
|
||||||
/// </summary>
|
/// The assigned NP user ID. Will be set on successful authentication.
|
||||||
/// <returns>True if the connection succeeded, otherwise false.</returns>
|
/// </summary>
|
||||||
public bool Connect()
|
public ulong LoginId { get; private set; }
|
||||||
{
|
|
||||||
_log.Debug("Connect() start");
|
/// <summary>
|
||||||
|
/// The assigned session token for this client. Will be set on successful authentication.
|
||||||
_cancellationTokenSource = new CancellationTokenSource();
|
/// </summary>
|
||||||
_cancellationToken = _cancellationTokenSource.Token;
|
public string SessionToken { get; private set; }
|
||||||
|
|
||||||
try
|
// TODO: Handle connection failures via exception
|
||||||
{
|
/// <summary>
|
||||||
_rpc = RPCClientStream.Open(_host, _port);
|
/// Connects the client to the NP server.
|
||||||
}
|
/// </summary>
|
||||||
catch (Exception err)
|
/// <returns>True if the connection succeeded, otherwise false.</returns>
|
||||||
{
|
public bool Connect()
|
||||||
#if DEBUG
|
{
|
||||||
_log.ErrorFormat(@"Could not initialize RPC: {0}", err);
|
_log.Debug("Connect() start");
|
||||||
#else
|
|
||||||
_log.ErrorFormat(@"Could not initialize RPC: {0}", err.Message);
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
#endif
|
_cancellationToken = _cancellationTokenSource.Token;
|
||||||
return false;
|
|
||||||
}
|
try
|
||||||
|
{
|
||||||
Task.Factory.StartNew(() =>
|
_rpc = RPCClientStream.Open(_host, _port);
|
||||||
{
|
}
|
||||||
_log.Debug("Now receiving RPC messages");
|
catch (Exception err)
|
||||||
try
|
{
|
||||||
{
|
#if DEBUG
|
||||||
while (true)
|
_log.ErrorFormat(@"Could not initialize RPC: {0}", err);
|
||||||
{
|
#else
|
||||||
if (_rpc.Read() == null)
|
_log.ErrorFormat(@"Could not initialize RPC: {0}", err.Message);
|
||||||
break;
|
#endif
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
catch (ProtocolViolationException error)
|
|
||||||
{
|
Task.Factory.StartNew(() =>
|
||||||
_log.ErrorFormat("Protocol violation: {0}. Disconnect imminent.", error.Message);
|
{
|
||||||
Disconnect();
|
_log.Debug("Now receiving RPC messages");
|
||||||
}
|
try
|
||||||
|
{
|
||||||
_log.Debug("Now not receiving RPC messages anymore");
|
while (true)
|
||||||
}, _cancellationToken);
|
{
|
||||||
|
if (_rpc.Read() == null)
|
||||||
_log.Debug("Connect() done");
|
break;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
catch (ProtocolViolationException error)
|
||||||
/// <summary>
|
{
|
||||||
/// Disconnects the client from the NP server.
|
_log.ErrorFormat("Protocol violation: {0}. Disconnect imminent.", error.Message);
|
||||||
/// </summary>
|
Disconnect();
|
||||||
public void Disconnect()
|
}
|
||||||
{
|
|
||||||
_log.Debug("Disconnect() start");
|
_log.Debug("Now not receiving RPC messages anymore");
|
||||||
|
}, _cancellationToken);
|
||||||
_cancellationTokenSource.Cancel(true);
|
|
||||||
// TODO: Find a cleaner way to cancel _processingTask (focus: _rpc.Read)
|
_log.Debug("Connect() done");
|
||||||
//_procTask.Wait(_cancellationToken);
|
return true;
|
||||||
_rpc.Close();
|
}
|
||||||
|
|
||||||
LoginId = 0;
|
/// <summary>
|
||||||
|
/// Disconnects the client from the NP server.
|
||||||
_log.Debug("Disconnect() done");
|
/// </summary>
|
||||||
}
|
public void Disconnect()
|
||||||
|
{
|
||||||
// TODO: Try to use an exception for failed action instead
|
_log.Debug("Disconnect() start");
|
||||||
/// <summary>
|
|
||||||
/// Authenticates this connection via a token. This token has to be requested via an external interface like
|
_cancellationTokenSource.Cancel(true);
|
||||||
/// remauth.php.
|
// TODO: Find a cleaner way to cancel _processingTask (focus: _rpc.Read)
|
||||||
/// </summary>
|
//_procTask.Wait(_cancellationToken);
|
||||||
/// <param name="token">The token to use for authentication</param>
|
_rpc.Close();
|
||||||
/// <returns>True if the login succeeded, otherwise false.</returns>
|
|
||||||
public async Task<bool> AuthenticateWithToken(string token)
|
LoginId = 0;
|
||||||
{
|
|
||||||
var tcs = new TaskCompletionSource<bool>();
|
_log.Debug("Disconnect() done");
|
||||||
|
}
|
||||||
_rpc.AttachHandlerForNextMessage(packet =>
|
|
||||||
{
|
// TODO: Try to use an exception for failed action instead
|
||||||
var result = packet as AuthenticateResultMessage;
|
/// <summary>
|
||||||
if (result == null)
|
/// Authenticates this connection via a token. This token has to be requested via an external interface like
|
||||||
return;
|
/// remauth.php.
|
||||||
|
/// </summary>
|
||||||
if (result.Result != 0)
|
/// <param name="token">The token to use for authentication</param>
|
||||||
tcs.SetResult(false);
|
/// <returns>True if the login succeeded, otherwise false.</returns>
|
||||||
LoginId = result.NPID;
|
public async Task<bool> AuthenticateWithToken(string token)
|
||||||
SessionToken = result.SessionToken;
|
{
|
||||||
tcs.SetResult(true);
|
var tcs = new TaskCompletionSource<bool>();
|
||||||
});
|
|
||||||
_rpc.Send(new AuthenticateWithTokenMessage {Token = token});
|
_rpc.AttachHandlerForNextMessage(packet =>
|
||||||
|
{
|
||||||
return await tcs.Task;
|
var result = packet as AuthenticateResultMessage;
|
||||||
|
if (result == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result.Result != 0)
|
||||||
|
tcs.SetResult(false);
|
||||||
|
LoginId = result.NPID;
|
||||||
|
SessionToken = result.SessionToken;
|
||||||
|
tcs.SetResult(true);
|
||||||
|
});
|
||||||
|
_rpc.Send(new AuthenticateWithTokenMessage {Token = token});
|
||||||
|
|
||||||
|
return await tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -161,7 +161,12 @@ namespace NPSharp.NP
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (result.Result != 0)
|
if (result.Result != 0)
|
||||||
|
{
|
||||||
tcs.SetResult(false);
|
tcs.SetResult(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LoginId = result.NPID;
|
LoginId = result.NPID;
|
||||||
SessionToken = result.SessionToken;
|
SessionToken = result.SessionToken;
|
||||||
tcs.SetResult(true);
|
tcs.SetResult(true);
|
||||||
|
@ -169,108 +174,132 @@ namespace NPSharp.NP
|
||||||
_rpc.Send(new AuthenticateWithKeyMessage { LicenseKey = key });
|
_rpc.Send(new AuthenticateWithKeyMessage { LicenseKey = key });
|
||||||
|
|
||||||
return await tcs.Task;
|
return await tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Try to use an exception for failed action instead
|
public async Task<bool> ValidateTicket(uint clientIP, ulong npID, byte[] ticket)
|
||||||
/// <summary>
|
{
|
||||||
/// Uploads a user file.
|
var tcs = new TaskCompletionSource<bool>();
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The file name to save the contents to on the server</param>
|
_rpc.AttachHandlerForNextMessage(packet =>
|
||||||
/// <param name="contents">The raw byte contents</param>
|
{
|
||||||
/// <returns>True if the upload succeeded, otherwise false.</returns>
|
var result = packet as AuthenticateValidateTicketResultMessage;
|
||||||
public async Task<bool> UploadUserFile(string filename, byte[] contents)
|
if (result == null)
|
||||||
{
|
return;
|
||||||
var tcs = new TaskCompletionSource<bool>();
|
|
||||||
|
if (result.Result != 0)
|
||||||
_rpc.AttachHandlerForNextMessage(packet =>
|
{
|
||||||
{
|
tcs.SetResult(false);
|
||||||
var result = (StorageWriteUserFileResultMessage) packet;
|
}
|
||||||
if (result.Result != 0)
|
else
|
||||||
tcs.SetResult(false);
|
{
|
||||||
tcs.SetResult(true);
|
tcs.SetResult(true);
|
||||||
});
|
}
|
||||||
_rpc.Send(new StorageWriteUserFileMessage {FileData = contents, FileName = filename, NPID = LoginId});
|
});
|
||||||
|
_rpc.Send(new AuthenticateValidateTicketMessage { ClientIP = clientIP, Ticket = ticket, NPID = npID });
|
||||||
return await tcs.Task;
|
|
||||||
}
|
return await tcs.Task;
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// Downloads a user file and returns its contents.
|
// TODO: Try to use an exception for failed action instead
|
||||||
/// </summary>
|
/// <summary>
|
||||||
/// <param name="filename">The file to download</param>
|
/// Uploads a user file.
|
||||||
/// <returns>File contents as byte array</returns>
|
/// </summary>
|
||||||
public async Task<byte[]> GetUserFile(string filename)
|
/// <param name="filename">The file name to save the contents to on the server</param>
|
||||||
{
|
/// <param name="contents">The raw byte contents</param>
|
||||||
var tcs = new TaskCompletionSource<byte[]>();
|
/// <returns>True if the upload succeeded, otherwise false.</returns>
|
||||||
|
public async Task<bool> UploadUserFile(string filename, byte[] contents)
|
||||||
_rpc.AttachHandlerForNextMessage(packet =>
|
{
|
||||||
{
|
var tcs = new TaskCompletionSource<bool>();
|
||||||
var result = (StorageUserFileMessage) packet;
|
|
||||||
if (result.Result != 0)
|
_rpc.AttachHandlerForNextMessage(packet =>
|
||||||
{
|
{
|
||||||
tcs.SetException(new NpFileException(result.Result));
|
var result = (StorageWriteUserFileResultMessage) packet;
|
||||||
return;
|
if (result.Result != 0)
|
||||||
}
|
tcs.SetResult(false);
|
||||||
tcs.SetResult(result.FileData);
|
tcs.SetResult(true);
|
||||||
});
|
});
|
||||||
_rpc.Send(new StorageGetUserFileMessage {FileName = filename, NPID = LoginId});
|
_rpc.Send(new StorageWriteUserFileMessage {FileData = contents, FileName = filename, NPID = LoginId});
|
||||||
|
|
||||||
return await tcs.Task;
|
return await tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// Downloads a user file and returns its contents.
|
||||||
/// Downloads a user file onto the harddisk.
|
/// </summary>
|
||||||
/// </summary>
|
/// <param name="filename">The file to download</param>
|
||||||
/// <param name="filename">The file to download</param>
|
/// <returns>File contents as byte array</returns>
|
||||||
/// <param name="targetpath">Path where to save the file</param>
|
public async Task<byte[]> GetUserFile(string filename)
|
||||||
public async void DownloadUserFileTo(string filename, string targetpath)
|
{
|
||||||
{
|
var tcs = new TaskCompletionSource<byte[]>();
|
||||||
var contents = await GetUserFile(filename);
|
|
||||||
|
_rpc.AttachHandlerForNextMessage(packet =>
|
||||||
File.WriteAllBytes(targetpath, contents);
|
{
|
||||||
}
|
var result = (StorageUserFileMessage) packet;
|
||||||
|
if (result.Result != 0)
|
||||||
|
{
|
||||||
/// <summary>
|
tcs.SetException(new NpFileException(result.Result));
|
||||||
/// Downloads a publisher file and returns its contents.
|
return;
|
||||||
/// </summary>
|
}
|
||||||
/// <param name="filename">The file to download</param>
|
tcs.SetResult(result.FileData);
|
||||||
/// <returns>File contents as byte array</returns>
|
});
|
||||||
public async Task<byte[]> GetPublisherFile(string filename)
|
_rpc.Send(new StorageGetUserFileMessage {FileName = filename, NPID = LoginId});
|
||||||
{
|
|
||||||
var tcs = new TaskCompletionSource<byte[]>();
|
return await tcs.Task;
|
||||||
|
}
|
||||||
_rpc.AttachHandlerForNextMessage(packet =>
|
|
||||||
{
|
|
||||||
var result = (StoragePublisherFileMessage) packet;
|
/// <summary>
|
||||||
if (result.Result != 0)
|
/// Downloads a user file onto the harddisk.
|
||||||
{
|
/// </summary>
|
||||||
tcs.SetException(new NpFileException(result.Result));
|
/// <param name="filename">The file to download</param>
|
||||||
return;
|
/// <param name="targetpath">Path where to save the file</param>
|
||||||
}
|
public async void DownloadUserFileTo(string filename, string targetpath)
|
||||||
tcs.SetResult(result.FileData);
|
{
|
||||||
});
|
var contents = await GetUserFile(filename);
|
||||||
_rpc.Send(new StorageGetPublisherFileMessage {FileName = filename});
|
|
||||||
|
File.WriteAllBytes(targetpath, contents);
|
||||||
return await tcs.Task;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Downloads a publisher file onto the harddisk.
|
/// Downloads a publisher file and returns its contents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">The file to download</param>
|
/// <param name="filename">The file to download</param>
|
||||||
/// <param name="targetpath">Path where to save the file</param>
|
/// <returns>File contents as byte array</returns>
|
||||||
public async void DownloadPublisherFileTo(string filename, string targetpath)
|
public async Task<byte[]> GetPublisherFile(string filename)
|
||||||
{
|
{
|
||||||
var contents = await GetPublisherFile(filename);
|
var tcs = new TaskCompletionSource<byte[]>();
|
||||||
|
|
||||||
File.WriteAllBytes(targetpath, contents);
|
_rpc.AttachHandlerForNextMessage(packet =>
|
||||||
}
|
{
|
||||||
|
var result = (StoragePublisherFileMessage) packet;
|
||||||
public void SendRandomString(string data)
|
if (result.Result != 0)
|
||||||
{
|
{
|
||||||
_rpc.Send(new StorageSendRandomStringMessage {RandomString = data});
|
tcs.SetException(new NpFileException(result.Result));
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
tcs.SetResult(result.FileData);
|
||||||
|
});
|
||||||
|
_rpc.Send(new StorageGetPublisherFileMessage {FileName = filename});
|
||||||
|
|
||||||
|
return await tcs.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Downloads a publisher file onto the harddisk.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The file to download</param>
|
||||||
|
/// <param name="targetpath">Path where to save the file</param>
|
||||||
|
public async void DownloadPublisherFileTo(string filename, string targetpath)
|
||||||
|
{
|
||||||
|
var contents = await GetPublisherFile(filename);
|
||||||
|
|
||||||
|
File.WriteAllBytes(targetpath, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendRandomString(string data)
|
||||||
|
{
|
||||||
|
_rpc.Send(new StorageSendRandomStringMessage {RandomString = data});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue