fixed hint path

feature-npv2
NTAuthority 2014-07-10 01:14:58 +02:00
commit f26fcf5dfa
12 changed files with 121 additions and 56 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace NPSharp.Master.Data
{
public class MasterGetServersEntry
{
internal MasterGetServersEntry(byte[] data)
{
if (data.Length < 4 || data.Length % 2 > 0)
throw new ArgumentException("Data length must be at least 4 bytes of IP address and can afterwards only contain full 2 byte segments of ushort port data.");
IP = new IPAddress(data.Take(4).ToArray());
Ports = new ushort[(data.Length - 4) % sizeof(ushort)];
for (var i = 4; i < data.Length; i += sizeof(ushort))
{
Ports[(i - 4)/2] = (ushort) IPAddress.NetworkToHostOrder((short) BitConverter.ToUInt16(data, i));
}
}
internal MasterGetServersEntry(IPAddress ip, ushort[] ports)
{
IP = ip;
Ports = ports;
}
public IPAddress IP { get; private set; }
public ushort[] Ports { get; set; }
}
}

View File

@ -35,9 +35,8 @@ namespace NPSharp.Master.Messages.Client
protected override string Serialize() protected override string Serialize()
{ {
// I wonder if an extra useless space char at the end is okay in this case
return string.Format("{0} {1} {2} {3}", Name, GameName, ProtocolVersion, return string.Format("{0} {1} {2} {3}", Name, GameName, ProtocolVersion,
string.Join(" ", Keywords.Select(k => k.ToString()))); string.Join(" ", Keywords.Distinct().Select(k => k.ToString()))).TrimEnd();
} }
protected override void Deserialize(string[] arguments) protected override void Deserialize(string[] arguments)

View File

@ -108,6 +108,8 @@ namespace NPSharp.Master.Messages
return Name; return Name;
} }
protected abstract void Deserialize(string[] arguments); protected virtual void Deserialize(string[] arguments)
{
}
} }
} }

View File

