RavenDB. Minimalistic, not quite efficient.

feature-npv2
Icedream 2014-05-10 00:36:03 +02:00
parent 1297afc0ee
commit 1ec64df389
15 changed files with 537 additions and 228 deletions

View File

@ -1,51 +0,0 @@
using System;
using System.Threading;
using NPSharp.Steam;
using Raven.Abstractions.Data;
using Raven.Client.Connection;
using Raven.Client.Linq;
using Raven.Database;
using Raven.Database.Linq.PrivateExtensions;
namespace NPSharp.Authentication
{
class DummyAuthenticationHandler : IAuthenticationHandler
{
// TODO: RavenDB integration
private uint _userID;
private DocumentDatabase _db;
public DummyAuthenticationHandler(DocumentDatabase db)
{
_db = db;
}
public AuthenticationResult AuthenticateUser(NPServerClient client, string username, string password)
{
return new AuthenticationResult(new CSteamID()
{
AccountID = _userID++
});
}
public AuthenticationResult AuthenticateUser(NPServerClient client, string token)
{
return new AuthenticationResult(new CSteamID()
{
AccountID = _userID++
});
}
public AuthenticationResult AuthenticateServer(NPServerClient client, string licenseKey)
{
throw new NotImplementedException();
}
public TicketValidationResult ValidateTicket(NPServerClient client, NPServerClient server)
{
throw new NotImplementedException();
}
}
}

View File

@ -57,7 +57,10 @@ namespace NPSharp.Authentication
{ {
throw new InvalidOperationException("This server is already running"); throw new InvalidOperationException("This server is already running");
} }
_log.Debug("Starting authentication server...");
_http = new HttpServer(new HttpRequestProvider()); _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 TcpListenerAdapter(new TcpListener(IPAddress.IPv6Any, port)));
_http.Use(new HttpRouter().With("authenticate", new AuthenticateHandler(this))); _http.Use(new HttpRouter().With("authenticate", new AuthenticateHandler(this)));
_http.Use(new AnonymousHttpRequestHandler((ctx, task) => _http.Use(new AnonymousHttpRequestHandler((ctx, task) =>
@ -67,6 +70,7 @@ namespace NPSharp.Authentication
return Task.Factory.GetCompleted(); return Task.Factory.GetCompleted();
})); }));
_http.Start(); _http.Start();
_log.Debug("Done starting authentication server.");
} }
/// <summary> /// <summary>

View File

