diff --git a/libnpsharp.sln b/libnpsharp.sln
index 0ce2d38..26f0ce2 100644
--- a/libnpsharp.sln
+++ b/libnpsharp.sln
@@ -18,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F8
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPSharp.Client", "src\client\NPSharp.Client.csproj", "{C6F941A5-82AF-456A-9B3A-752E5B001035}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPSharp.Server", "src\server\NPSharp.Server.csproj", "{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/src/server/Authentication/SessionAuthenticationServer.cs b/src/server/Authentication/SessionAuthenticationServer.cs
deleted file mode 100644
index ace5a6f..0000000
--- a/src/server/Authentication/SessionAuthenticationServer.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading.Tasks;
-using log4net;
-using uhttpsharp;
-using uhttpsharp.Handlers;
-using uhttpsharp.Headers;
-using uhttpsharp.Listeners;
-using uhttpsharp.RequestProviders;
-
-namespace NPSharp.Authentication
-{
- ///
- /// Represents a session authentication server which uses the HTTP protocol to send out session tokens to
- /// authenticating NP clients.
- ///
- public class SessionAuthenticationServer
- {
- private readonly ILog _log;
- private HttpServer _http;
-
- ///
- /// Constructs a new session authentication server.
- ///
- public SessionAuthenticationServer()
- {
- SupportOldAuthentication = true;
- _log = LogManager.GetLogger("Auth");
- }
-
- ///
- /// Support oldskool "user&&pass" authentication format.
- ///
- public bool SupportOldAuthentication { get; set; }
-
- ///
- /// Will be triggered whenever a client tries to authenticate via this server.
- ///
- public event Func Authenticating;
-
- protected virtual SessionAuthenticationResult OnAuthenticating(string username, string password)
- {
- var handler = Authenticating;
- return handler != null
- ? handler(username, password)
- : new SessionAuthenticationResult {Reason = "Login currently disabled"};
- }
-
- ///
- /// Starts the authentication server.
- ///
- /// The port on which the authentication server should listen on.
- public void Start(ushort port = 12003)
- {
- if (_http != null)
- {
- throw new InvalidOperationException("This server is already running");
- }
-
- _log.Debug("Starting authentication server...");
- _http = new HttpServer(new HttpRequestProvider());
- _http.Use(new TcpListenerAdapter(new TcpListener(IPAddress.Any, port)));
- _http.Use(new TcpListenerAdapter(new TcpListener(IPAddress.IPv6Any, port)));
- _http.Use(new HttpRouter().With("authenticate", new AuthenticateHandler(this)));
- _http.Use(new AnonymousHttpRequestHandler((ctx, task) =>
- {
- ctx.Response = HttpResponse.CreateWithMessage(HttpResponseCode.NotFound, "Not found",
- ctx.Request.Headers.KeepAliveConnection());
- return Task.Factory.GetCompleted();
- }));
- _http.Start();
- _log.Debug("Done starting authentication server.");
- }
-
- ///
- /// Stops the authentication server.
- ///
- public void Stop()
- {
- _http.Dispose();
- }
-
- protected class AuthenticateHandler : IHttpRequestHandler
- {
- private readonly SessionAuthenticationServer _authServer;
-
- public AuthenticateHandler(SessionAuthenticationServer sessionAuthenticationServer)
- {
- _authServer = sessionAuthenticationServer;
- }
-
- public Task Handle(IHttpContext context, Func next)
- {
- SessionAuthenticationResult sar;
-
- string username;
- string password;
-
- if (!context.Request.Post.Parsed.TryGetByName("user", out username) ||
- !context.Request.Post.Parsed.TryGetByName("pass", out password))
- {
- var login = Encoding.UTF8.GetString(context.Request.Post.Raw)
- .Split(new[] {"&&"}, StringSplitOptions.None);
- if (login.Length != 2)
- {
- sar = new SessionAuthenticationResult {Reason = @"Invalid login data"};
-
- context.Response = new HttpResponse(HttpResponseCode.Ok, sar.ToString(),
- context.Request.Headers.KeepAliveConnection());
- return Task.Factory.GetCompleted();
- }
-
- username = login[0];
- password = login[1];
- }
-
- try
- {
- sar = _authServer.OnAuthenticating(username, password);
- }
- catch (Exception error)
- {
- _authServer._log.Error(@"Authentication handler error", error);
- sar = new SessionAuthenticationResult {Reason = @"Internal server error"};
- }
-
- _authServer._log.DebugFormat("/authenticate reply is {0}", sar);
-
- context.Response = new HttpResponse(HttpResponseCode.Ok, sar.ToString(),
- !sar.Success && context.Request.Headers.KeepAliveConnection());
- return Task.Factory.GetCompleted();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/server/Events/ClientEventArgs.cs b/src/server/Events/ClientEventArgs.cs
deleted file mode 100644
index 7abadbc..0000000
--- a/src/server/Events/ClientEventArgs.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using NPSharp.NP;
-
-namespace NPSharp.Events
-{
- public class ClientEventArgs : EventArgs
- {
- internal ClientEventArgs(NPServerClient client)
- {
- Client = client;
- }
-
- public NPServerClient Client { get; private set; }
- }
-}
\ No newline at end of file
diff --git a/src/server/Events/ClientEventHandler.cs b/src/server/Events/ClientEventHandler.cs
deleted file mode 100644
index f46d5f5..0000000
--- a/src/server/Events/ClientEventHandler.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using NPSharp.NP;
-
-namespace NPSharp.Events
-{
- ///
- /// A delegate for all general client-related events.
- ///
- /// The instance of the NP server
- /// All related arguments to this event
- public delegate void ClientEventHandler(NPServer sender, ClientEventArgs args);
-}
\ No newline at end of file
diff --git a/src/server/Handlers/IAuthenticationHandler.cs b/src/server/Handlers/IAuthenticationHandler.cs
deleted file mode 100644
index 865e2f1..0000000
--- a/src/server/Handlers/IAuthenticationHandler.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using NPSharp.NP;
-using NPSharp.RPC.Messages.Data;
-
-namespace NPSharp.Handlers
-{
- ///
- /// Represents a handler for all authentication-related requests.
- ///
- public interface IAuthenticationHandler
- {
- ///
- /// Authenticates a user based on username and password.
- ///
- /// The NP server client to authenticate
- /// The username to use for authentication
- /// The password to use for authentication
- /// An instance of
- NPAuthenticationResult AuthenticateUser(NPServerClient client, string username, string password);
-
- ///
- /// Authenticates a user based on a session token.
- ///
- /// The NP server client to authenticate
- /// The session token to use for authentication
- /// An instance of
- NPAuthenticationResult AuthenticateUser(NPServerClient client, string token);
-
- ///
- /// Authenticates a dedicated server based on its license key.
- ///
- /// The NP server client of the dedicated server to authenticate
- /// The license key to use for authentication
- /// An instance of
- NPAuthenticationResult AuthenticateServer(NPServerClient client, string licenseKey);
-
- ///
- /// Validates a ticket.
- ///
- /// The NP server client of the user who is trying to get the ticket validated
- /// The server that the user wants to connect to using this ticket
- /// A determining if the ticket is valid
- TicketValidationResult ValidateTicket(NPServerClient client, NPServerClient server);
- }
-}
\ No newline at end of file
diff --git a/src/server/Handlers/IFileServingHandler.cs b/src/server/Handlers/IFileServingHandler.cs
deleted file mode 100644
index 4de4e9c..0000000
--- a/src/server/Handlers/IFileServingHandler.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using NPSharp.NP;
-
-namespace NPSharp.Handlers
-{
- ///
- /// Represents a handler for all file-related requests.
- ///
- public interface IFileServingHandler
- {
- ///
- /// Reads a file assigned to the user.
- ///
- /// The file contents as byte array or null if the file could not be read, opened or generated
- /// NP server client of the user
- /// The file name
- byte[] ReadUserFile(NPServerClient client, string file);
-
- ///
- /// Reads a publisher file.
- ///
- /// The file contents as byte array or null if the file could not be read, opened or generated
- /// NP server client of the user
- /// The file name
- byte[] ReadPublisherFile(NPServerClient client, string file);
-
- ///
- /// Writes a file and assigns it to the client user.
- ///
- /// NP server client of the user
- /// The file name
- /// The file contents as byte array
- void WriteUserFile(NPServerClient client, string file, byte[] data);
- }
-}
\ No newline at end of file
diff --git a/src/server/Handlers/IFriendsHandler.cs b/src/server/Handlers/IFriendsHandler.cs
deleted file mode 100644
index 73694a5..0000000
--- a/src/server/Handlers/IFriendsHandler.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Collections.Generic;
-using NPSharp.NP;
-using NPSharp.RPC.Messages.Data;
-
-namespace NPSharp.Handlers
-{
- ///
- /// Represents a handler for all friends-related requests.
- ///
- public interface IFriendsHandler
- {
- ///
- /// Fetches all friends of the connected user.
- ///
- /// The NP server client of the user
- /// All friend details found for the user
- IEnumerable GetFriends(NPServerClient client);
- }
-}
\ No newline at end of file
diff --git a/src/server/Handlers/IUserAvatarHandler.cs b/src/server/Handlers/IUserAvatarHandler.cs
deleted file mode 100644
index cfd0f4a..0000000
--- a/src/server/Handlers/IUserAvatarHandler.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using NPSharp.Steam;
-
-namespace NPSharp.Handlers
-{
- ///
- /// Represents a handler for all user avatar-related requests.
- ///
- public interface IUserAvatarHandler
- {
- byte[] GetUserAvatar(CSteamID id);
-
- byte[] GetDefaultAvatar();
- }
-}
\ No newline at end of file
diff --git a/src/server/Master/MasterServer.cs b/src/server/Master/MasterServer.cs
deleted file mode 100644
index d8eb93c..0000000
--- a/src/server/Master/MasterServer.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using log4net;
-using NPSharp.Master.Messages;
-using NPSharp.Master.Messages.Client;
-
-namespace NPSharp.Master
-{
- public class MasterServer
- {
- // TODO: !! Avoid socket fail if stopping then restarting
-
- private readonly List>> _callbacks =
- new List>>();
-
- private readonly ILog _log;
- private readonly ushort _port;
-
- // TODO: Use the same kind of interfaces as in NP server to handle server addition and deletion
- private readonly List _registeredServers = new List();
- private readonly Socket _socket4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- private readonly Socket _socket6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
-
- public MasterServer(ushort port = 20810)
- {
- _port = port;
- _log = LogManager.GetLogger("MasterServer");
-
- // Internal callbacks
- AddCallback(messages => { });
- }
-
- internal void AddCallback(Action callback) where T : MasterClientMessage
- {
- _callbacks.Add(
- new KeyValuePair>(
- typeof (T),
- msg => callback.Invoke((T) msg)));
- }
-
- ///
- /// Starts up the NP server.
- ///
- public void Start()
- {
- if (_socket4.IsBound || _socket6.IsBound)
- throw new InvalidOperationException("This server is already running");
-
- try
- {
- // ReSharper disable once ObjectCreationAsStatement
- // TODO: fix this shit permission code
- new SocketPermission(NetworkAccess.Accept, TransportType.Udp, "", _port);
- }
- catch
- {
- _log.Error("Socket permission request failed, can't start server.");
- throw new SocketException(10013 /* Permission denied */);
- }
-
- _socket4.Bind(new IPEndPoint(IPAddress.Any, _port));
- _socket4.Listen(100);
-
- _socket6.Bind(new IPEndPoint(IPAddress.IPv6Any, _port));
- _socket6.Listen(100);
-
-
- // TODO: Implement IPv4 handling
-
- Task.Factory.StartNew(() =>
- {
- _log.Debug("Listener loop (IPv6) started");
-
- while (_socket6 != null && _socket6.IsBound)
- {
- var mergedBuffer = new List();
- while (true)
- {
- var buffer = new byte[1400];
- var clientEndPoint = (EndPoint) new IPEndPoint(IPAddress.IPv6Any, 0);
- var recvLength = _socket6.ReceiveFrom(buffer, ref clientEndPoint);
- if (recvLength <= buffer.Length)
- mergedBuffer.AddRange(buffer);
- if (recvLength < 1400)
- break;
- _handleClient(buffer, clientEndPoint);
- }
- }
- _log.Debug("Listener loop (IPv6) shut down");
- });
- }
-
- private void _handleClient(byte[] buffer, EndPoint ep)
- {
- _log.DebugFormat("Handle client {0}", ep);
-
- var message = MasterClientMessage.Deserialize(buffer);
- if (message == null)
- {
- _log.WarnFormat("Received invalid or empty request from {0}", ep);
- return;
- }
-
- // Invoke (internal) callbacks for fitting message types
- foreach (var callback in _callbacks.Where(i => i.Key == message.GetType()).Select(i => i.Value))
- {
- callback.Invoke(message);
- }
-
- _log.DebugFormat("Not handling client {0} anymore", ep);
- }
- }
-}
\ No newline at end of file
diff --git a/src/server/Master/README.txt b/src/server/Master/README.txt
deleted file mode 100644
index 439f495..0000000
--- a/src/server/Master/README.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-# Master API source code
-
-This folder is supposed to contain the source code that will provide both, a master server and client.
-
-alterIWnet and fourdeltaone made use of the open-sourced DP master server code to serve registration of dedicated servers
-and the dedicated server list for the game client.
-
-This server is supposed to be replaced by a full implementation of the protocol, both as server and client, in C# and is
-to be integrated into libnpsharp.
-
-## Protocol
-
-The master server protocol is based on Quake 3's (http://src.gnu-darwin.org/ports/games/masterserver/work/masterserver-0.4.1/docs/PROTOCOLS):
-
-Request message:
- AA AA AA AA|BB .. .. BB| A=Header, B=Body ending with line break or \x00
-
-Response message:
- AA .. .. AA|0a|BB .. .. A=Message name, B=Body
- BB
-
-Important: The response is supposed to be one or multiple specific-length plus a less-than-specific-length
-UDP packet(s).
-
-TODO: Look up the specific length in the DP master source code. It's somewhere around 1400/1500 bytes.
-
-The master server itself has to only serve for the "getservers" request and has to respond with a getServersResponse message.
-This getServersResponse message's body is serialized as following:
-
- XX AA AA AA AA BB BB[CC X=ascii("\\"), A=IP (uint, network byte order), B=Port 1 (ushort, network byte order), C=Optional port 2 (ushort, network byte order)
- CC[..] ]XX .. .. .. ..
- XX YY YY YY 00 00 00[00 Y=ascii("EOT")
- 00]
-
-In short, serialized ip-port pairs/triples separated by ASCII backslashes and ended by an entry which decodes to "EOT".
-
-## Protocol limits
-
-(see https://github.com/kphillisjr/dpmaster/blob/master/src/messages.c for reference)
-
-```c
-// Timeout after a valid infoResponse (in secondes)
-#define TIMEOUT_INFORESPONSE (15 * 60)
-
-// Period of validity for a challenge string (in secondes)
-#define TIMEOUT_CHALLENGE 2
-
-// Maximum size of a reponse packet
-#define MAX_PACKET_SIZE_OUT 1400
-```
-
-## Internal management
-
-Both the server and the client should be able to handle a variable amount of ports. For this, we plan following things:
-
-1) Assume "\" at the beginning of an entry. If not true, stream out of sync -> throw exception/disconnect.
-2) Assume an IP address exists (4 bytes minimum).
- a) If IP address is ASCII "EOT" with \x00 bytes at the end, stop reading the message.
-3) Do not assume a fixed amount of ports. Instead
- a) ...if rest > 0 bytes, read 2 bytes and append to a ushort list for ports.
- b) ...if rest == 0 bytes, prepare for reading next entry.
-
-This should be compatible with both, messages with 1 IP address + 1 port (game) and 1 IP address + 2 ports (game/query).
-
-## Messages
-
-(see https://github.com/kphillisjr/dpmaster/blob/master/src/messages.c for reference)
-
-// Types of messages (with samples):
-
-// Q3: "heartbeat QuakeArena-1\x0A"
-// DP: "heartbeat DarkPlaces\x0A"
-#define S2M_HEARTBEAT "heartbeat "
-
-// Q3 & DP & QFusion: "getinfo A_Challenge"
-#define M2S_GETINFO "getinfo"
-
-// Q3 & DP & QFusion: "infoResponse\x0A\\pure\\1\\..."
-#define S2M_INFORESPONSE "infoResponse\x0A"
-
-// Q3: "getservers 67 ffa empty full"
-// DP: "getservers DarkPlaces-Quake 3 empty full"
-// DP: "getservers Transfusion 3 empty full"
-// QFusion: "getservers qfusion 39 empty full"
-#define C2M_GETSERVERS "getservers "
-
-// DP: "getserversExt DarkPlaces-Quake 3 empty full ipv4 ipv6"
-// IOQuake3: "getserversExt 68 empty ipv6"
-#define C2M_GETSERVERSEXT "getserversExt "
-
-// Q3 & DP & QFusion:
-// "getserversResponse\\...(6 bytes)...\\...(6 bytes)...\\EOT\0\0\0"
-#define M2C_GETSERVERSREPONSE "getserversResponse"
-
-// DP & IOQuake3:
-// "getserversExtResponse\\...(6 bytes)...//...(18 bytes)...\\EOT\0\0\0"
-#define M2C_GETSERVERSEXTREPONSE "getserversExtResponse"
diff --git a/src/server/NP/NPServer.cs b/src/server/NP/NPServer.cs
deleted file mode 100644
index 820f429..0000000
--- a/src/server/NP/NPServer.cs
+++ /dev/null
@@ -1,732 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-using log4net;
-using NPSharp.Events;
-using NPSharp.Handlers;
-using NPSharp.RPC;
-using NPSharp.RPC.Messages.Client;
-using NPSharp.RPC.Messages.Data;
-using NPSharp.RPC.Messages.Server;
-using NPSharp.Steam;
-
-namespace NPSharp.NP
-{
- public class NPServer
- {
- private readonly List _clients;
- private readonly ILog _log;
- private readonly ushort _port;
-#if MONO_INCOMPATIBLE
- private readonly Socket _socket;
-#else
- private readonly Socket _socket4;
- private readonly Socket _socket6;
-#endif
-
- ///
- /// Constructs a new NP server.
- ///
- public NPServer(ushort port = 3025)
- {
- _log = LogManager.GetLogger("NPServer");
- _clients = new List();
-
-#if MONO_INCOMPATIBLE
- // Mono can't compile this since the constructor is proprietary to Windows' .NET library
- _socket = new Socket(SocketType.Stream, ProtocolType.IP);
-
- // Mono can't compile this either since the IPv6Only socket option is completely missing.
- //_socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
- //_socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0);
-#else
- // So as much as this hurts me, I have to go with TWO sockets.
- // Guys, this is why I hate network programming sometimes. SOMETIMES.
- _socket4 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- _socket6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
-#endif
- _port = port;
- }
-
- ///
- /// The handler to use for file requests to this NP server.
- ///
- public IFileServingHandler FileServingHandler { get; set; }
-
- ///
- /// The handler to use for user avatar requests to this NP server.
- ///
- public IUserAvatarHandler UserAvatarHandler { get; set; }
-
- ///
- /// Returns all currently connected clients
- ///
- public NPServerClient[] Clients
- {
- get { return _clients.ToArray(); } // Avoid race condition by IEnum changes
- }
-
- ///
- /// The handler to use for authentication requests to this NP server.
- ///
- public IAuthenticationHandler AuthenticationHandler { get; set; }
-
- ///
- /// The handler to use for friends-related requests to this NP server.
- ///
- public IFriendsHandler FriendsHandler { get; set; }
-
- ///
- /// Starts up the NP server.
- ///
- public void Start()
- {
- if (
-#if MONO_INCOMPATIBLE
- _socket.IsBound
-#else
- _socket4.IsBound || _socket6.IsBound
-#endif
- )
- throw new InvalidOperationException("This server is already running");
-
- try
- {
- // ReSharper disable once ObjectCreationAsStatement
- // TODO: fix this shit permission code
- new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", _port);
- }
- catch
- {
- _log.Error("Socket permission request failed, can't start server.");
- throw new SocketException(10013 /* Permission denied */);
- }
-
-#if MONO_INCOMPATIBLE
- _socket.Bind(new IPEndPoint(IPAddress.IPv6Any, _port));
- _socket.Listen(100);
-#else
- _socket4.Bind(new IPEndPoint(IPAddress.Any, _port));
- _socket4.Listen(100);
-
- _socket6.Bind(new IPEndPoint(IPAddress.IPv6Any, _port));
- _socket6.Listen(100);
-#endif
-
- Task.Factory.StartNew(() =>
- {
- _log.Debug("Listener loop started");
-#if MONO_INCOMPATIBLE
- var socket = _socket;
-#else
- var socket = _socket4;
-#endif
- var allDone = new ManualResetEvent(false);
- while (
-#if MONO_INCOMPATIBLE
- _socket != null && _socket.IsBound
-#else
- _socket4 != null && _socket4.IsBound
-#endif
- )
- {
- allDone.Reset();
- socket.BeginAccept(ar =>
- {
- _log.Debug("Async accept client start");
- allDone.Set();
-
- var serverSocket = (Socket) ar.AsyncState;
- var clientSocket = serverSocket.EndAccept(ar);
-
- var npsc = new NPServerClient(this, new RPCServerStream(clientSocket));
-
- _log.Debug("Async accept client end");
-
- _handleClient(npsc);
- }, socket);
- allDone.WaitOne();
- }
- _log.Debug("Listener loop shut down");
- });
-
-#if !MONO_INCOMPATIBLE
- Task.Factory.StartNew(() =>
- {
- _log.Debug("Listener loop (IPv6) started");
-
- var allDone = new ManualResetEvent(false);
- while (_socket6 != null && _socket6.IsBound)
- {
- allDone.Reset();
- _socket6.BeginAccept(ar =>
- {
- _log.Debug("Async accept (IPv6) client start");
- allDone.Set();
-
- var serverSocket = (Socket) ar.AsyncState;
- var clientSocket = serverSocket.EndAccept(ar);
-
- var npsc = new NPServerClient(this, new RPCServerStream(clientSocket));
-
- _log.Debug("Async accept (IPv6) client end");
-
- _handleClient(npsc);
- }, _socket6);
- allDone.WaitOne();
- }
- _log.Debug("Listener loop (IPv6) shut down");
- });
- }
-#endif
-
- ///
- /// Shuts down all connections and stops the NP server.
- ///
- public void Stop()
- {
- // TODO: Wait for sockets to COMPLETELY shut down
-#if MONO_INCOMPATIBLE
- _socket.Shutdown(SocketShutdown.Both);
-#else
- _socket4.Shutdown(SocketShutdown.Both);
- _socket6.Shutdown(SocketShutdown.Both);
-#endif
- }
-
- internal void _handleClient(NPServerClient client)
- {
- _log.Debug("Client now being handled");
-
- #region RPC authentication message handlers
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- var result = new NPAuthenticationResult();
- if (AuthenticationHandler != null)
- {
- try
- {
- result = AuthenticationHandler.AuthenticateServer(client, msg.LicenseKey);
- }
- catch (Exception error)
- {
- _log.Error("Error occurred in authentication handler", error);
- }
- }
-
- // Send authentication result directly to client
- client.RPC.Send(new AuthenticateResultMessage
- {
- NPID = result.UserID,
- Result = result.Result ? 0 : 1,
- SessionToken = string.Empty
- });
-
- // Authentication failed => close connection
- if (!result.Result)
- {
- client.RPC.Close();
- return;
- }
-
- // Assign login ID
- client.UserID = result.UserID;
- client.IsServer = true;
-
- OnClientAuthenticated(client);
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- var result = new NPAuthenticationResult();
- if (AuthenticationHandler != null)
- {
- try
- {
- result = AuthenticationHandler.AuthenticateUser(client, msg.Username, msg.Password);
- }
- catch (Exception error)
- {
- _log.Error("Error occurred in authentication handler", error);
- result = new NPAuthenticationResult();
- }
- }
-
- // Send authentication result directly to client
- client.RPC.Send(new AuthenticateResultMessage
- {
- NPID = result.UserID,
- Result = result.Result ? 0 : 1,
- SessionToken = string.Empty
- });
-
- // Authentication failed => close connection
- if (!result.Result)
- {
- client.RPC.Close();
- return;
- }
-
- // Assign login ID
- client.UserID = result.UserID;
-
- // Send "online" notification to all friends of this player
- foreach (var fconn in client.FriendConnections)
- {
- fconn.RPC.Send(new FriendsPresenceMessage
- {
- CurrentServer = client.DedicatedServer == null ? 0 : client.DedicatedServer.UserID,
- Friend = client.UserID,
- Presence = client.PresenceData,
- PresenceState = client.DedicatedServer == null ? 1 : 2
- });
- }
-
- // Send friends roster to player
- client.RPC.Send(new FriendsRosterMessage
- {
- Friends = client.Friends.ToArray()
- });
-
- OnClientAuthenticated(client);
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- var result = new NPAuthenticationResult();
- if (AuthenticationHandler != null)
- {
- try
- {
- result = AuthenticationHandler.AuthenticateUser(client, msg.Token);
- }
- catch (Exception error)
- {
- _log.Error("Error occurred in authentication handler", error);
- }
- }
-
- // Send authentication result directly to client
- client.RPC.Send(new AuthenticateResultMessage
- {
- NPID = result.UserID == null ? 0 : result.UserID.ConvertToUint64(),
- Result = result.Result ? 0 : 1,
- SessionToken = msg.Token
- });
-
- // Authentication failed => close connection
- if (!result.Result)
- {
- client.RPC.Close();
- return;
- }
-
- // Assign login ID
- client.UserID = result.UserID;
-
- // Send "online" notification to all friends of this player
- foreach (var fconn in client.FriendConnections)
- {
- fconn.RPC.Send(new FriendsPresenceMessage
- {
- CurrentServer = client.DedicatedServer == null ? 0 : client.DedicatedServer.UserID,
- Friend = client.UserID,
- Presence = client.PresenceData,
- PresenceState = client.DedicatedServer == null ? 1 : 2
- });
- }
-
- // Send friends roster to player
- client.RPC.Send(new FriendsRosterMessage
- {
- Friends = client.Friends.ToArray()
- });
-
- OnClientAuthenticated(client);
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- var validTicket = false;
-
- if (!client.IsDirty)
- {
- Ticket ticketData = null;
-
- try
- {
- ticketData = new Ticket(msg.Ticket);
-
- _log.DebugFormat("Ticket[Version={0},ServerID={1},Time={2}]", ticketData.Version,
- ticketData.ServerID, ticketData.Time);
- }
- catch (ArgumentException error)
- {
- _log.Warn("Got some weird-length ticket data", error);
- }
-
- if (ticketData != null)
- {
- if (ticketData.Version == 1) // Version 1 enforcement
- {
- if (ticketData.ClientID == client.UserID) // NPID enforcement
- {
- var s =
- _clients.Where(c => c.IsServer && !c.IsDirty && c.UserID == ticketData.ServerID)
- .ToArray();
-
- if (s.Any())
- {
- // TODO: Time validation. Problem is some clocks go wrong by minutes!
- client.DedicatedServer = s.First();
- validTicket = true;
- _log.Debug("Ticket validated");
- }
- else
- {
- _log.Warn("Ticket invalid, could not find any sane servers with requested server ID");
- }
- }
- else
- {
- _log.Warn("Ticket invalid, found NPID spoofing attempt");
- }
- }
- else
- {
- _log.Warn("Ticket invalid, found invalid version");
- }
- }
- }
- else
- {
- _log.Warn("Ticket invalid, client is marked as dirty");
- }
-
- // Invalid data buffer
- client.RPC.Send(new AuthenticateValidateTicketResultMessage
- {
- GroupID = client.GroupID,
- NPID = client.UserID,
- Result = validTicket ? 0 : 1
- });
- });
-
- #endregion
-
- #region RPC friend message handlers
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- foreach (var pdata in msg.Presence)
- {
- client.SetPresence(pdata.Key, pdata.Value);
- _log.DebugFormat("Client says presence \"{0}\" is \"{1}\"", pdata.Key, pdata.Value);
- }
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- // TODO: Not compatible with non-public accounts
- var npid = new CSteamID((uint) msg.Guid, EUniverse.Public,
- EAccountType.Individual).ConvertToUint64();
-
- var avatar = UserAvatarHandler.GetUserAvatar(npid) ?? UserAvatarHandler.GetDefaultAvatar();
-
- client.RPC.Send(new FriendsGetUserAvatarResultMessage
- {
- FileData = avatar,
- Guid = msg.Guid,
- Result = avatar != null ? 0 : 1
- });
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- // TODO
- });
-
- #endregion
-
- #region RPC storage message handlers
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- if (FileServingHandler == null)
- {
- client.RPC.Send(new StoragePublisherFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- return;
- }
-
- try
- {
- if (client.UserID == null)
- {
- client.RPC.Send(new StoragePublisherFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- _log.WarnFormat("Client tried to read publisher file {0} while not logged in", msg.FileName);
- return;
- }
-
- var data = FileServingHandler.ReadPublisherFile(client, msg.FileName);
- if (data == null)
- {
- client.RPC.Send(new StoragePublisherFileMessage
- {
- MessageId = msg.MessageId,
- Result = 1,
- FileName = msg.FileName
- });
- _log.DebugFormat("Could not open publisher file {0}", msg.FileName);
- return;
- }
-
- client.RPC.Send(new StoragePublisherFileMessage
- {
- MessageId = msg.MessageId,
- Result = 0,
- FileName = msg.FileName,
- FileData = data
- });
- _log.DebugFormat("Sent publisher file {0}", msg.FileName);
- }
- catch (Exception error)
- {
- _log.Warn("GetPublisherFile handler error", error);
- client.RPC.Send(new StoragePublisherFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- }
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- if (FileServingHandler == null)
- {
- client.RPC.Send(new StorageUserFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- return;
- }
-
- try
- {
- if (client.UserID == null)
- {
- client.RPC.Send(new StorageUserFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName,
- NPID = client.UserID
- });
- _log.WarnFormat("Client tried to read user file {0} while not logged in", msg.FileName);
- return;
- }
-
- var data = FileServingHandler.ReadUserFile(client, msg.FileName);
- if (data == null)
- {
- client.RPC.Send(new StorageUserFileMessage
- {
- MessageId = msg.MessageId,
- Result = 1,
- FileName = msg.FileName,
- NPID = client.UserID
- });
- _log.DebugFormat("Could not open user file {0}", msg.FileName);
- return;
- }
-
- client.RPC.Send(new StorageUserFileMessage
- {
- MessageId = msg.MessageId,
- Result = 0,
- FileName = msg.FileName,
- FileData = data,
- NPID = client.UserID
- });
- _log.DebugFormat("Sent user file {0}", msg.FileName);
- }
- catch (Exception error)
- {
- _log.Warn("GetUserFile handler error", error);
- client.RPC.Send(new StorageUserFileMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- }
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- // TODO: Handle "random string" messages
- });
-
- client.RPC.AttachHandlerForMessageType(msg =>
- {
- if (FileServingHandler == null)
- {
- client.RPC.Send(new StorageWriteUserFileResultMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- return;
- }
-
- try
- {
- if (client.UserID == null)
- {
- client.RPC.Send(new StorageWriteUserFileResultMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName,
- NPID = client.UserID
- });
- _log.WarnFormat("Client tried to write user file {0} while not logged in", msg.FileName);
- return;
- }
-
- FileServingHandler.WriteUserFile(client, msg.FileName, msg.FileData);
-
- client.RPC.Send(new StorageWriteUserFileResultMessage
- {
- MessageId = msg.MessageId,
- Result = 0,
- FileName = msg.FileName,
- NPID = client.UserID
- });
- _log.DebugFormat("Received and wrote user file {0}", msg.FileName);
- }
- catch (Exception error)
- {
- _log.Warn("WriteUserFile handler error", error);
- client.RPC.Send(new StorageWriteUserFileResultMessage
- {
- MessageId = msg.MessageId,
- Result = 2,
- FileName = msg.FileName
- });
- }
- });
- // TODO: RPC message handling for MessagingSendData
-
- #endregion
-
- #region RPC server session message handler
-
- #endregion
-
- _clients.Add(client);
-#if !DEBUG
- try
- {
-#endif
- _log.Debug("Client connected");
- OnClientConnected(client);
-#if !DEBUG
- try
-#endif
- {
- while (true)
- {
- var msg = client.RPC.Read();
- if (msg == null)
- break;
- }
- }
-#if !DEBUG
- catch (Exception error)
- {
- _log.Error("Error in RPC read loop", error);
- }
-#endif
- _log.Debug("Client disconnected");
- OnClientDisconnected(client);
-#if !DEBUG
- }
- catch (Exception error)
- {
- _log.Error("Error in client handling loop", error);
- client.RPC.Send(new CloseAppMessage {Reason = "Server-side error occurred, try again later."});
- client.RPC.Close();
- }
-#endif
- _clients.Remove(client);
- }
-
- ///
- /// Triggered when a client has connected but is not authenticating yet.
- ///
- public event ClientEventHandler ClientConnected;
-
- ///
- /// Invokes the event.
- ///
- /// The client
- protected virtual void OnClientConnected(NPServerClient client)
- {
- var handler = ClientConnected;
- var args = new ClientEventArgs(client);
- if (handler != null) handler(this, args);
- }
-
- ///
- /// Triggered when a client has disconnected.
- ///
- public event ClientEventHandler ClientDisconnected;
-
- ///
- /// Invokes the event.
- ///
- /// The client
- protected virtual void OnClientDisconnected(NPServerClient client)
- {
- var handler = ClientDisconnected;
- var args = new ClientEventArgs(client);
- if (handler != null) handler(this, args);
- }
-
- ///
- /// Triggered when a client has authenticated successfully.
- ///
- public event ClientEventHandler ClientAuthenticated;
-
- ///
- /// Invokes the event.
- ///
- /// The client
- protected virtual void OnClientAuthenticated(NPServerClient client)
- {
- var handler = ClientAuthenticated;
- var args = new ClientEventArgs(client);
- if (handler != null) handler(this, args);
- }
- }
-}
\ No newline at end of file
diff --git a/src/server/NP/NPServerClient.cs b/src/server/NP/NPServerClient.cs
deleted file mode 100644
index e569d8a..0000000
--- a/src/server/NP/NPServerClient.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using NPSharp.RPC;
-using NPSharp.RPC.Messages.Data;
-using NPSharp.Steam;
-
-namespace NPSharp.NP
-{
- ///
- /// Represents a remote client connection to an NP server.
- ///
- public class NPServerClient
- {
- internal readonly NPServer NP;
- internal readonly RPCServerStream RPC;
- private readonly Dictionary _presence = new Dictionary();
- internal NPServerClient DedicatedServer;
-
- internal NPServerClient(NPServer np, RPCServerStream rpcclient)
- {
- NP = np;
- RPC = rpcclient;
- }
-
- public CSteamID UserID { get; internal set; }
-
- public IEnumerable Friends
- {
- get
- {
- return NP.FriendsHandler == null
- ? new FriendDetails[0]
- : NP.FriendsHandler.GetFriends(this).ToArray();
- }
- }
-
- public IEnumerable FriendConnections
- {
- get { return NP.Clients.Where(c => Friends.Any(f => f.NPID == c.UserID)); }
- }
-
- public FriendsPresence[] PresenceData
- {
- get { return _presence.Select(i => new FriendsPresence {Key = i.Key, Value = i.Value}).ToArray(); }
- }
-
- public bool IsServer { get; set; }
- public bool IsDirty { get; set; }
- public int GroupID { get; set; }
-
- internal void SetPresence(string key, string value)
- {
- if (!_presence.ContainsKey(key))
- _presence.Add(key, value);
- else
- _presence[key] = value;
- }
- }
-}
\ No newline at end of file
diff --git a/src/server/NPSharp.Server.csproj b/src/server/NPSharp.Server.csproj
deleted file mode 100644
index 1d3dd18..0000000
--- a/src/server/NPSharp.Server.csproj
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {1A5AC63A-250E-4BC8-B81A-822AC31F5E37}
- Library
- Properties
- NPSharp
- npsharp_server
- v4.5
- 512
-
- 12.0.0
- 2.0
- ..\..\
- true
-
-
- true
- full
- false
- TRACE;DEBUG;COMPILE_RPC,COMPILE_NP,COMPILE_AUTH
- prompt
- 4
- false
-
-
- pdbonly
- true
- TRACE;COMPILE_RPC,COMPILE_NP,COMPILE_AUTH
- prompt
- 4
- false
-
-
- $(SolutionDir)\bin\$(Configuration)\$(Platform)\
- $(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\
- $(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\
- $(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\
- $(SolutionDir)\bin\$(Configuration)\$(Platform)\
-
-
-
- $(SolutionDir)\packages\log4net.2.0.3\lib\net40-full\log4net.dll
-
-
- $(SolutionDir)\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll
-
-
-
- False
- $(SolutionDir)\packages\uHttpSharp.0.1.5.4\lib\net40\uhttpsharp.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {c6f941a5-82af-456a-9b3a-752e5b001035}
- NPSharp.Client
-
-
-
-
\ No newline at end of file
diff --git a/src/server/Properties/AssemblyInfo.cs b/src/server/Properties/AssemblyInfo.cs
deleted file mode 100644
index 2291f1e..0000000
--- a/src/server/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// Allgemeine Informationen über eine Assembly werden über die folgenden
-// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
-// die mit einer Assembly verknüpft sind.
-
-[assembly: AssemblyTitle("NPSharp server library")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Carl Kittelberger")]
-[assembly: AssemblyProduct("NPSharp")]
-[assembly: AssemblyCopyright("© 2014 Carl Kittelberger")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
-// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
-// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
-
-[assembly: ComVisible(false)]
-
-// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
-
-[assembly: Guid("0efdd0b5-fd69-48fd-b714-f4f0e032f417")]
-
-// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
-//
-// Hauptversion
-// Nebenversion
-// Buildnummer
-// Revision
-//
-// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
-// übernehmen, indem Sie "*" eingeben:
-// [assembly: AssemblyVersion("1.0.*")]
-
-[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyFileVersion("1.0")]
\ No newline at end of file
diff --git a/src/server/RPC/RPCServerStream.cs b/src/server/RPC/RPCServerStream.cs
deleted file mode 100644
index fb24e91..0000000
--- a/src/server/RPC/RPCServerStream.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-#if COMPILE_RPC||COMPILE_NP
-
-using System.Net.Sockets;
-using NPSharp.RPC.Messages;
-
-namespace NPSharp.RPC
-{
- ///
- /// Represents a low-level stream which communicates with an NP client using RPC messages.
- ///
- public class RPCServerStream : RPCStream
- {
- public RPCServerStream(Socket sock) : base(sock)
- {
- }
- }
-}
-
-#endif
\ No newline at end of file
diff --git a/src/server/app.config b/src/server/app.config
deleted file mode 100644
index e63f192..0000000
--- a/src/server/app.config
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/server/packages.config b/src/server/packages.config
deleted file mode 100644
index 4b9179d..0000000
--- a/src/server/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file