@ -6,6 +6,7 @@ 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.Data;
using NPSharp.RPC.Messages.Server; using NPSharp.RPC.Messages.Server;
namespace NPSharp.NP namespace NPSharp.NP
@ -20,7 +21,8 @@ namespace NPSharp.NP
private readonly ushort _port; private readonly ushort _port;
private CancellationToken _cancellationToken; private CancellationToken _cancellationToken;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
private RPCClientStream _rpc;
public RPCClientStream RPC { get; private set; }
/// <summary> /// <summary>
/// Initializes the NP client with a specified host and port. /// Initializes the NP client with a specified host and port.
@ -37,7 +39,7 @@ namespace NPSharp.NP
/// <summary> /// <summary>
/// The internal RPC client. /// The internal RPC client.
/// </summary> /// </summary>
public RPCClientStream RPCClient { get { return _rpc; } } public RPCClientStream RPCClient { get; private set; }
/// <summary> /// <summary>
/// The assigned NP user ID. Will be set on successful authentication. /// The assigned NP user ID. Will be set on successful authentication.
@ -63,7 +65,7 @@ namespace NPSharp.NP
try try
{ {
_rpc = RPCClientStream.Open(_host, _port); RPC = RPCClientStream.Open(_host, _port);
} }
catch (Exception err) catch (Exception err)
{ {
@ -82,7 +84,7 @@ namespace NPSharp.NP
{ {
while (true) while (true)
{ {
if (_rpc.Read() == null) if (RPC.Read() == null)
break; break;
} }
} }
@ -91,6 +93,11 @@ namespace NPSharp.NP
_log.ErrorFormat("Protocol violation: {0}. Disconnect imminent.", error.Message); _log.ErrorFormat("Protocol violation: {0}. Disconnect imminent.", error.Message);
Disconnect(); Disconnect();
} }
catch (Exception error)
{
_log.ErrorFormat("Loop error in RPC read: {0}", error.ToString());
Disconnect();
}
_log.Debug("Now not receiving RPC messages anymore"); _log.Debug("Now not receiving RPC messages anymore");
}, _cancellationToken); }, _cancellationToken);
@ -109,7 +116,7 @@ namespace NPSharp.NP
_cancellationTokenSource.Cancel(true); _cancellationTokenSource.Cancel(true);
// TODO: Find a cleaner way to cancel _processingTask (focus: _rpc.Read) // TODO: Find a cleaner way to cancel _processingTask (focus: _rpc.Read)
//_procTask.Wait(_cancellationToken); //_procTask.Wait(_cancellationToken);
_rpc.Close(); RPC.Close();
LoginId = 0; LoginId = 0;
@ -127,7 +134,7 @@ namespace NPSharp.NP
{ {
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = packet as AuthenticateResultMessage; var result = packet as AuthenticateResultMessage;
if (result == null) if (result == null)
@ -139,7 +146,7 @@ namespace NPSharp.NP
SessionToken = result.SessionToken; SessionToken = result.SessionToken;
tcs.SetResult(true); tcs.SetResult(true);
}); });
_rpc.Send(new AuthenticateWithTokenMessage {Token = token}); RPC.Send(new AuthenticateWithTokenMessage {Token = token});
return await tcs.Task; return await tcs.Task;
} }
@ -154,7 +161,7 @@ namespace NPSharp.NP
{ {
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = packet as AuthenticateResultMessage; var result = packet as AuthenticateResultMessage;
if (result == null) if (result == null)
@ -171,31 +178,34 @@ namespace NPSharp.NP
SessionToken = result.SessionToken; SessionToken = result.SessionToken;
tcs.SetResult(true); tcs.SetResult(true);
}); });
_rpc.Send(new AuthenticateWithKeyMessage { LicenseKey = key }); RPC.Send(new AuthenticateWithKeyMessage { LicenseKey = key });
return await tcs.Task; return await tcs.Task;
} }
public async Task<bool> ValidateTicket(uint clientIP, ulong npID, byte[] ticket) /// <summary>
/// Authenticates a server ticket.
/// </summary>
/// <returns>True if the ticket validation succeeded, otherwise false.</returns>
public async Task<bool> ValidateTicket(IPAddress clientIP, Ticket ticket)
{ {
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = packet as AuthenticateValidateTicketResultMessage; var result = packet as AuthenticateValidateTicketResultMessage;
if (result == null) if (result == null)
return; return;
if (result.Result != 0) tcs.SetResult(result.Result == 0);
{ });
tcs.SetResult(false);
} RPC.Send(new AuthenticateValidateTicketMessage
else {
{ ClientIP = (uint)IPAddress.HostToNetworkOrder((int)BitConverter.ToUInt32(clientIP.GetAddressBytes(), 0)),
tcs.SetResult(true); Ticket = ticket.Serialize(),
} NPID = ticket.ClientID
}); });
_rpc.Send(new AuthenticateValidateTicketMessage { ClientIP = clientIP, Ticket = ticket, NPID = npID });
return await tcs.Task; return await tcs.Task;
} }
@ -211,14 +221,17 @@ namespace NPSharp.NP
{ {
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = (StorageWriteUserFileResultMessage) packet; var result = (StorageWriteUserFileResultMessage) packet;
if (result.Result != 0) if (result.Result != 0)
{
tcs.SetResult(false); tcs.SetResult(false);
return;
}
tcs.SetResult(true); tcs.SetResult(true);
}); });
_rpc.Send(new StorageWriteUserFileMessage {FileData = contents, FileName = filename, NPID = LoginId}); RPC.Send(new StorageWriteUserFileMessage {FileData = contents, FileName = filename, NPID = LoginId});
return await tcs.Task; return await tcs.Task;
} }
@ -232,7 +245,7 @@ namespace NPSharp.NP
{ {
var tcs = new TaskCompletionSource<byte[]>(); var tcs = new TaskCompletionSource<byte[]>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = (StorageUserFileMessage) packet; var result = (StorageUserFileMessage) packet;
if (result.Result != 0) if (result.Result != 0)
@ -242,7 +255,7 @@ namespace NPSharp.NP
} }
tcs.SetResult(result.FileData); tcs.SetResult(result.FileData);
}); });
_rpc.Send(new StorageGetUserFileMessage {FileName = filename, NPID = LoginId}); RPC.Send(new StorageGetUserFileMessage {FileName = filename, NPID = LoginId});
return await tcs.Task; return await tcs.Task;
} }
@ -270,7 +283,7 @@ namespace NPSharp.NP
{ {
var tcs = new TaskCompletionSource<byte[]>(); var tcs = new TaskCompletionSource<byte[]>();
_rpc.AttachHandlerForNextMessage(packet => RPC.AttachHandlerForNextMessage(packet =>
{ {
var result = (StoragePublisherFileMessage) packet; var result = (StoragePublisherFileMessage) packet;
if (result.Result != 0) if (result.Result != 0)
@ -280,7 +293,7 @@ namespace NPSharp.NP
} }
tcs.SetResult(result.FileData); tcs.SetResult(result.FileData);
}); });
_rpc.Send(new StorageGetPublisherFileMessage {FileName = filename}); RPC.Send(new StorageGetPublisherFileMessage {FileName = filename});
return await tcs.Task; return await tcs.Task;
} }
@ -299,7 +312,7 @@ namespace NPSharp.NP
public void SendRandomString(string data) public void SendRandomString(string data)
{ {
_rpc.Send(new StorageSendRandomStringMessage {RandomString = data}); RPC.Send(new StorageSendRandomStringMessage {RandomString = data});
} }
} }
} }