@ -67,7 +67,7 @@ namespace NPSharp.RPC.Messages
#if !DEBUG #if !DEBUG
catch (Exception error) catch (Exception error)
{ {
Log.Error("Error while reading from network socket", error) Log.Error("Error while reading from network socket", error);
return null; return null;
} }
#endif #endif
@ -97,7 +97,7 @@ namespace NPSharp.RPC.Messages
using (var ms = new MemoryStream(buffer)) using (var ms = new MemoryStream(buffer))
{ {
Type[] types = Assembly.GetExecutingAssembly().GetTypes().Where( var types = Assembly.GetExecutingAssembly().GetTypes().Where(
t => t =>
t.IsSubclassOf(typeof (T)) t.IsSubclassOf(typeof (T))
&& &&

View File

@ -42,48 +42,14 @@
<OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> <Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\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="Microsoft.Data.Edm, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage">
<HintPath>..\..\packages\WindowsAzure.Storage.2.0.6.1\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="Raven.Abstractions">
<HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Raven.Client.Embedded">
<HintPath>..\..\packages\RavenDB.Embedded.2.5.2878\lib\net45\Raven.Client.Embedded.dll</HintPath>
</Reference>
<Reference Include="Raven.Client.Lightweight">
<HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Client.Lightweight.dll</HintPath>
</Reference>
<Reference Include="Raven.Database">
<HintPath>..\..\packages\RavenDB.Database.2.5.2878\lib\net45\Raven.Database.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Data.Services.Client" />
<Reference Include="System.Spatial, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="log4net"> <Reference Include="log4net">
<HintPath>..\..\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>
@ -98,7 +64,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AuthenticationResult.cs" /> <Compile Include="AuthenticationResult.cs" />
<Compile Include="Authentication\DummyAuthenticationHandler.cs" />
<Compile Include="Authentication\SessionAuthenticationServer.cs" /> <Compile Include="Authentication\SessionAuthenticationServer.cs" />
<Compile Include="ClientEventArgs.cs" /> <Compile Include="ClientEventArgs.cs" />
<Compile Include="ClientEventHandler.cs" /> <Compile Include="ClientEventHandler.cs" />

View File

@ -91,11 +91,28 @@ namespace NPSharp.CommandLine.File
return; return;
} }
string hostname = args[0]; var hostname = args[0];
ushort port = ushort.Parse(args[1]); var port = ushort.Parse(args[1]);
string username = args[2]; var username = args[2];
string password = args[3]; var password = args[3];
int hport = args.Length > 4 ? ushort.Parse(args[4]) : 5680; var hport = args.Length > 4 ? ushort.Parse(args[4]) : 5680;
// Get session token
var ah = new SessionAuthenticationClient(hostname);
try
{
ah.Authenticate(username, password);
log.Info("NP authentication successful.");
}
catch (Exception err)
{
#if DEBUG
log.ErrorFormat("Could not authenticate: {0}", err);
#else
log.ErrorFormat("Could not authenticate: {0}", err.Message);
#endif
return;
}
// NP connection setup // NP connection setup
log.DebugFormat("Connecting to {0}:{1}...", hostname, port); log.DebugFormat("Connecting to {0}:{1}...", hostname, port);
@ -105,26 +122,14 @@ namespace NPSharp.CommandLine.File
log.Error("Connection to NP server failed."); log.Error("Connection to NP server failed.");
return; return;
} }
log.Info("NP connection successful, authenticating..."); if (!np.AuthenticateWithToken(ah.SessionToken).Result)
// Get session token
var ah = new SessionAuthenticationClient(hostname);
try
{
ah.Authenticate(username, password);
np.AuthenticateWithToken(ah.SessionToken).Wait();
log.Info("NP authentication successful.");
}
catch (Exception err)
{ {
np.Disconnect(); np.Disconnect();
#if DEBUG log.Error("Authentication to NP server failed.");
log.ErrorFormat("Could not authenticate: {0}", err);
#else
log.ErrorFormat("Could not authenticate: {0}", err.Message);
#endif
return; return;
} }
log.Info("NP connection successful, authenticating...");
// HTTP server // HTTP server
using (var httpServer = new HttpServer(new HttpRequestProvider())) using (var httpServer = new HttpServer(new HttpRequestProvider()))

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using BCryptClass = BCrypt.Net.BCrypt;
namespace NPSharp.CommandLine.Server.Database
{
class Session
{
public Session()
{
Id = Guid.NewGuid().ToString("N");
}
public string Id { get; set; }
public User User { get; set; }
public DateTime ExpiryTime { get; set; }
public TimeSpan ExpiresIn { get { return ExpiryTime - DateTime.Now; } }
public bool IsValid { get { return ExpiryTime >= DateTime.Now; } }
}
class User
{
public uint Id { get; set; }
public string UserName { get; set; }
public string UserMail { get; set; }
public string PasswordHash { get; set; }
public DateTime LastLogin { get; set; }
public List<string> BanIDs { get; set; }
public List<string> CheatDetectionIDs { get; set; }
public List<uint> FriendIDs { get; set; }
public bool ComparePassword(string pw)
{
return BCryptClass.Verify(pw, PasswordHash);
}
}
class UserFile
{
public string Id { get; set; }
public string FileName { get; set; }
public uint UserID { get; set; }
public byte[] FileData { get; set; }
}
class PublisherFile
{
public string Id { get; set; }
public string FileName { get; set; }
public byte[] FileData { get; set; }
}
class Ban
{
public Ban()
{
Id = Guid.NewGuid().ToString("N");
}
public string Id { get; set; }
public string Reason { get; set; }
public DateTime ExpiryTime { get; set; }
public TimeSpan ExpiresIn { get { return ExpiryTime - DateTime.Now; } }
public bool IsValid { get { return ExpiryTime >= DateTime.Now; } }
}
class CheatDetection
{
public CheatDetection()
{
Id = Guid.NewGuid().ToString("N");
}
public string Id { get; set; }
public uint CheatId { get; set; }
public uint UserId { get; set; }
public string Reason { get; set; }
public DateTime ExpiryTime { get; set; }
public TimeSpan ExpiresIn { get { return ExpiryTime - DateTime.Now; } }
public bool IsValid { get { return ExpiryTime >= DateTime.Now; } }
}
}