View File

@ -2,7 +2,7 @@
namespace NPSharp.NP namespace NPSharp.NP
{ {
internal class NpFileException : Exception public class NpFileException : Exception
{ {
internal NpFileException(int error) internal NpFileException(int error)
: base(error == 1 ? @"File not found on NP server" : @"Internal error on NP server") : base(error == 1 ? @"File not found on NP server" : @"Internal error on NP server")

View File

@ -33,12 +33,10 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net"> <Reference Include="log4net">
<HintPath>$(SolutionDir)\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
<HintPath>..\..\..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference> </Reference>
<Reference Include="protobuf-net"> <Reference Include="protobuf-net">
<HintPath>$(SolutionDir)\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll</HintPath>
<HintPath>..\..\..\..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -47,6 +45,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Authentication\SessionAuthenticationClient.cs" /> <Compile Include="Authentication\SessionAuthenticationClient.cs" />
<Compile Include="Authentication\SessionAuthenticationResult.cs" /> <Compile Include="Authentication\SessionAuthenticationResult.cs" />
<Compile Include="Master\Data\MasterGetServersEntry.cs" />
<Compile Include="Master\Data\MasterGetServersKeywords.cs" /> <Compile Include="Master\Data\MasterGetServersKeywords.cs" />
<Compile Include="Master\Messages\Client\MasterGetServersMessage.cs" /> <Compile Include="Master\Messages\Client\MasterGetServersMessage.cs" />
<Compile Include="Master\DedicatedServerEntry.cs" /> <Compile Include="Master\DedicatedServerEntry.cs" />

View File

@ -3,8 +3,15 @@ using System.IO;
namespace NPSharp.RPC.Messages.Data namespace NPSharp.RPC.Messages.Data
{ {
internal class Ticket /// <summary>
/// Represents a ticket which is used to validate client-to-gameserver connections.
/// </summary>
public class Ticket
{ {
/// <summary>
/// Reconstructs the ticket from raw byte data.
/// </summary>
/// <param name="data">The ticket's raw data</param>
public Ticket(byte[] data) public Ticket(byte[] data)
{ {
if (data.Length < sizeof (uint) + (sizeof (ulong)*2) + sizeof (uint)) 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 /// <summary>
public Ticket(uint version, ulong clientID, ulong serverID, uint? time = null) /// Constructs a ticket from given parameters.
/// </summary>
/// <param name="clientID">The client NPID</param>
/// <param name="serverID">The server NPID</param>
/// <param name="version">The ticket's structure version</param>
/// <param name="time">The ticket time</param>
public Ticket(ulong clientID, ulong serverID, uint version = 1, uint? time = null)
{ {
Version = version;
ClientID = clientID; ClientID = clientID;
ServerID = serverID; ServerID = serverID;
Version = version;
if (time.HasValue) if (time.HasValue)
Time = time.Value; Time = time.Value;
else else
Time = (uint) DateTime.Now.ToUniversalTime().ToBinary(); Time = (uint) DateTime.Now.ToUniversalTime().ToBinary();
} }
/// <summary>
/// Ticket structure version.
/// </summary>
public uint Version { get; private set; } public uint Version { get; private set; }
/// <summary>
/// The client's ID on the NP server.
/// </summary>
public ulong ClientID { get; private set; } public ulong ClientID { get; private set; }
/// <summary>
/// The gameserver's ID on the NP server.
/// </summary>
public ulong ServerID { get; private set; } public ulong ServerID { get; private set; }
/// <summary>
/// The creation time of the ticket.
/// </summary>
public uint Time { get; private set; } public uint Time { get; private set; }
public byte[] Serialize() internal byte[] Serialize()
{ {
using (var ms = new MemoryStream(sizeof (uint) + (sizeof (ulong)*2) + sizeof (uint))) using (var ms = new MemoryStream(sizeof (uint) + (sizeof (ulong)*2) + sizeof (uint)))
{ {

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using log4net;
using NPSharp.RPC.Messages; using NPSharp.RPC.Messages;
namespace NPSharp.RPC namespace NPSharp.RPC
@ -32,11 +31,6 @@ namespace NPSharp.RPC
protected readonly List<KeyValuePair<uint, Action<TRecv>>> TypeCallbacks = protected readonly List<KeyValuePair<uint, Action<TRecv>>> TypeCallbacks =
new List<KeyValuePair<uint, Action<TRecv>>>(); new List<KeyValuePair<uint, Action<TRecv>>>();
/// <summary>
/// Logger instance.
/// </summary>
private readonly ILog _log;
/// <summary> /// <summary>
/// ID of the next message. /// ID of the next message.
/// </summary> /// </summary>
@ -53,7 +47,6 @@ namespace NPSharp.RPC
/// <param name="sock">Client's network stream</param> /// <param name="sock">Client's network stream</param>
protected RPCStream(Socket sock) protected RPCStream(Socket sock)
{ {
_log = LogManager.GetLogger("RPC");
_sock = sock; _sock = sock;
} }
@ -138,7 +131,7 @@ namespace NPSharp.RPC
_sock.Send(buffer); _sock.Send(buffer);
if (typeof (TSend) == typeof (RPCClientMessage)) if (typeof(TSend) == typeof(RPCClientMessage))
IterateMessageID(); IterateMessageID();
} }

View File

@ -50,7 +50,7 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Web" /> <Reference Include="System.Web" />
<Reference Include="uhttpsharp"> <Reference Include="uhttpsharp">
<HintPath>..\..\packages\uHttpSharp.0.1.4.8\lib\net40\uhttpsharp.dll</HintPath> <HintPath>..\..\packages\uHttpSharp.0.1.5.2\lib\net40\uhttpsharp.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -3,5 +3,5 @@
<packages> <packages>
<package id="log4net" version="2.0.3" targetFramework="net45" /> <package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" /> <package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" />
<package id="uHttpSharp" version="0.1.4.8" targetFramework="net45" /> <package id="uHttpSharp" version="0.1.5.2" targetFramework="net45" />
</packages> </packages>

View File

@ -44,15 +44,14 @@
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>$(SolutionDir)\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="log4net"> <Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath> <HintPath>$(SolutionDir)\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference> </Reference>
<Reference Include="uhttpsharp, Version=0.1.5247.25275, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="uhttpsharp">
<SpecificVersion>False</SpecificVersion> <HintPath>..\..\packages\uHttpSharp.0.1.5.2\lib\net40\uhttpsharp.dll</HintPath>
<HintPath>..\..\packages\uHttpSharp.0.1.4.8\lib\net40\uhttpsharp.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -4,5 +4,5 @@
<package id="log4net" version="2.0.3" targetFramework="net45" /> <package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" /> <package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" /> <package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
<package id="uHttpSharp" version="0.1.4.8" targetFramework="net45" /> <package id="uHttpSharp" version="0.1.5.2" targetFramework="net45" />
</packages> </packages>