View File

@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPSharp.Steam;
namespace NPSharp.CommandLine.Server
{
class DummyAuthenticationHandler : IAuthenticationHandler
{
private uint _userID = 1;
public AuthenticationResult AuthenticateUser(NPServerClient client, string username, string password)
{
return new AuthenticationResult(new CSteamID()
{
AccountID = _userID++,
AccountInstance = 1,
AccountType = EAccountType.Individual,
AccountUniverse = EUniverse.Public
});
}
public AuthenticationResult AuthenticateUser(NPServerClient client, string token)
{
return new AuthenticationResult(new CSteamID()
{
AccountID = _userID++,
AccountInstance = 1,
AccountType = EAccountType.Individual,
AccountUniverse = EUniverse.Public
});
}
public AuthenticationResult AuthenticateServer(NPServerClient client, string licenseKey)
{
throw new NotImplementedException();
}
public TicketValidationResult ValidateTicket(NPServerClient client, NPServerClient server)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NPSharp.CommandLine.Server
{
class DummyFileServingHandler : IFileServingHandler
{
public byte[] ReadUserFile(NPServerClient client, string file)
{
return new byte[0];
}
public byte[] ReadPublisherFile(NPServerClient client, string file)
{
switch (file.ToLower())
{
case "hello_world.txt":
return Encoding.UTF8.GetBytes("Hi, this is a test hello_world.txt.");
case "motd-english.txt":
return
Encoding.UTF8.GetBytes(
"Hello, this is a test NP server written in C#. Thanks for visiting this server.");
}
return null;
}
public void WriteUserFile(NPServerClient client, string file, byte[] data)
{
// Ignore stuff
}
}
}

14
src/npserv/LICENSE.txt Normal file
View File

@ -0,0 +1,14 @@
Copyright (c) 2006 Damien Miller <djm@mindrot.org> (jBCrypt)
Copyright (c) 2013 Ryan D. Emerle (.Net port)
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@ -1,20 +1,217 @@
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using log4net; using log4net;
using log4net.Appender; using log4net.Appender;
using log4net.Config; using log4net.Config;
using log4net.Core; using log4net.Core;
using log4net.Layout; using log4net.Layout;
using NPSharp.Authentication; using NPSharp.Authentication;
using NPSharp.CommandLine.Server.Database;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Linq;
using Raven.Database.Server;
namespace NPSharp.CommandLine.Server namespace NPSharp.CommandLine.Server
{ {
class Program class Program
{ {
private static ILog _log;
private static IDocumentStore _database;
private static IDocumentSession _db;
private static SessionAuthenticationServer _authServer;
private static NPServer _np;
static void Main() static void Main()
{ {
InitializeLogging();
_log.Info("NP server is about to start up, this might take a few seconds...");
// log4net setup InitializeDatabase();
InitializeAuthServer();
InitializeNPServer();
_log.Info("NP server started up successfully.");
Thread.Sleep(Timeout.Infinite);
}
static void InitializeDatabase()
{
_log.Debug("Starting Raven database...");
#if DEBUG
Directory.CreateDirectory(@"Raven");
Directory.CreateDirectory(@"Raven\CompiledIndexCache");
#endif
Directory.CreateDirectory(@"Database");
NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(12002);
var database = new EmbeddableDocumentStore
{
DataDirectory = "Database",
UseEmbeddedHttpServer = true
};
database.Configuration.Port = 12002;
database.Configuration.AllowLocalAccessWithoutAuthorization = true;
database.Configuration.DataDirectory = "Database";
_database = database.Initialize();
_database.Conventions.IdentityTypeConvertors.Add(new UInt32Converter());
// Set up initial admin user
_db = _database.OpenSession();
//using (var db = _database.OpenSession())
//{
if (!_db.Query<User>().Any())
{
_log.Warn("Creating default admin user because no users could be found in the database...");
var adminUser = new User()
{
BanIDs = new List<string>(),
CheatDetectionIDs = new List<string>(),
FriendIDs = new List<uint>(),
PasswordHash = BCrypt.Net.BCrypt.HashPassword("test"),
UserMail = "admin@localhost",
UserName = "admin"
};
_db.Store(adminUser);
_db.SaveChanges();
_log.Warn("Default admin user created. For details see below.");
_log.Warn("\tUsername: admin");
_log.Warn("\tPassword: test");
_log.Warn("This only happens when no users can be found in the database. Change the details or create a new user to access the server asap!");
}
//}
// Endless loop to clean up expired stuff
Task.Factory.StartNew(() =>
{
while (_database != null && !_database.WasDisposed)
{
using (var db = _database.OpenSession())
{
var expiredSessions = db.Query<Session>().Where(s => !s.IsValid).ToArray();
foreach (var session in expiredSessions)
db.Delete(session);
var expiredBans = db.Query<Ban>().Where(b => !b.IsValid).ToArray();
foreach (var ban in expiredBans)
db.Delete(ban);
var expiredCheatDetections = db.Query<CheatDetection>().Where(cd => !cd.IsValid).ToArray();
foreach (var cd in expiredCheatDetections)
db.Delete(cd);
_log.DebugFormat(
"Purging {0} invalid sessions, {1} invalid bans and {2} invalid cheat detections",
expiredSessions.Length,
expiredBans.Length,
expiredCheatDetections.Length);
db.SaveChanges();
}
Thread.Sleep(TimeSpan.FromMinutes(5));
}
});
}
static void InitializeAuthServer()
{
_log.Debug("Starting authentication server...");
_authServer = new SessionAuthenticationServer();
_authServer.Authenticating += (loginUsername, loginPassword) =>
{
//using (var db = _database.OpenSession())
//{
var resp = new SessionAuthenticationResult();
// Check if we have any user to which the given credentials fit
var users = _db
// database processing
.Query<User>()
.Customize(x => x
.Include<User>(o => o.BanIDs)
.Include<User>(o => o.CheatDetectionIDs))
.Where(u => u.UserName == loginUsername)
.ToArray()
// local processing
.Where(u => u.ComparePassword(loginPassword))
.ToArray();
if (!users.Any())
{
resp.Reason =
"Login details are incorrect. Please check your username and password and try again.";
return resp;
}
var user = users.Single();
// Check if user is banned
var bans = _db.Load<Ban>(user.BanIDs);
if (bans.Any(b => b.IsValid))
{
var ban = bans.First(b => b.IsValid);
resp.Reason = string.Format("You're currently banned: {0} (expires in {1})", ban.Reason,
ban.ExpiresIn.ToString("g")); // TODO: Format as d days h hours m minutes and s seconds
return resp;
}
// Check if user was hacking
var cheatDetections = _db.Load<CheatDetection>(user.CheatDetectionIDs);
if (cheatDetections.Any(b => b.IsValid))
{
var ban = cheatDetections.First(b => b.IsValid);
resp.Reason = string.Format("You have been seen using a cheat: {0} (expires in {1})", ban.Reason,
ban.ExpiresIn.ToString("g")); // TODO: Format as d days h hours m minutes and s seconds
return resp;
}
// Create a session for this user
var session = new Session()
{
ExpiryTime = DateTime.Now + TimeSpan.FromMinutes(5),
User = user
};
_db.Store(session);
// Update user's last login time
user.LastLogin = DateTime.Now;
_db.Store(user);
resp.UserID = user.Id;
resp.UserMail = user.UserMail;
resp.UserName = user.UserName;
resp.SessionToken = session.Id;
resp.Success = true;
// Save everything to the database now
_db.SaveChanges();
return resp;
//}
};
_authServer.Start();
}
private static void InitializeNPServer()
{
_log.Debug("Starting NP server...");
_np = new NPServer(3036)
{
AuthenticationHandler = new RavenDatabaseAuthenticationHandler(_database),
FileServingHandler = new RavenDatabaseFileServingHandler(_database)
// TODO: Implement the other handlers
};
_np.Start();
}
static void InitializeLogging()
{
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
{ {
var appender = new ConsoleAppender var appender = new ConsoleAppender
@ -69,32 +266,7 @@ namespace NPSharp.CommandLine.Server
BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } }); BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } });
} }
var log = LogManager.GetLogger("Main"); _log = LogManager.GetLogger("Main");
log.Info("Now starting authentication server...");
var auth = new SessionAuthenticationServer();
auth.Authenticating += (user, pw) => new SessionAuthenticationResult()
{
SessionToken = Guid.NewGuid().ToString("N"),
UserID = 1,
Success = true,
UserMail = "anonymous@localhost",
UserName = "anonymous"
};
auth.Start();
log.Info("Authentication server started up successfully.");
log.Info("Now starting NP server...");
var np = new NPServer(3036)
{
AuthenticationHandler = new DummyAuthenticationHandler(),
FileServingHandler = new DummyFileServingHandler()
// TODO: Implement the other handlers
};
np.Start();
log.Info("NP server started up successfully.");
Thread.Sleep(Timeout.Infinite);
} }
} }
} }

View File

@ -0,0 +1,65 @@
using System;
using NPSharp.CommandLine.Server.Database;
using NPSharp.Steam;
using Raven.Client;
namespace NPSharp.CommandLine.Server
{
class RavenDatabaseAuthenticationHandler : IAuthenticationHandler
{
//private readonly IDocumentStore _database;
private readonly IDocumentSession _db;
public RavenDatabaseAuthenticationHandler(IDocumentStore database)
{
//_database = database;
_db = database.OpenSession();
}
~RavenDatabaseAuthenticationHandler()
{
_db.Dispose();
}
public AuthenticationResult AuthenticateUser(NPServerClient client, string username, string password)
{
// Nah, authenticating this way is deprecated as fuck.
return new AuthenticationResult();
}
public AuthenticationResult AuthenticateUser(NPServerClient client, string token)
{
//using (var db = _database.OpenSession())
//{
var session = _db.Load<Session>(token);
if (session == null)
{
// Invalid session token
return new AuthenticationResult();
}
// Remove session now since we don't need it anymore
_db.Delete(session);
_db.SaveChanges();
return new AuthenticationResult(new CSteamID()
{
AccountID = session.User.Id,
AccountInstance = 1,
AccountType = EAccountType.Individual,
AccountUniverse = EUniverse.Public
});
//}
}
public AuthenticationResult AuthenticateServer(NPServerClient client, string licenseKey)
{
throw new NotImplementedException();
}
public TicketValidationResult ValidateTicket(NPServerClient client, NPServerClient server)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,98 @@
using System.Linq;
using System.Text;
using NPSharp.CommandLine.Server.Database;
using Raven.Client;
namespace NPSharp.CommandLine.Server
{
class RavenDatabaseFileServingHandler : IFileServingHandler
{
private readonly IDocumentStore _database;
public RavenDatabaseFileServingHandler(IDocumentStore database)
{
_database = database;
}
protected byte[] GetDefaultUserFile(string file)
{
switch (file)
{
case "iw4.stat":
return new byte[8 * 1024];
default:
return null;
}
}
protected byte[] GetDefaultPublisherFile(string file)
{
switch (file)
{
case "hello_world.txt":
case "motd-english.txt":
case "motd-german.txt":
case "motd-french.txt":
case "motd-russian.txt":
case "motd-spanish.txt":
return Encoding.UTF8.GetBytes("hello");
case "playerlog.csv":
case "social_tu1.cfg":
case "heatmap.raw":
case "online_mp.img":
return new byte[0];
default:
return null;
}
}
public byte[] ReadUserFile(NPServerClient client, string file)
{
using (var db = _database.OpenSession())
{
var userfile = db
.Query<UserFile>()
.Customize(uf => uf.Include<UserFile>(o => o.UserID))
.SingleOrDefault(uf =>
uf.FileName == file
&& db.Load<User>(uf.UserID).Id == client.UserID.AccountID);
return userfile == null ? null : userfile.FileData;
}
}
public byte[] ReadPublisherFile(NPServerClient client, string file)
{
using (var db = _database.OpenSession())
{
var pubfiles =
db.Query<PublisherFile>()
.Where(uf => uf.FileName == file)
.ToArray();
return !pubfiles.Any() ? GetDefaultPublisherFile(file) : pubfiles.Single().FileData;
}
}
public void WriteUserFile(NPServerClient client, string file, byte[] data)
{
using (var db = _database.OpenSession())
{
var userfile = db
.Query<UserFile>()
.Customize(uf => uf.Include<UserFile>(o => o.UserID))
.SingleOrDefault(uf =>
uf.FileName == file
&& db.Load<User>(uf.UserID).Id == client.UserID.AccountID)
?? new UserFile();
userfile.UserID = client.UserID.AccountID;
userfile.FileData = data;
userfile.FileName = file;
db.Store(userfile);
db.SaveChanges();
}
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using Raven.Client.Converters;
namespace NPSharp.CommandLine.Server
{
public class UInt32Converter : ITypeConverter
{
public bool CanConvertFrom(Type sourceType)
{
return sourceType == typeof(uint);
}
public string ConvertFrom(string tag, object value, bool allowNull)
{
var val = (uint)value;
if (val == 0 && allowNull)
return null;
return tag + value;
}
public object ConvertTo(string value)
{
return uint.Parse(value);
}
}
}

View File

@ -39,36 +39,37 @@
<OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="BCrypt.Net">
<HintPath>..\..\packages\BCrypt-Official.0.1.109\lib\BCrypt.Net.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> <Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\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="Microsoft.Data.Edm, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Data.Edm, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll</HintPath> <HintPath>..\..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Data.OData, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Data.OData, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll</HintPath> <HintPath>..\..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration"> <Reference Include="Microsoft.WindowsAzure.Configuration, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath> <HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.WindowsAzure.Storage"> <Reference Include="Microsoft.WindowsAzure.Storage, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.2.0.6.1\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath> <HintPath>..\..\packages\WindowsAzure.Storage.2.0.6.1\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="Raven.Abstractions"> <Reference Include="Raven.Abstractions, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Abstractions.dll</HintPath> <HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Abstractions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Raven.Client.Embedded"> <Reference Include="Raven.Client.Embedded, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>..\..\packages\RavenDB.Embedded.2.5.2878\lib\net45\Raven.Client.Embedded.dll</HintPath> <HintPath>..\..\packages\RavenDB.Embedded.2.5.2878\lib\net45\Raven.Client.Embedded.dll</HintPath>
</Reference> </Reference>
<Reference Include="Raven.Client.Lightweight"> <Reference Include="Raven.Client.Lightweight, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Client.Lightweight.dll</HintPath> <HintPath>..\..\packages\RavenDB.Client.2.5.2878\lib\net45\Raven.Client.Lightweight.dll</HintPath>
</Reference> </Reference>
<Reference Include="Raven.Database"> <Reference Include="Raven.Database, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>..\..\packages\RavenDB.Database.2.5.2878\lib\net45\Raven.Database.dll</HintPath> <HintPath>..\..\packages\RavenDB.Database.2.5.2878\lib\net45\Raven.Database.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
@ -77,20 +78,22 @@
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Data.Services.Client" /> <Reference Include="System.Data.Services.Client" />
<Reference Include="System.Spatial, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Spatial, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll</HintPath> <HintPath>..\..\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="uhttpsharp, Version=0.1.5230.25021, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="uhttpsharp, Version=0.1.5230.25021, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\uHttpSharp.0.1.4.7\lib\net40\uhttpsharp.dll</HintPath> <HintPath>..\..\packages\uHttpSharp.0.1.4.7\lib\net40\uhttpsharp.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DummyAuthenticationHandler.cs" /> <Compile Include="Database\User.cs" />
<Compile Include="DummyFileServingHandler.cs" /> <Compile Include="RavenDatabaseAuthenticationHandler.cs" />
<Compile Include="RavenDatabaseFileServingHandler.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UInt32Converter.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
@ -102,6 +105,9 @@
<Name>libnpsharp</Name> <Name>libnpsharp</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="LICENSE.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -1,7 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="BCrypt-Official" version="0.1.109" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" /> <package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Microsoft.Data.Edm" version="5.2.0" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.2.0" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="1.8.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" /> <package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
<package id="RavenDB.Client" version="2.5.2878" targetFramework="net45" />
<package id="RavenDB.Database" version="2.5.2878" targetFramework="net45" />
<package id="RavenDB.Embedded" version="2.5.2878" targetFramework="net45" />
<package id="System.Spatial" version="5.2.0" targetFramework="net45" />
<package id="uHttpSharp" version="0.1.4.7" targetFramework="net45" /> <package id="uHttpSharp" version="0.1.4.7" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="2.0.6.1" targetFramework="net45" />
</packages> </packages>