Splitting the library in client and server parts + MIT licensing.

feature-npv2
Icedream 2014-05-30 20:23:04 +02:00
parent e9e309bc2f
commit 11486ab8e4
107 changed files with 737 additions and 2674 deletions

21
LICENSE.txt Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Carl Kittelberger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.30501.0 VisualStudioVersion = 12.0.30501.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libnpsharp", "src\libnpsharp\libnpsharp.csproj", "{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npmotd", "src\npmotd\npmotd.csproj", "{7887D77B-3C79-44C5-AB80-944B191321BB}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npmotd", "src\npmotd\npmotd.csproj", "{7887D77B-3C79-44C5-AB80-944B191321BB}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{587B7B8C-1605-46CF-BA39-AC9C72C1E860}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{587B7B8C-1605-46CF-BA39-AC9C72C1E860}"
@ -16,7 +14,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{587B7B
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npfile", "src\npfile\npfile.csproj", "{19EBF339-E076-4962-A671-5B44A978687D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npfile", "src\npfile\npfile.csproj", "{19EBF339-E076-4962-A671-5B44A978687D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npserv", "src\npserv\npserv.csproj", "{1FF77692-D07C-4131-95AE-21AD2A74CA11}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F86304A3-8257-4132-A0B3-AC3CE0E2EB3F}"
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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -24,10 +26,6 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Release|Any CPU.Build.0 = Release|Any CPU
{7887D77B-3C79-44C5-AB80-944B191321BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7887D77B-3C79-44C5-AB80-944B191321BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7887D77B-3C79-44C5-AB80-944B191321BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {7887D77B-3C79-44C5-AB80-944B191321BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7887D77B-3C79-44C5-AB80-944B191321BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {7887D77B-3C79-44C5-AB80-944B191321BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -35,13 +33,20 @@ Global
{19EBF339-E076-4962-A671-5B44A978687D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {19EBF339-E076-4962-A671-5B44A978687D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19EBF339-E076-4962-A671-5B44A978687D}.Debug|Any CPU.Build.0 = Debug|Any CPU {19EBF339-E076-4962-A671-5B44A978687D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19EBF339-E076-4962-A671-5B44A978687D}.Release|Any CPU.ActiveCfg = Release|Any CPU {19EBF339-E076-4962-A671-5B44A978687D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19EBF339-E076-4962-A671-5B44A978687D}.Release|Any CPU.Build.0 = Release|Any CPU {C6F941A5-82AF-456A-9B3A-752E5B001035}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FF77692-D07C-4131-95AE-21AD2A74CA11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C6F941A5-82AF-456A-9B3A-752E5B001035}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FF77692-D07C-4131-95AE-21AD2A74CA11}.Debug|Any CPU.Build.0 = Debug|Any CPU {C6F941A5-82AF-456A-9B3A-752E5B001035}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FF77692-D07C-4131-95AE-21AD2A74CA11}.Release|Any CPU.ActiveCfg = Release|Any CPU {C6F941A5-82AF-456A-9B3A-752E5B001035}.Release|Any CPU.Build.0 = Release|Any CPU
{1FF77692-D07C-4131-95AE-21AD2A74CA11}.Release|Any CPU.Build.0 = Release|Any CPU {1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7887D77B-3C79-44C5-AB80-944B191321BB} = {F86304A3-8257-4132-A0B3-AC3CE0E2EB3F}
{19EBF339-E076-4962-A671-5B44A978687D} = {F86304A3-8257-4132-A0B3-AC3CE0E2EB3F}
EndGlobalSection
EndGlobal EndGlobal

View File

@ -0,0 +1,11 @@
namespace NPSharp.Master.Messages.Data
{
/// <summary>
/// Represents keywords for a master server standard serverlist request.
/// </summary>
public enum MasterGetServersKeywords
{
Full = 0x01,
Empty = 0x02
}
}

View File

@ -1,7 +1,5 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using log4net; using log4net;
using NPSharp.Master.Messages.Data; using NPSharp.Master.Messages.Data;
@ -63,15 +61,3 @@ namespace NPSharp.Master.Messages.Client
public List<MasterGetServersKeywords> Keywords { get; set; } public List<MasterGetServersKeywords> Keywords { get; set; }
} }
} }
namespace NPSharp.Master.Messages.Data
{
/// <summary>
/// Represents keywords for a master server standard serverlist request.
/// </summary>
public enum MasterGetServersKeywords
{
Full = 0x01,
Empty = 0x02
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
namespace NPSharp.Master
{
public class DedicatedServerEntry
{
internal DedicatedServerEntry(IPAddress ip, params ushort[] ports)
{
IP = ip;
Ports = ports;
}
public IPAddress IP { get; private set; }
public ushort[] Ports { get; private set; }
internal byte[] Serialize(bool standardFormat = true)
{
if (standardFormat && IP.AddressFamily != AddressFamily.InterNetwork)
throw new InvalidOperationException("Can't serialize non-IPv4 addresses into standard format");
var buffer = new List<byte>();
if (standardFormat)
buffer.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(IP.GetHashCode()))); // TODO: GetHashCode == IP address as number???
else
{
// TODO: Implement extended serialization format for IP addresses!
throw new NotImplementedException("Extended serialization format not implemented yet");
}
foreach (var port in Ports)
buffer.AddRange(BitConverter.GetBytes((ushort) IPAddress.HostToNetworkOrder((short) port)));
return buffer.ToArray();
}
// TODO: Deserialize
}
}

View File

@ -32,7 +32,7 @@ namespace NPSharp.Master.Messages
get { return GetType().GetCustomAttribute<MasterClientMessageAttribute>().Name; } get { return GetType().GetCustomAttribute<MasterClientMessageAttribute>().Name; }
} }
internal MasterClientMessage Deserialize(Socket sock) internal static MasterClientMessage Deserialize(Socket sock)
{ {
while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead)) while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead))
{ {
@ -57,9 +57,21 @@ namespace NPSharp.Master.Messages
throw new ProtocolViolationException("Received incomplete header"); throw new ProtocolViolationException("Received incomplete header");
} }
return Deserialize(buffer.Take(length).ToArray());
}
catch (SocketException)
{
if (sock.Connected)
throw;
return null;
}
}
internal static MasterClientMessage Deserialize(byte[] buffer)
{
var header = buffer.Take(4).ToArray(); var header = buffer.Take(4).ToArray();
var command = Encoding.ASCII.GetString(buffer, 4, length - 4).Trim(); var command = Encoding.ASCII.GetString(buffer, 4, buffer.Length - 4).Trim();
var commandSplit = command.Split(new[] {'\t', '\r', '\n', '\0', ' '}, var commandSplit = command.Split(new[] { '\t', '\r', '\n', '\0', ' ' },
StringSplitOptions.RemoveEmptyEntries); StringSplitOptions.RemoveEmptyEntries);
var commandName = commandSplit[0]; var commandName = commandSplit[0];
@ -67,11 +79,11 @@ namespace NPSharp.Master.Messages
// Search for a message class which fits to the commandName // Search for a message class which fits to the commandName
var message = var message =
(MasterClientMessage) Activator.CreateInstance(Assembly.GetExecutingAssembly() (MasterClientMessage)Activator.CreateInstance(Assembly.GetExecutingAssembly()
.GetTypes() .GetTypes()
.Single( .Single(
t => t =>
t.IsSubclassOf(typeof (MasterClientMessage)) && t.IsSubclassOf(typeof(MasterClientMessage)) &&
t.GetCustomAttribute<MasterClientMessageAttribute>() t.GetCustomAttribute<MasterClientMessageAttribute>()
.Name.Equals(commandName, StringComparison.OrdinalIgnoreCase))); .Name.Equals(commandName, StringComparison.OrdinalIgnoreCase)));
@ -81,13 +93,6 @@ namespace NPSharp.Master.Messages
return message; return message;
} }
catch (SocketException)
{
if (sock.Connected)
throw;
return null;
}
}
internal byte[] SerializeInternal() internal byte[] SerializeInternal()
{ {

View File

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NPSharp.Master.Messages namespace NPSharp.Master.Messages
{ {

View File

@ -79,7 +79,6 @@ namespace NPSharp.NP
{ {
if (_rpc.Read() == null) if (_rpc.Read() == null)
break; break;
_log.Debug("Disconnected.");
} }
} }
catch (ProtocolViolationException error) catch (ProtocolViolationException error)

View File

@ -1,19 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1A5AC63A-250E-4BC8-B81A-822AC31F5E37}</ProjectGuid> <ProjectGuid>{C6F941A5-82AF-456A-9B3A-752E5B001035}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NPSharp</RootNamespace> <RootNamespace>NPSharp</RootNamespace>
<AssemblyName>libnpsharp</AssemblyName> <AssemblyName>npsharp_client</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages> <RestorePackages>true</RestorePackages>
</PropertyGroup> </PropertyGroup>
@ -21,120 +18,110 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;COMPILE_RPC,COMPILE_NP,COMPILE_AUTH</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants> <OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;COMPILE_RPC,COMPILE_NP,COMPILE_AUTH</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntDir>
<IntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntermediateOutputPath>
<BaseIntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</BaseIntermediateOutputPath>
<OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<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>..\..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="protobuf-net"> <Reference Include="protobuf-net">
<HintPath>..\..\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.XML" /> <Reference Include="System" />
<Reference Include="System.Xml.Serialization" /> <Reference Include="System.Core" />
<Reference Include="uhttpsharp, Version=0.1.5247.25275, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="System.Xml.Linq" />
<SpecificVersion>False</SpecificVersion> <Reference Include="System.Data.DataSetExtensions" />
<HintPath>..\..\packages\uHttpSharp.0.1.4.8\lib\net40\uhttpsharp.dll</HintPath> <Reference Include="Microsoft.CSharp" />
</Reference> <Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Master\Messages\Client\MasterGetServersExtendedMessage.cs" /> <Compile Include="Authentication\SessionAuthenticationClient.cs" />
<Compile Include="Master\Messages\Client\MasterGetServersMessage.cs" />
<Compile Include="Master\Messages\MasterServerMessage.cs" />
<Compile Include="Master\Messages\MasterClientMessage.cs" />
<Compile Include="Master\Messages\MasterClientMessageAttribute.cs" />
<Compile Include="Master\Messages\MasterServerMessageAttribute.cs" />
<Compile Include="NP\NPAuthenticationResult.cs" />
<Compile Include="Authentication\SessionAuthenticationResult.cs" /> <Compile Include="Authentication\SessionAuthenticationResult.cs" />
<Compile Include="Authentication\SessionAuthenticationServer.cs" /> <Compile Include="Master\Client\MasterGetServersKeywords.cs" />
<Compile Include="Events\ClientEventArgs.cs" /> <Compile Include="Master\Client\MasterGetServersMessage.cs" />
<Compile Include="Events\ClientEventHandler.cs" /> <Compile Include="Master\DedicatedServerEntry.cs" />
<Compile Include="Handlers\IAuthenticationHandler.cs" /> <Compile Include="Master\MasterClientMessage.cs" />
<Compile Include="Handlers\IFileServingHandler.cs" /> <Compile Include="Master\MasterClientMessageAttribute.cs" />
<Compile Include="Handlers\IFriendsHandler.cs" /> <Compile Include="NP\NPAuthenticationResult.cs" />
<Compile Include="Handlers\IUserAvatarHandler.cs" />
<Compile Include="NP\NPClient.cs" /> <Compile Include="NP\NPClient.cs" />
<Compile Include="NP\NPFileException.cs" /> <Compile Include="NP\NPFileException.cs" />
<Compile Include="NP\NPServer.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="NP\NPServerClient.cs" />
<Compile Include="RPC\Messages\Data\PresenceState.cs" />
<Compile Include="RPC\Messages\Client\AuthenticateRegisterServerMessage.cs" /> <Compile Include="RPC\Messages\Client\AuthenticateRegisterServerMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateRegisterServerResultMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateUserGroupMessage.cs" />
<Compile Include="RPC\Messages\Client\AuthenticateValidateTicketMessage.cs" /> <Compile Include="RPC\Messages\Client\AuthenticateValidateTicketMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateValidateTicketResultMessage.cs" />
<Compile Include="RPC\Messages\Client\AuthenticateWithDetailsMessage.cs" /> <Compile Include="RPC\Messages\Client\AuthenticateWithDetailsMessage.cs" />
<Compile Include="RPC\Messages\Client\AuthenticateWithKeyMessage.cs" /> <Compile Include="RPC\Messages\Client\AuthenticateWithKeyMessage.cs" />
<Compile Include="RPC\Messages\Data\FriendDetails.cs" />
<Compile Include="RPC\Messages\Client\FriendsSetSteamIDMessage.cs" />
<Compile Include="RPC\Messages\Client\FriendsGetProfileDataMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsGetProfileDataResultMessage.cs" />
<Compile Include="RPC\Messages\Client\FriendsGetUserAvatarMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsGetUserAvatarResultMessage.cs" />
<Compile Include="RPC\Messages\Data\FriendsPresence.cs" />
<Compile Include="RPC\Messages\Server\FriendsPresenceMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsRosterMessage.cs" />
<Compile Include="RPC\Messages\Client\FriendsSetPresenceMessage.cs" />
<Compile Include="RPC\Messages\Data\ProfileData.cs" />
<Compile Include="RPC\RPCClientStream.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateExternalStatusMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateResultMessage.cs" />
<Compile Include="RPC\Messages\Client\AuthenticateWithTokenMessage.cs" /> <Compile Include="RPC\Messages\Client\AuthenticateWithTokenMessage.cs" />
<Compile Include="RPC\Messages\Server\CloseAppMessage.cs" /> <Compile Include="RPC\Messages\Client\FriendsGetProfileDataMessage.cs" />
<Compile Include="RPC\Messages\Server\HelloMessage.cs" /> <Compile Include="RPC\Messages\Client\FriendsGetUserAvatarMessage.cs" />
<Compile Include="RPC\Messages\Client\FriendsSetPresenceMessage.cs" />
<Compile Include="RPC\Messages\Client\FriendsSetSteamIDMessage.cs" />
<Compile Include="RPC\Messages\Client\MessagingSendDataMessage.cs" /> <Compile Include="RPC\Messages\Client\MessagingSendDataMessage.cs" />
<Compile Include="RPC\Messages\RPCMessage.cs" /> <Compile Include="RPC\Messages\Client\StorageGetPublisherFileMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageGetUserFileMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageSendRandomStringMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageWriteUserFileMessage.cs" />
<Compile Include="RPC\Messages\Data\FriendDetails.cs" />
<Compile Include="RPC\Messages\Data\FriendsPresence.cs" />
<Compile Include="RPC\Messages\Data\PresenceState.cs" />
<Compile Include="RPC\Messages\Data\ProfileData.cs" />
<Compile Include="RPC\Messages\Data\Ticket.cs" />
<Compile Include="RPC\Messages\Data\TicketValidationResult.cs" />
<Compile Include="RPC\Messages\PacketAttribute.cs" /> <Compile Include="RPC\Messages\PacketAttribute.cs" />
<Compile Include="RPC\Messages\RPCClientMessage.cs" /> <Compile Include="RPC\Messages\RPCClientMessage.cs" />
<Compile Include="RPC\Messages\RPCMessage.cs" />
<Compile Include="RPC\Messages\RPCServerMessage.cs" /> <Compile Include="RPC\Messages\RPCServerMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageGetUserFileMessage.cs" /> <Compile Include="RPC\Messages\Server\AuthenticateExternalStatusMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageGetPublisherFileMessage.cs" /> <Compile Include="RPC\Messages\Server\AuthenticateRegisterServerResultMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateResultMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateUserGroupMessage.cs" />
<Compile Include="RPC\Messages\Server\AuthenticateValidateTicketResultMessage.cs" />
<Compile Include="RPC\Messages\Server\CloseAppMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsGetProfileDataResultMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsGetUserAvatarResultMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsPresenceMessage.cs" />
<Compile Include="RPC\Messages\Server\FriendsRosterMessage.cs" />
<Compile Include="RPC\Messages\Server\HelloMessage.cs" />
<Compile Include="RPC\Messages\Server\StoragePublisherFileMessage.cs" /> <Compile Include="RPC\Messages\Server\StoragePublisherFileMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageSendRandomStringMessage.cs" />
<Compile Include="RPC\Messages\Server\StorageUserFileMessage.cs" /> <Compile Include="RPC\Messages\Server\StorageUserFileMessage.cs" />
<Compile Include="RPC\Messages\Client\StorageWriteUserFileMessage.cs" />
<Compile Include="RPC\Messages\Server\StorageWriteUserFileResultMessage.cs" /> <Compile Include="RPC\Messages\Server\StorageWriteUserFileResultMessage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="RPC\RPCClientStream.cs" />
<Compile Include="Authentication\SessionAuthenticationClient.cs" />
<Compile Include="RPC\RPCServerStream.cs" />
<Compile Include="RPC\RPCStream.cs" /> <Compile Include="RPC\RPCStream.cs" />
<Compile Include="Steam\CSteamID.cs" /> <Compile Include="Steam\CSteamID.cs" />
<Compile Include="Steam\EAccountType.cs" /> <Compile Include="Steam\EAccountType.cs" />
<Compile Include="Steam\EUniverse.cs" /> <Compile Include="Steam\EUniverse.cs" />
<Compile Include="Steam\InteropHelp.cs" /> <Compile Include="Steam\InteropHelp.cs" />
<Compile Include="Steam\SteamID_t.cs" /> <Compile Include="Steam\SteamID_t.cs" />
<Compile Include="RPC\Messages\Data\Ticket.cs" />
<Compile Include="RPC\Messages\Data\TicketValidationResult.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Master\README.txt" /> <None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Steam\README.txt" /> <Content Include="Steam\README.txt" />
</ItemGroup> </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')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Aktivieren Sie die Wiederherstellung von NuGet-Paketen, um die fehlende Datei herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- 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.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
@ -142,10 +129,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</Project> </Project>

View File

@ -1,28 +1,26 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden // Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind. // die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("NPSharp client library")]
[assembly: AssemblyTitle("npserv")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")] [assembly: AssemblyCompany("Carl Kittelberger")]
[assembly: AssemblyProduct("npserv")] [assembly: AssemblyProduct("NPSharp")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2014")] [assembly: AssemblyCopyright("© 2014 Carl Kittelberger")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar // 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 // 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. // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("eb49c20b-b649-42fa-bff4-f62aba36e0b0")]
[assembly: Guid("098bf075-4a4b-437c-9283-011ffb6ff277")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
// //
@ -34,6 +32,8 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben: // übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0")]
[assembly: AssemblyVersion("1.0.0.0")] // Make internals visible to the server counterpart of this library
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: InternalsVisibleTo("npsharp_server")]

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.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" />
</packages>

View File

@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using NPSharp.Master.Messages.Data;
namespace NPSharp.Master.Messages.Client
{
/// <summary>
/// Represents a request message for the master server for an extended dedicated server list.
/// </summary>
[MasterClientMessage("getserversExt")]
public class MasterGetServersExtendedMessage : MasterClientMessage
{
private static readonly ILog Log;
static MasterGetServersExtendedMessage()
{
Log = LogManager.GetLogger(typeof (MasterGetServersExtendedMessage));
}
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, string.Join(" ", Keywords.Select(k => k.ToString())));
}
protected override void Deserialize(string[] arguments)
{
GameName = arguments[0];
ProtocolVersion = uint.Parse(arguments[1]);
foreach (var kw in arguments.Skip(2))
{
switch (kw.ToLower())
{
case "empty":
Keywords.Add(MasterGetServersExtendedKeywords.Empty);
break;
case "full":
Keywords.Add(MasterGetServersExtendedKeywords.Full);
break;
case "ipv4":
Keywords.Add(MasterGetServersExtendedKeywords.InternetProtocolVersion4);
break;
case "ipv6":
Keywords.Add(MasterGetServersExtendedKeywords.InternetProtocolVersion6);
break;
default:
Log.WarnFormat("{0}: weird keyword {1}", Name, kw);
break;
}
}
}
/// <summary>
/// The game for which servers should be fetched
/// </summary>
public string GameName { get; set; }
/// <summary>
/// The protocol version of the dedicated servers to search for
/// </summary>
public uint ProtocolVersion { get; set; }
/// <summary>
/// Extra keywords to take care of when generating the server list
/// </summary>
public List<MasterGetServersExtendedKeywords> Keywords { get; set; }
}
}
namespace NPSharp.Master.Messages.Data
{
/// <summary>
/// Represents keywords for a master server standard serverlist request.
/// </summary>
public enum MasterGetServersExtendedKeywords
{
Full = 0x01,
Empty = 0x02,
InternetProtocolVersion4 = 0x04,
InternetProtocolVersion6 = 0x08
}
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

90
src/masterlist/Program.cs Normal file
View File

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
namespace NPSharp.CommandLine.MasterList
{
class Program
{
static void Main(string[] args)
{
// log4net setup
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
{
var appender = new ConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } });
}
else
{
var appender = new ColoredConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Debug,
ForeColor = ColoredConsoleAppender.Colors.Cyan | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Info,
ForeColor = ColoredConsoleAppender.Colors.Green | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Warn,
ForeColor = ColoredConsoleAppender.Colors.Purple | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Error,
ForeColor = ColoredConsoleAppender.Colors.Red | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Fatal,
ForeColor = ColoredConsoleAppender.Colors.White | ColoredConsoleAppender.Colors.HighIntensity,
BackColor = ColoredConsoleAppender.Colors.Red
});
appender.ActivateOptions();
BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } });
}
var log = LogManager.GetLogger("Main");
// Arguments
if (args.Length < 1)
{
log.ErrorFormat("Needs at least 1 argument: hostname [masterport, defaults to 27015]");
return;
}
var hostname = args[0];
var masterport = (ushort)27015;
ushort.TryParse(args[1], out masterport);
}
}
}

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3321608C-2063-4AC4-AF03-5858A7A2B1D8}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NPSharp.CommandLine.MasterList</RootNamespace>
<AssemblyName>masterlist</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntDir>
<IntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntermediateOutputPath>
<BaseIntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</BaseIntermediateOutputPath>
<OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<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>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\client\NPSharp.Client.csproj">
<Project>{c6f941a5-82af-456a-9b3a-752e5b001035}</Project>
<Name>NPSharp.Client</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Aktivieren Sie die Wiederherstellung von NuGet-Paketen, um die fehlende Datei herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net45" />
</packages>

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using log4net; using log4net;
using log4net.Appender; using log4net.Appender;
@ -24,63 +23,8 @@ namespace NPSharp.CommandLine.File
private static void Main(string[] args) private static void Main(string[] args)
{ {
// log4net setup // log4net setup
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) SetupLog4Net();
{ var log = LogManager.GetLogger("Main");
var appender = new ConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
BasicConfigurator.Configure(new IAppender[]
{appender, new DebugAppender {Layout = appender.Layout, Threshold = Level.All}});
}
else
{
var appender = new ColoredConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Debug,
ForeColor = ColoredConsoleAppender.Colors.Cyan | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Info,
ForeColor = ColoredConsoleAppender.Colors.Green | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Warn,
ForeColor = ColoredConsoleAppender.Colors.Purple | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Error,
ForeColor = ColoredConsoleAppender.Colors.Red | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Fatal,
ForeColor = ColoredConsoleAppender.Colors.White | ColoredConsoleAppender.Colors.HighIntensity,
BackColor = ColoredConsoleAppender.Colors.Red
});
appender.ActivateOptions();
BasicConfigurator.Configure(new IAppender[]
{appender, new DebugAppender {Layout = appender.Layout, Threshold = Level.All}});
}
ILog log = LogManager.GetLogger("Main");
// Arguments // Arguments
if (args.Length < 4) if (args.Length < 4)
@ -120,13 +64,13 @@ 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) if (!np.AuthenticateWithToken(ah.SessionToken).Result)
{ {
np.Disconnect(); np.Disconnect();
log.Error("Authentication to NP server failed."); log.Error("Authentication to NP server failed.");
return; return;
} }
log.Info("NP connection successful, authenticating...");
// HTTP server // HTTP server
@ -148,8 +92,68 @@ namespace NPSharp.CommandLine.File
log.InfoFormat("HTTP server now running on port {0}.", hport); log.InfoFormat("HTTP server now running on port {0}.", hport);
log.InfoFormat("Access publisher files through http://{0}:{1}/pub/<file>", IPAddress.Any, hport); log.InfoFormat("Access publisher files through http://{0}:{1}/pub/<file>", IPAddress.Any, hport);
log.InfoFormat("Access user files through http://{0}:{1}/user/<file>", IPAddress.Any, hport); log.InfoFormat("Access user files through http://{0}:{1}/user/<file>", IPAddress.Any, hport);
Thread.Sleep(Timeout.Infinite); log.Info("You can shut down the HTTP server by pressing any key.");
Console.ReadKey();
} }
} }
private static void SetupLog4Net()
{
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
{
var appender = new ConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } });
}
else
{
var appender = new ColoredConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Debug,
ForeColor = ColoredConsoleAppender.Colors.Cyan | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Info,
ForeColor = ColoredConsoleAppender.Colors.Green | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Warn,
ForeColor = ColoredConsoleAppender.Colors.Purple | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Error,
ForeColor = ColoredConsoleAppender.Colors.Red | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(new ColoredConsoleAppender.LevelColors
{
Level = Level.Fatal,
ForeColor = ColoredConsoleAppender.Colors.White | ColoredConsoleAppender.Colors.HighIntensity,
BackColor = ColoredConsoleAppender.Colors.Red
});
appender.ActivateOptions();
BasicConfigurator.Configure(new IAppender[] { appender, new DebugAppender { Layout = appender.Layout, Threshold = Level.All } });
}
}
} }
} }

View File

@ -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("npfile")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("npfile")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2014")]
[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("549e5fde-a94d-4154-9577-5743f8be3ed3")]
// 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.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -42,8 +42,9 @@
<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>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -56,16 +57,18 @@
<Compile Include="NP2HTTPPublisherFileHandler.cs" /> <Compile Include="NP2HTTPPublisherFileHandler.cs" />
<Compile Include="NP2HTTPUserFileHandler.cs" /> <Compile Include="NP2HTTPUserFileHandler.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\libnpsharp\libnpsharp.csproj"> <Folder Include="Properties\" />
<Project>{1a5ac63a-250e-4bc8-b81a-822ac31f5e37}</Project> </ItemGroup>
<Name>libnpsharp</Name> <ItemGroup>
<ProjectReference Include="..\client\NPSharp.Client.csproj">
<Project>{c6f941a5-82af-456a-9b3a-752e5b001035}</Project>
<Name>NPSharp.Client</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<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="5.0.8" 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.4.8" targetFramework="net45" />
</packages> </packages>

View File

@ -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 MOTD test client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Icedream")]
[assembly: AssemblyProduct("NPSharp Library")]
[assembly: AssemblyCopyright("© 2014 Icedream")]
[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("b91f9ba4-757a-4c72-b12a-c3e1f1b05715")]
// 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("0.1.*")]
[assembly: AssemblyFileVersion("0.1")]

View File

@ -47,16 +47,18 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\libnpsharp\libnpsharp.csproj"> <Folder Include="Properties\" />
<Project>{1a5ac63a-250e-4bc8-b81a-822ac31f5e37}</Project> </ItemGroup>
<Name>libnpsharp</Name> <ItemGroup>
<ProjectReference Include="..\client\NPSharp.Client.csproj">
<Project>{c6f941a5-82af-456a-9b3a-752e5b001035}</Project>
<Name>NPSharp.Client</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -1,76 +0,0 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using log4net;
using NPSharp.CommandLine.Server.Database;
using NPSharp.Handlers;
using NPSharp.NP;
using NPSharp.RPC.Messages.Data;
using NPSharp.Steam;
namespace NPSharp.CommandLine.Server
{
internal class BrightstarDatabaseAuthenticationHandler : IAuthenticationHandler
{
private readonly BrightstarDatabaseContext _db;
private readonly ILog _log;
public BrightstarDatabaseAuthenticationHandler(BrightstarDatabaseContext database)
{
_log = LogManager.GetLogger("AuthHandler");
_db = database;
}
public NPAuthenticationResult AuthenticateUser(NPServerClient client, string username, string password)
{
// Nah, authenticating this way is deprecated as fuck.
return new NPAuthenticationResult();
}
public NPAuthenticationResult AuthenticateUser(NPServerClient client, string token)
{
var ar = new NPAuthenticationResult();
// Check if token is valid
_db.ValidateSession(token, session =>
{
if (session == null)
{
return;
}
ar =
new NPAuthenticationResult(new CSteamID
{
AccountID = session.User.UserNumber,
AccountInstance = 1,
AccountType = EAccountType.Individual,
AccountUniverse = EUniverse.Public
});
_log.DebugFormat("Deleting validated session {0}", session.Id);
});
_db.SaveChanges();
return ar;
}
public NPAuthenticationResult AuthenticateServer(NPServerClient client, string licenseKey)
{
// TODO: AuthenticateServer
throw new NotImplementedException();
}
public TicketValidationResult ValidateTicket(NPServerClient client, NPServerClient server)
{
// TODO: ValidateTicket
throw new NotImplementedException();
}
~BrightstarDatabaseAuthenticationHandler()
{
_db.Dispose();
}
}
}

View File

@ -1,93 +0,0 @@
using System.Globalization;
using System.Linq;
using System.Text;
using NPSharp.CommandLine.Server.Database;
using NPSharp.Handlers;
using NPSharp.NP;
namespace NPSharp.CommandLine.Server
{
internal class BrightstarDatabaseFileServingHandler : IFileServingHandler
{
private readonly BrightstarDatabaseContext _db;
public BrightstarDatabaseFileServingHandler(BrightstarDatabaseContext database)
{
//_database = database;
_db = database;
}
public byte[] ReadUserFile(NPServerClient client, string file)
{
var resultEnum =
_db.UserFiles.Where(
uf =>
uf.User.Id == client.UserID.AccountID.ToString(CultureInfo.InvariantCulture) &&
uf.FileName == file);
return resultEnum.Any() ? resultEnum.Single().FileData : GetDefaultUserFile(file);
}
public byte[] ReadPublisherFile(NPServerClient client, string file)
{
var resultEnum =
_db.PublisherFiles.Where(pf => pf.FileName == file).ToArray();
return resultEnum.Any() ? resultEnum.Single().FileData : GetDefaultPublisherFile(file);
}
public void WriteUserFile(NPServerClient client, string file, byte[] data)
{
var resultEnum =
_db.UserFiles.Where(
uf =>
uf.User.Id == client.UserID.AccountID.ToString(CultureInfo.InvariantCulture) &&
uf.FileName == file)
.ToArray();
var userFile = resultEnum.Any() ? resultEnum.Single() : _db.UserFiles.Create();
userFile.FileName = file;
userFile.FileData = data;
userFile.User = _db.Users.Single(u => u.Id == client.UserID.AccountID.ToString(CultureInfo.InvariantCulture));
_db.SaveChanges();
}
~BrightstarDatabaseFileServingHandler()
{
_db.Dispose();
}
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;
}
}
}
}

View File

@ -1,498 +0,0 @@
using System;
using System.Collections.Generic;
using BrightstarDB.Client;
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
public partial class BrightstarDatabaseContext : BrightstarEntityContext
{
private static readonly EntityMappingStore TypeMappings;
static BrightstarDatabaseContext()
{
TypeMappings = new EntityMappingStore();
var provider = new ReflectionMappingProvider();
provider.AddMappingsForType(TypeMappings, typeof (IBan));
TypeMappings.SetImplMapping<IBan, Ban>();
provider.AddMappingsForType(TypeMappings, typeof (ICheatDetection));
TypeMappings.SetImplMapping<ICheatDetection, CheatDetection>();
provider.AddMappingsForType(TypeMappings, typeof (IFriend));
TypeMappings.SetImplMapping<IFriend, Friend>();
provider.AddMappingsForType(TypeMappings, typeof (IPublisherFile));
TypeMappings.SetImplMapping<IPublisherFile, PublisherFile>();
provider.AddMappingsForType(TypeMappings, typeof (ISession));
TypeMappings.SetImplMapping<ISession, Session>();
provider.AddMappingsForType(TypeMappings, typeof (IUser));
TypeMappings.SetImplMapping<IUser, User>();
provider.AddMappingsForType(TypeMappings, typeof (IUserFile));
TypeMappings.SetImplMapping<IUserFile, UserFile>();
}
/// <summary>
/// Initialize a new entity context using the specified BrightstarDB
/// Data Object Store connection
/// </summary>
/// <param name="dataObjectStore">The connection to the BrightstarDB Data Object Store that will provide the entity objects</param>
/// <param name="typeMappings">
/// OPTIONAL: A <see cref="EntityMappingStore" /> that overrides the default mappings generated
/// by reflection.
/// </param>
public BrightstarDatabaseContext(IDataObjectStore dataObjectStore, EntityMappingStore typeMappings = null)
: base(typeMappings ?? TypeMappings, dataObjectStore)
{
InitializeContext();
}
/// <summary>
/// Initialize a new entity context using the specified Brightstar connection string
/// </summary>
/// <param name="connectionString">The connection to be used to connect to an existing BrightstarDB store</param>
/// <param name="enableOptimisticLocking">OPTIONAL: If set to true optmistic locking will be applied to all entity updates</param>
/// <param name="updateGraphUri">
/// OPTIONAL: The URI identifier of the graph to be updated with any new triples created by operations on the store. If
/// not defined, the default graph in the store will be updated.
/// </param>
/// <param name="datasetGraphUris">
/// OPTIONAL: The URI identifiers of the graphs that will be queried to retrieve entities and their properties.
/// If not defined, all graphs in the store will be queried.
/// </param>
/// <param name="versionGraphUri">
/// OPTIONAL: The URI identifier of the graph that contains version number statements for entities.
/// If not defined, the <paramref name="updateGraphUri" /> will be used.
/// </param>
/// <param name="typeMappings">
/// OPTIONAL: A <see cref="EntityMappingStore" /> that overrides the default mappings generated
/// by reflection.
/// </param>
public BrightstarDatabaseContext(
string connectionString,
bool? enableOptimisticLocking = null,
string updateGraphUri = null,
IEnumerable<string> datasetGraphUris = null,
string versionGraphUri = null,
EntityMappingStore typeMappings = null
)
: base(
typeMappings ?? TypeMappings, connectionString, enableOptimisticLocking, updateGraphUri,
datasetGraphUris, versionGraphUri)
{
InitializeContext();
}
/// <summary>
/// Initialize a new entity context using the specified Brightstar
/// connection string retrieved from the configuration.
/// </summary>
/// <param name="typeMappings">
/// OPTIONAL: A <see cref="EntityMappingStore" /> that overrides the default mappings generated
/// by reflection.
/// </param>
public BrightstarDatabaseContext(EntityMappingStore typeMappings = null) : base(typeMappings ?? TypeMappings)
{
InitializeContext();
}
// specified target graphs
/// <summary>
/// Initialize a new entity context using the specified Brightstar
/// connection string retrieved from the configuration and the
/// </summary>
/// <param name="updateGraphUri">
/// The URI identifier of the graph to be updated with any new triples created by operations on the store. If
/// set to null, the default graph in the store will be updated.
/// </param>
/// <param name="datasetGraphUris">
/// The URI identifiers of the graphs that will be queried to retrieve entities and their properties.
/// If set to null, all graphs in the store will be queried.
/// </param>
/// <param name="versionGraphUri">
/// The URI identifier of the graph that contains version number statements for entities.
/// If set to null, the value of <paramref name="updateGraphUri" /> will be used.
/// </param>
/// <param name="typeMappings">
/// OPTIONAL: A <see cref="EntityMappingStore" /> that overrides the default mappings generated
/// by reflection.
/// </param>
public BrightstarDatabaseContext(
string updateGraphUri,
IEnumerable<string> datasetGraphUris,
string versionGraphUri,
EntityMappingStore typeMappings = null
) : base(typeMappings ?? TypeMappings, updateGraphUri, datasetGraphUris, versionGraphUri)
{
InitializeContext();
}
public IEntitySet<IBan> Bans { get; private set; }
public IEntitySet<ICheatDetection> CheatDetections { get; private set; }
public IEntitySet<IFriend> Friends { get; private set; }
public IEntitySet<IPublisherFile> PublisherFiles { get; private set; }
public IEntitySet<ISession> Sessions { get; private set; }
public IEntitySet<IUser> Users { get; private set; }
public IEntitySet<IUserFile> UserFiles { get; private set; }
private void InitializeContext()
{
Bans = new BrightstarEntitySet<IBan>(this);
CheatDetections = new BrightstarEntitySet<ICheatDetection>(this);
Friends = new BrightstarEntitySet<IFriend>(this);
PublisherFiles = new BrightstarEntitySet<IPublisherFile>(this);
Sessions = new BrightstarEntitySet<ISession>(this);
Users = new BrightstarEntitySet<IUser>(this);
UserFiles = new BrightstarEntitySet<IUserFile>(this);
}
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class Ban : BrightstarEntityObject, IBan
{
public Ban(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public Ban()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.IBan
public IUser User
{
get { return GetRelatedObject<IUser>("User"); }
}
public String Reason
{
get { return GetRelatedProperty<String>("Reason"); }
set { SetRelatedProperty("Reason", value); }
}
public DateTime ExpiryTime
{
get { return GetRelatedProperty<DateTime>("ExpiryTime"); }
set { SetRelatedProperty("ExpiryTime", value); }
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class CheatDetection : BrightstarEntityObject, ICheatDetection
{
public CheatDetection(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public CheatDetection()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.ICheatDetection
public IUser User
{
get { return GetRelatedObject<IUser>("User"); }
}
public UInt32 CheatId
{
get { return GetRelatedProperty<UInt32>("CheatId"); }
set { SetRelatedProperty("CheatId", value); }
}
public String Reason
{
get { return GetRelatedProperty<String>("Reason"); }
set { SetRelatedProperty("Reason", value); }
}
public DateTime ExpiryTime
{
get { return GetRelatedProperty<DateTime>("ExpiryTime"); }
set { SetRelatedProperty("ExpiryTime", value); }
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class Friend : BrightstarEntityObject, IFriend
{
public Friend(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public Friend()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.IFriend
public IUser User
{
get { return GetRelatedObject<IUser>("User"); }
}
public UInt32 FriendUserId
{
get { return GetRelatedProperty<UInt32>("FriendUserId"); }
set { SetRelatedProperty("FriendUserId", value); }
}
public String FriendName
{
get { return GetRelatedProperty<String>("FriendName"); }
set { SetRelatedProperty("FriendName", value); }
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class PublisherFile : BrightstarEntityObject, IPublisherFile
{
public PublisherFile(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public PublisherFile()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.IPublisherFile
public String FileName
{
get { return GetRelatedProperty<String>("FileName"); }
set { SetRelatedProperty("FileName", value); }
}
public Byte[] FileData
{
get { return GetRelatedProperty<Byte[]>("FileData"); }
set { SetRelatedProperty("FileData", value); }
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class Session : BrightstarEntityObject, ISession
{
public Session(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public Session()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.ISession
public IUser User
{
get { return GetRelatedObject<IUser>("User"); }
}
public DateTime ExpiryTime
{
get { return GetRelatedProperty<DateTime>("ExpiryTime"); }
set { SetRelatedProperty("ExpiryTime", value); }
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class User : BrightstarEntityObject, IUser
{
public User(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public User()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.IUser
public String UserName
{
get { return GetRelatedProperty<String>("UserName"); }
set { SetRelatedProperty("UserName", value); }
}
public String UserMail
{
get { return GetRelatedProperty<String>("UserMail"); }
set { SetRelatedProperty("UserMail", value); }
}
public UInt32 UserNumber
{
get { return GetRelatedProperty<UInt32>("UserNumber"); }
set { SetRelatedProperty("UserNumber", value); }
}
public String PasswordHash
{
get { return GetRelatedProperty<String>("PasswordHash"); }
set { SetRelatedProperty("PasswordHash", value); }
}
public DateTime LastLogin
{
get { return GetRelatedProperty<DateTime>("LastLogin"); }
set { SetRelatedProperty("LastLogin", value); }
}
public ICollection<ISession> Sessions
{
get { return GetRelatedObjects<ISession>("Sessions"); }
set
{
if (value == null) throw new ArgumentNullException("value");
SetRelatedObjects("Sessions", value);
}
}
public ICollection<IBan> Bans
{
get { return GetRelatedObjects<IBan>("Bans"); }
set
{
if (value == null) throw new ArgumentNullException("value");
SetRelatedObjects("Bans", value);
}
}
public ICollection<ICheatDetection> CheatDetections
{
get { return GetRelatedObjects<ICheatDetection>("CheatDetections"); }
set
{
if (value == null) throw new ArgumentNullException("value");
SetRelatedObjects("CheatDetections", value);
}
}
public ICollection<IUserFile> UserFiles
{
get { return GetRelatedObjects<IUserFile>("UserFiles"); }
set
{
if (value == null) throw new ArgumentNullException("value");
SetRelatedObjects("UserFiles", value);
}
}
public ICollection<IFriend> FriendIDs
{
get { return GetRelatedObjects<IFriend>("FriendIDs"); }
set
{
if (value == null) throw new ArgumentNullException("value");
SetRelatedObjects("FriendIDs", value);
}
}
#endregion
}
}
namespace NPSharp.CommandLine.Server.Database
{
public class UserFile : BrightstarEntityObject, IUserFile
{
public UserFile(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject)
{
}
public UserFile()
{
}
public String Id
{
get { return GetIdentity(); }
set { SetIdentity(value); }
}
#region Implementation of NPSharp.CommandLine.Server.Database.IUserFile
public IUser User
{
get { return GetRelatedObject<IUser>("User"); }
set { SetRelatedObject("User", value); }
}
public String FileName
{
get { return GetRelatedProperty<String>("FileName"); }
set { SetRelatedProperty("FileName", value); }
}
public Byte[] FileData
{
get { return GetRelatedProperty<Byte[]>("FileData"); }
set { SetRelatedProperty("FileData", value); }
}
#endregion
}
}

View File

@ -1,96 +0,0 @@
using System;
using System.Linq;
namespace NPSharp.CommandLine.Server.Database
{
public partial class BrightstarDatabaseContext
{
public IUser CreateUser(string name, string email, string password)
{
if (UserExists(name))
throw new DatabaseUserExistsException();
var user = Users.Create();
user.UserName = name;
user.UserMail = email;
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(password);
user.UserNumber = _genUserNumber(/*user.Id*/);
return user;
}
private uint _genUserNumber(/*string userId*/)
{
/*
// for some reason we sometimes get full URIs here.
userId = userId.Split('/').Last().Replace("-", "");
// Since the string is a hexified UNIQUE identifier,
// use the numeric representation of it.
var userNum = uint.Parse(userId, NumberStyles.HexNumber);
*/
// The above doesn't work since the GUID has a few bits too much :P
// So instead - even though taking more queries - we will use the user
// count to approximate a new user ID.
var userNum = (uint)Users.Count() + 1;
while (Users.Count(u => u.UserNumber == userNum) > 0)
userNum++;
return userNum;
}
public bool UserExists(string userName)
{
return GetUser(userName) != null;
}
public IUser GetUser(string userName)
{
var users = Users.Where(u => u.UserName == userName).ToArray();
return users.Any() ? users.Single() : null;
}
/// <summary>
/// Creates a user session.
/// </summary>
/// <param name="user">The user to assign the session to.</param>
/// <param name="validTimeSpan">The time span in seconds. Default: 3 minutes.</param>
/// <returns>The newly created user session</returns>
public ISession CreateSession(IUser user, uint validTimeSpan = 3 * 60)
{
var session = Sessions.Create();
session.ExpiryTime = DateTime.Now + TimeSpan.FromSeconds(validTimeSpan);
user.Sessions.Add(session);
return session;
}
/// <summary>
/// Tries to find the wanted session and drops it if it's valid,
/// therefore "using it".
/// </summary>
/// <param name="sessionToken">The token of the wanted session</param>
/// <param name="callback">The callback to use for session results (goes for both invalid and valid sessions)</param>
/// <returns>The found session if the session is validated successfully, otherwise null.</returns>
public void ValidateSession(string sessionToken, Action<ISession> callback)
{
var sessions = Sessions
.Where(s => s.Id == sessionToken).ToArray() // database level query
.Where(s => s.ExpiryTime > DateTime.Now).ToArray(); // local level query (seems like this isn't supported [yet])
// We have to use a callback here since deleting the object from database
// will also release it from .NET's management and therefore makes the object
// invalid.
if (!sessions.Any())
callback(null);
else
{
var session = sessions.Single();
callback(session);
DeleteObject(session);
}
}
}
}

View File

@ -1,918 +0,0 @@
<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="EnvDTE80" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#
var code = new CodeGenerationTools(this);
var helper = new Helper(this);
var namespaceName = code.VsNamespaceSuggestion();
var contextClassName = System.IO.Path.GetFileNameWithoutExtension(this.Host.TemplateFile);
WriteHeader(helper.GetExtraUsings().ToArray());
BeginNamespace(code, namespaceName);
WriteContextClass(code, helper, contextClassName);
EndNamespace(namespaceName);
foreach(var i in helper.GetDecoratedInterfaces()) {
WriteEntityClass(code, helper, i);
}
#>
<#+
public void WriteHeader(params string[] extraUsings) {
#>
// -----------------------------------------------------------------------
// <autogenerated>
// This code was generated from a template.
//
// Changes to this file may cause incorrect behaviour and will be lost
// if the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using BrightstarDB.Client;
using BrightstarDB.EntityFramework;
<#=String.Join(String.Empty, extraUsings.Select(u => "using " + u + ";" + Environment.NewLine).ToArray())#>
<#+
}
public void BeginNamespace(CodeGenerationTools code, string namespaceName)
{
CodeRegion region = new CodeRegion(this);
if (!String.IsNullOrEmpty(namespaceName))
{
#>
namespace <#=code.EscapeNamespace(namespaceName) #>
{
<#+
PushIndent(CodeRegion.GetIndent(1));
}
}
public void EndNamespace(string namespaceName) {
if (!String.IsNullOrEmpty(namespaceName)) {
PopIndent();
#>
}
<#+
}
}
private void WriteContextClass(CodeGenerationTools code, Helper helper, string contextClassName) {
#>
public partial class <#=code.Escape(contextClassName) #> : BrightstarEntityContext {
private static readonly EntityMappingStore TypeMappings;
static <#= code.Escape(contextClassName) #>()
{
TypeMappings = new EntityMappingStore();
var provider = new ReflectionMappingProvider();
<#+
foreach(var i in helper.GetDecoratedInterfaces())
{
#>
provider.AddMappingsForType(TypeMappings, typeof(<#=i.InterfaceFullName#>));
TypeMappings.SetImplMapping<<#=i.InterfaceFullName#>, <#=code.CreateFullName(i.InterfaceNamespaceName, i.ClassName)#>>();
<#+
}
#>
}
/// <summary>
/// Initialize a new entity context using the specified BrightstarDB
/// Data Object Store connection
/// </summary>
/// <param name="dataObjectStore">The connection to the BrightstarDB Data Object Store that will provide the entity objects</param>
/// <param name="typeMappings">OPTIONAL: A <see cref="EntityMappingStore"/> that overrides the default mappings generated by reflection.</param>
public <#= code.Escape(contextClassName) #>(IDataObjectStore dataObjectStore, EntityMappingStore typeMappings = null) : base(typeMappings ?? TypeMappings, dataObjectStore)
{
InitializeContext();
}
/// <summary>
/// Initialize a new entity context using the specified Brightstar connection string
/// </summary>
/// <param name="connectionString">The connection to be used to connect to an existing BrightstarDB store</param>
/// <param name="enableOptimisticLocking">OPTIONAL: If set to true optmistic locking will be applied to all entity updates</param>
/// <param name="updateGraphUri">OPTIONAL: The URI identifier of the graph to be updated with any new triples created by operations on the store. If
/// not defined, the default graph in the store will be updated.</param>
/// <param name="datasetGraphUris">OPTIONAL: The URI identifiers of the graphs that will be queried to retrieve entities and their properties.
/// If not defined, all graphs in the store will be queried.</param>
/// <param name="versionGraphUri">OPTIONAL: The URI identifier of the graph that contains version number statements for entities.
/// If not defined, the <paramref name="updateGraphUri"/> will be used.</param>
/// <param name="typeMappings">OPTIONAL: A <see cref="EntityMappingStore"/> that overrides the default mappings generated by reflection.</param>
public <#= code.Escape(contextClassName) #>(
string connectionString,
bool? enableOptimisticLocking=null,
string updateGraphUri = null,
IEnumerable<string> datasetGraphUris = null,
string versionGraphUri = null,
EntityMappingStore typeMappings = null
) : base(typeMappings ?? TypeMappings, connectionString, enableOptimisticLocking, updateGraphUri, datasetGraphUris, versionGraphUri)
{
InitializeContext();
}
/// <summary>
/// Initialize a new entity context using the specified Brightstar
/// connection string retrieved from the configuration.
/// </summary>
/// <param name="typeMappings">OPTIONAL: A <see cref="EntityMappingStore"/> that overrides the default mappings generated by reflection.</param>
public <#= code.Escape(contextClassName) #>(EntityMappingStore typeMappings = null) : base(typeMappings ?? TypeMappings)
{
InitializeContext();
}
/// <summary>
/// Initialize a new entity context using the specified Brightstar
/// connection string retrieved from the configuration and the
// specified target graphs
/// </summary>
/// <param name="updateGraphUri">The URI identifier of the graph to be updated with any new triples created by operations on the store. If
/// set to null, the default graph in the store will be updated.</param>
/// <param name="datasetGraphUris">The URI identifiers of the graphs that will be queried to retrieve entities and their properties.
/// If set to null, all graphs in the store will be queried.</param>
/// <param name="versionGraphUri">The URI identifier of the graph that contains version number statements for entities.
/// If set to null, the value of <paramref name="updateGraphUri"/> will be used.</param>
/// <param name="typeMappings">OPTIONAL: A <see cref="EntityMappingStore"/> that overrides the default mappings generated by reflection.</param>
public <#= code.Escape(contextClassName) #>(
string updateGraphUri,
IEnumerable<string> datasetGraphUris,
string versionGraphUri,
EntityMappingStore typeMappings = null
) : base(typeMappings ?? TypeMappings, updateGraphUri:updateGraphUri, datasetGraphUris:datasetGraphUris, versionGraphUri:versionGraphUri)
{
InitializeContext();
}
private void InitializeContext()
{
<#+
foreach(var i in helper.GetDecoratedInterfaces()) {
#>
<#= code.Escape(i.PluralizedName) #> = new BrightstarEntitySet<<#=i.InterfaceFullName#>>(this);
<#+
}
#>
}
<#+
foreach(var i in helper.GetDecoratedInterfaces())
{
#>
<#=i.EntitySetAccessLevel#> IEntitySet<<#=i.InterfaceFullName#>> <#= code.Escape(i.PluralizedName) #>
{
get; private set;
}
<#+
}
#>
}
<#+
}
private void WriteEntityClass(CodeGenerationTools code, Helper helper, ResourceInterface iface)
{
BeginNamespace(code, iface.InterfaceNamespaceName);
var identityProperty = iface.IdentityProperty;
WriteClassAttributes(code, helper, iface);
#>
<#= code.SpaceAfter(iface.EntitySetAccessLevel)#>partial class <#= iface.ClassName #> : BrightstarEntityObject, <#= iface.InterfaceName #>
{
public <#= iface.ClassName#>(BrightstarEntityContext context, IDataObject dataObject) : base(context, dataObject) { }
public <#= iface.ClassName#>() : base() { }
<#+
if (identityProperty != null)
{
ValidateIdentityProperty(identityProperty);
#>
public <#= ((CodeProperty)identityProperty).Type.AsFullName #> <#= identityProperty.Name #> { get {return GetIdentity(); } set { SetIdentity(value); } }
<#+
}
WriteInterfaceImplementation(code, helper, iface);
foreach(var b in iface.AllInterfaces){
WriteInterfaceImplementation(code, helper, b);
}
#>
}
<#+
EndNamespace(iface.InterfaceNamespaceName);
}
private void WriteInterfaceImplementation(CodeGenerationTools code, Helper helper, ResourceInterface iface)
{#>
#region Implementation of <#= iface.InterfaceFullName #>
<#+
foreach(var p in iface.Properties) {
if (!p.Equals(iface.IdentityProperty))
{
bool isCollectionProperty;
if (ValidateProperty(p, helper, out isCollectionProperty))
{
WritePropertyAttributes(code, helper, p);
if (isCollectionProperty)
{
string generic, t;
Helper.TryParseGenericTypeName(p.Type.AsFullName, out generic, out t);
generic = Helper.GetEntityGeneric(generic);
if (generic == null)
{
this.Error(String.Format("There is no known mapping for the generic type {0} on the property {1} of type {2}",
generic, p.Name, p.Type.AsFullName));
}
else
{
#>
public <#= generic#><<#=t#>> <#= p.Name #>
{
<#+
if (helper.GetDecoratedInterfaces().Any(x=>x.InterfaceFullName.Equals(t)))
{
#>
get { return GetRelatedObjects<<#=t#>>(<#= code.CreateLiteral(p.Name) #>); }
set { if (value == null) throw new ArgumentNullException("value"); SetRelatedObjects(<#= code.CreateLiteral(p.Name)#>, value); }
<#+
}
else
{
#>
get { return GetRelatedLiteralPropertiesCollection<<#=t#>>(<#= code.CreateLiteral(p.Name) #>); }
set { if (value == null) throw new ArgumentNullException("value"); SetRelatedLiteralPropertiesCollection<<#=t#>>(<#= code.CreateLiteral(p.Name)#>, value); }
<#+
}
#>
}
<#+
}
}
else
{
var itemType = GetPropertyTypeName(p.Type);
#>
public <#= itemType #> <#= p.Name #>
{
<#+
PushIndent(CodeRegion.GetIndent(2));
if (IsValidLiteralType(helper, p.Type))
{
#>
get { return GetRelatedProperty<<#= itemType #>>(<#=code.CreateLiteral(p.Name)#>); }
set { SetRelatedProperty(<#=code.CreateLiteral(p.Name)#>, value); }
<#+
}
else
{
if (p.Getter != null) WriteSingleGetter(code, p);
if (p.Setter != null) WriteSingleSetter(code, p);
}
PopIndent();
#>
}
<#+
}
}
}
}
#>
#endregion
<#+
}
private void WriteCustomAttribute(Helper helper, CodeAttribute attr)
{
if (attr.FullName.Equals("BrightstarDB.EntityFramework.ClassAttributeAttribute"))
{
var e = attr.Children.GetEnumerator();
if (e.MoveNext())
{
var classAttributeArg = e.Current as EnvDTE80.CodeAttributeArgument;
if (classAttributeArg != null) {
#><#=helper.Unquote(classAttributeArg.Value)#><#+
}
}
}
if (attr.FullName.StartsWith("BrightstarDB.EntityFramework"))
{
return;
}
#>
[<#= attr.FullName#><#+
var childEnumerator = attr.Children.GetEnumerator();
if (childEnumerator.MoveNext())
{
bool keepGoing = true;
#>(<#+
while (keepGoing) {
if (childEnumerator.Current is EnvDTE80.CodeAttributeArgument)
{
var arg = childEnumerator.Current as EnvDTE80.CodeAttributeArgument;
if (!String.IsNullOrEmpty(arg.Name)) {
#><#=arg.Name#>=<#=arg.Value#><#+
}
else
{
#><#=arg.Value#><#+
}
keepGoing = childEnumerator.MoveNext();
if (keepGoing) {
#>, <#+
}
}
}
#>)<#+
}
#>]<#+
}
private void WriteClassAttributes(CodeGenerationTools code, Helper helper, ResourceInterface iface)
{
foreach(var x in iface.Interface.Attributes)
{
if (x is CodeAttribute) {
WriteCustomAttribute(helper, x as CodeAttribute);
}
}
}
private void WritePropertyAttributes(CodeGenerationTools code, Helper helper, CodeProperty property)
{
foreach(var x in property.Attributes)
{
if (x is CodeAttribute)
{
var attr = x as CodeAttribute;
WriteCustomAttribute(helper, attr);
}
}
}
private bool IsValidLiteralType(Helper helper, CodeTypeRef t)
{
if (Constants.BasicTypes.Contains(t.AsFullName) ||
IsByteArray(t) ||
t.CodeType.IsDerivedFrom["System.Enum"]) {
return true;
}
string genericName, typeName;
if (Helper.TryParseGenericTypeName(t.AsFullName, out genericName, out typeName)
&& genericName.Equals("System.Nullable")
&& helper.GetEnums().Any(e=>e.FullName.Equals(typeName))) {
return true;
}
return false;
}
private bool IsByteArray(CodeTypeRef t)
{
return t.TypeKind == vsCMTypeRef.vsCMTypeRefArray && t.ElementType.AsFullName == "System.Byte";
}
private void WriteCollectionGetter(CodeGenerationTools code, CodeProperty property, string itemType) {
if (Constants.BasicTypes.Contains(itemType))
{
#>
get { return GetRelatedProperties<<#= itemType #>>(<#=code.CreateLiteral(property.Name) #>); }
<#+
}
else
{
#>
get { return GetRelatedObjects<<#= itemType #>>(<#=code.CreateLiteral(property.Name)#>); }
<#+
}
}
private void WriteCollectionSetter(CodeGenerationTools code, CodeProperty property, string itemType) {
if (Constants.BasicTypes.Contains(itemType))
{
#>
set { SetRelatedProperties(<#= code.CreateLiteral(property.Name) #>, value); }
<#+
}
else
{
#>
set { SetRelatedObjects(<#= code.CreateLiteral(property.Name) #>, value ); }
<#+
}
}
private void WriteSingleGetter(CodeGenerationTools code, CodeProperty property)
{
var itemType = property.Type.AsFullName;
#>
get { return GetRelatedObject<<#= itemType #>>(<#=code.CreateLiteral(property.Name)#>); }
<#+
}
private void WriteSingleSetter(CodeGenerationTools code, CodeProperty property) {
var itemType = property.Type.AsFullName;
#>
set { SetRelatedObject<<#= itemType #>>(<#=code.CreateLiteral(property.Name)#>, value); }
<#+
}
private string GetPropertyTypeName(CodeTypeRef propertyType)
{
if (propertyType.TypeKind == vsCMTypeRef.vsCMTypeRefArray) {
return propertyType.ElementType.AsFullName + "[]";
} else {
return propertyType.AsFullName;
}
}
private void ValidateIdentityProperty(CodeProperty property) {
if (!property.Type.AsFullName.Equals("System.String"))
{
Error(String.Format("The property '{0}' must be of type String to be used as the identity property for an entity. If this property is intended to be the identity property for the entity please change its type to String. If it is not intended to be the identity property, either rename this property or create an identity property and decorate it with the [{1}] attribute.",
property.FullName, Constants.IdentityAttributeShortName));
}
if (property.Setter != null) {
Error(String.Format("The property '{0}' must not have a setter to be used as the identity property for an entity. If this property is intended to be the identity property for the entity please remove the setter. If it is not intended to be the identity property, either rename this property or create an identity propertyn and decorate it with the [{1}] attribute.",
property.FullName, Constants.IdentityAttributeShortName));
}
}
private bool ValidateProperty(CodeProperty property, Helper helper, out bool isCollection)
{
var propertyTypeName = property.Type.AsFullName;
isCollection = false;
bool isValid = false;
if (IsValidLiteralType(helper, property.Type) ||
helper.GetDecoratedInterfaces().Any(i=>i.InterfaceFullName.Equals(propertyTypeName)))
{
isValid = true;
}
else
{
string generic, t;
if (Helper.TryParseGenericTypeName(propertyTypeName, out generic, out t))
{
if (Constants.CollectionTypes.Contains(generic) &&
(Constants.BasicTypes.Contains(t) || helper.GetDecoratedInterfaces().Any(i=>i.InterfaceFullName.Equals(t))))
{
isCollection = true;
isValid = true;
propertyTypeName = t;
}
}
}
if (!isValid)
{
Error("Invalid property: " + property.FullName + " - the property type " + propertyTypeName + " is not supported by Entity Framework.");
isCollection = false;
return false;
}
var inversePropertyAttr = property.Attributes.OfType<CodeAttribute>().FirstOrDefault(
attr => attr.FullName.Equals(Constants.InversePropertyAttributeName));
if (inversePropertyAttr != null)
{
var arg = inversePropertyAttr.Children.OfType<EnvDTE80.CodeAttributeArgument>().FirstOrDefault();
var inversePropertyName = arg.Value.Trim('\"');
var targetInterface = helper.GetDecoratedInterfaces().FirstOrDefault(i=>i.InterfaceFullName.Equals(propertyTypeName));
if (targetInterface == null)
{
this.Error("Invalid InverseProperty attribute on property " + property.Name + ". The property type " + propertyTypeName + " must be marked as an Entity.");
return false;
}
var targetProperty = targetInterface.Properties.FirstOrDefault(p=>p.Name.Equals(inversePropertyName));
if (targetProperty == null)
{
this.Error("Invalid InverseProperty attribute on property " + property.Name + ". A property named '" + inversePropertyName + "' cannot be found on the target interface type '" + targetInterface.InterfaceFullName + "'.");
return false;
}
}
return true;
}
static class Constants {
public const string IdentityAttributeName = "BrightstarDB.EntityFramework.IdentifierAttribute";
public const string IdentityAttributeShortName = "Identifier";
public const string EntityAttributeName = "BrightstarDB.EntityFramework.EntityAttribute";
public const string InversePropertyAttributeName = "BrightstarDB.EntityFramework.InversePropertyAttribute";
/// <summary>
/// The property types that are supported entity property types
/// </summary>
public static readonly List<string> BasicTypes = new List<string>
{
"System.Boolean",
"System.Int16",
"System.Int64",
"System.Int32",
"System.UInt16",
"System.UInt32",
"System.UInt64",
"System.String",
"System.DateTime",
"System.Decimal",
"System.Double",
"System.Single",
"System.Uri",
"System.Byte",
"System.Char",
"System.SByte",
"BrightstarDB.Rdf.PlainLiteral",
"System.Nullable<System.Boolean>",
"System.Nullable<System.Int16>",
"System.Nullable<System.Int32>",
"System.Nullable<System.Int64>",
"System.Nullable<System.UInt16>",
"System.Nullable<System.UInt32>",
"System.Nullable<System.UInt64>",
"System.Nullable<System.DateTime>",
"System.Nullable<System.Decimal>",
"System.Nullable<System.Double>",
"System.Nullable<System.Single>",
"System.Nullable<System.Byte>",
"System.Nullable<System.Char>",
"System.Nullable<System.SByte>",
};
/// <summary>
/// The generic collection types that are supported entity collection property types
/// </summary>
public static readonly List<string> CollectionTypes = new List<string>
{
"System.Collections.Generic.ISet",
"System.Collections.Generic.ICollection",
};
public static readonly List<string> CoreImports = new List<string> {
"System", "System.Collections.Generic", "System.Linq", "BrightstarDB.Client", "BrightstarDB.EntityFramework"
};
}
class Helper {
private DTE _dte;
public static TextTransformation _transformation;
private ProjectItem _templateProjectItem;
private Project _project;
public Helper(TextTransformation transformation) {
_transformation = transformation;
_templateProjectItem = DTE.Solution.FindProjectItem(Host.TemplateFile);
_project = _templateProjectItem.ContainingProject;
}
public ITextTemplatingEngineHost Host {
get {
return _transformation.GetType().GetProperty("Host").GetValue(_transformation, null) as ITextTemplatingEngineHost;
}
}
public DTE DTE
{
get {
if (_dte == null) {
IServiceProvider hostServiceProvider = (IServiceProvider)Host;
_dte = hostServiceProvider.GetService(typeof(DTE)) as DTE;
}
return _dte;
}
}
public IEnumerable<CodeElement> GetInterfaces() {
foreach(var pi in GetCodeProjectItems()) {
foreach(CodeElement ce in GetInterfaces(pi.FileCodeModel.CodeElements)) {
yield return ce;
}
}
}
public IEnumerable<ResourceInterface> GetDecoratedInterfaces() {
return GetCodeProjectItems().SelectMany(pi=>GetDecoratedInterfaces(pi.FileCodeModel.CodeElements)).Select(x=>new ResourceInterface(x));
}
/// <summary>
/// Returns an enumeration of all distinct using statements contained
/// in the files that define BrightstarDB Entity Framework entity interfaces
/// <summary>
public IEnumerable<string> GetExtraUsings() {
return GetCodeProjectItems()
.Where(pi=>GetDecoratedInterfaces(pi.FileCodeModel.CodeElements).Any())
.SelectMany(pi=>pi.FileCodeModel.CodeElements.OfType<CodeImport>().Select(ce=>ce.Namespace))
.Distinct().Except(Constants.CoreImports);
}
/// <summary>
/// Returns an enumeration over all the enums types defined in the project
/// </summary>
/// <returns></returns>
public IEnumerable<CodeEnum> GetEnums() {
foreach(var pi in GetCodeProjectItems()) {
foreach(CodeElement ce in GetEnums(pi.FileCodeModel.CodeElements)) {
yield return (CodeEnum)ce;
}
}
}
/// <summary>
/// Pass-through write operation to allow this class to contain template output
/// </summary>
/// <param name="text"></param>
public void Write(string text) {
_transformation.Write(text);
}
/// <summary>
/// Pass-through write operation to allow this class to contain template output
/// </summary>
/// <param name="text"></param>
public void Write(string msg, object[] args) {
_transformation.Write(msg, args);
}
public static IEnumerable<CodeElement> GetDecoratedInterfaces(CodeElements container) {
return GetInterfaces(container).Where(i=>i.Children.OfType<CodeElement>().Any(c=>c.Kind == vsCMElement.vsCMElementAttribute && c.FullName.Equals(Constants.EntityAttributeName)));
}
public static IEnumerable<CodeElement> GetInterfaces(CodeElements container) {
foreach(CodeElement ce in container) {
if (ce.Kind == vsCMElement.vsCMElementInterface) {
yield return ce;
} else {
foreach(var child in GetInterfaces(ce.Children)) {
yield return child;
}
}
}
}
public static IEnumerable<CodeElement> GetEnums(CodeElements container) {
foreach(CodeElement ce in container) {
if (ce.Kind == vsCMElement.vsCMElementEnum) {
yield return ce;
} else {
foreach(var child in GetEnums(ce.Children)) {
yield return child;
}
}
}
}
public static bool TryParseGenericTypeName(string genericTypeName, out string generic, out string t)
{
var regex = new System.Text.RegularExpressions.Regex(@"^([a-zA-Z0-9\.]+)<([^>]+)>$");
var match = regex.Match(genericTypeName);
if (match.Success)
{
generic=match.Groups[1].Value;
t = match.Groups[2].Value;
return true;
}
else
{
generic = t = null;
return false;
}
}
public static string GetEntityGeneric(string genericTypeName)
{
if (genericTypeName.Equals("System.Collections.Generic.ICollection"))
{
return "System.Collections.Generic.ICollection";
}
return null;
}
public IEnumerable<ProjectItem> GetCodeProjectItems() {
foreach(var pi in GetCodeProjectItems(_project.ProjectItems)) {
yield return pi;
}
}
public string Unquote(string quotedString)
{
if(quotedString.StartsWith("\""))
{
return quotedString.Trim('\"').Replace("\\\"", "\"");
}
else if (quotedString.StartsWith("@\""))
{
return quotedString.TrimStart('@','\"').TrimEnd('\"');
}
else
{
return quotedString;
}
}
private IEnumerable<ProjectItem> GetCodeProjectItems(ProjectItems projectItems) {
foreach(ProjectItem pi in projectItems) {
if (pi.Equals(_templateProjectItem)) {
continue;
}
if (pi.FileCodeModel != null) {
yield return pi;
}
if (pi.ProjectItems != null) {
foreach(var childItem in GetCodeProjectItems(pi.ProjectItems)) {
yield return childItem;
}
}
}
}
}
class ResourceInterface {
private CodeInterface _interfaceCE;
private CodeProperty _identityProperty;
private string _className;
public ResourceInterface(CodeInterface interfaceCE){
_interfaceCE = interfaceCE;
_identityProperty = (CodeProperty)FindIdentityProperty();
}
public ResourceInterface(CodeElement rootElement)
{
_interfaceCE = ((CodeInterface)rootElement);
_identityProperty = (CodeProperty)FindIdentityProperty();
}
public IEnumerable<CodeProperty> Properties {
get
{
return _interfaceCE.Children
.OfType<CodeElement>()
.Where(c=>c.Kind == vsCMElement.vsCMElementProperty)
.Select(c=>(CodeProperty)c);
}
}
public CodeInterface Interface {
get { return _interfaceCE; }
}
public IEnumerable<ResourceInterface> BaseInterfaces
{
get
{
foreach(var baseInterface in _interfaceCE.Bases.OfType<CodeInterface>().Where(HasEntityAttribute))
{
yield return new ResourceInterface(baseInterface);
}
}
}
private bool HasEntityAttribute(CodeInterface iface)
{
try
{
return iface.Children.OfType<CodeElement>().Any(c=>c.Kind == vsCMElement.vsCMElementAttribute && c.FullName.Equals(Constants.EntityAttributeName));
}
catch
{
return false;
}
}
public void GetAllInterfaces(List<ResourceInterface> interfaces)
{
foreach (var ri in BaseInterfaces)
{
if (!interfaces.Contains(ri))
{
interfaces.Add(ri);
}
ri.GetAllInterfaces(interfaces);
}
}
public IEnumerable<ResourceInterface> AllInterfaces {
get {
var resourceInterfaces = new List<ResourceInterface>();
GetAllInterfaces(resourceInterfaces);
return resourceInterfaces;
}
}
private CodeProperty FindIdentityProperty()
{
// Find the identity property on the interface (if any)
var ret = Properties.Where( c=>
c.Attributes.OfType<CodeAttribute>().Any(
attr => attr.FullName.Equals(Constants.IdentityAttributeName))).FirstOrDefault();
if (ret == null)
ret = Properties.Where( c=>
(c.Name.Equals(ClassName+"Id") || c.Name.Equals(ClassName+"ID"))).FirstOrDefault();
if (ret == null)
{
ret = Properties.Where( c=>
(c.Name.Equals("Id") || c.Name.Equals("ID"))).FirstOrDefault();
}
// if there is no indication on this class of an id property then check the interfaces we inherit from
if (ret == null)
{
foreach (var bi in AllInterfaces){
ret = bi.FindIdentityProperty();
if (ret != null) return ret;
}
} else {
foreach (var bi in AllInterfaces){
var aret = bi.FindIdentityProperty();
if (aret != null && (!aret.Name.Equals(ret.Name))) {
Helper._transformation.Error("Invalid identity property " + ret.Name + " on " + _interfaceCE.Name + " it differs from ancestor id " + aret.Name + " on " + bi.InterfaceName);
}
}
}
return ret;
}
public void ValidateIdentityProperty(CodeProperty identityProperty){
foreach (var bi in AllInterfaces){
var aret = bi.FindIdentityProperty();
if (aret != null && (aret.Name != identityProperty.Name)) {
throw new Exception("Invalid identity property. It differs from ancestor identity.");
}
}
}
public string ClassName {
get {
if (_className == null) {
if (_interfaceCE.Name.StartsWith("I")) {
_className = _interfaceCE.Name.Substring(1);
} else {
_className = _interfaceCE.Name + "Impl";
}
}
return _className;
}
}
public string InterfaceName
{
get { return _interfaceCE.Name; }
}
public string InterfaceFullName
{
get { return _interfaceCE.FullName; }
}
public string InterfaceNamespaceName
{
get { return _interfaceCE.Namespace.FullName; }
}
public CodeProperty IdentityProperty {
get {return _identityProperty; }
}
public string PluralizedName {
get { return Pluralize(_interfaceCE.Name.StartsWith("I") ? _interfaceCE.Name.Substring(1) : _interfaceCE.Name); }
}
public string Pluralize(string name)
{
if (name.EndsWith("y")) {
return name.Substring(0, name.Length - 1) + "ies";
}
return name + "s";
}
public string EntitySetAccessLevel
{
get
{
switch (_interfaceCE.Access) {
case vsCMAccess.vsCMAccessPublic :
return "public";
case vsCMAccess.vsCMAccessPrivate :
return "private";
case vsCMAccess.vsCMAccessProject :
case vsCMAccess.vsCMAccessAssemblyOrFamily:
return "internal";
default :
return "private";
}
}
}
}
#>

View File

@ -1,8 +0,0 @@
using System;
namespace NPSharp.CommandLine.Server.Database
{
class DatabaseUserExistsException : Exception
{
}
}

View File

@ -1,17 +0,0 @@
using System;
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface IBan
{
string Id { get; }
IUser User { get; }
string Reason { get; set; }
DateTime ExpiryTime { get; set; }
}
}

View File

@ -1,19 +0,0 @@
using System;
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface ICheatDetection
{
string Id { get; }
IUser User { get; }
uint CheatId { get; set; }
string Reason { get; set; }
DateTime ExpiryTime { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface IFriend
{
string Id { get; }
IUser User { get; }
uint FriendUserId { get; set; }
string FriendName { get; set; }
}
}

View File

@ -1,14 +0,0 @@
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface IPublisherFile
{
string Id { get; }
string FileName { get; set; }
byte[] FileData { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System;
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface ISession
{
[Identifier]
string Id { get; }
IUser User { get; }
DateTime ExpiryTime { get; set; }
}
}

View File

@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface IUser
{
[Identifier]
string Id { get; }
string UserName { get; set; }
string UserMail { get; set; }
uint UserNumber { get; set; }
string PasswordHash { get; set; }
DateTime LastLogin { get; set; }
[InverseProperty("User")]
ICollection<ISession> Sessions { get; set; }
[InverseProperty("User")]
ICollection<IBan> Bans { get; set; }
[InverseProperty("User")]
ICollection<ICheatDetection> CheatDetections { get; set; }
[InverseProperty("User")]
ICollection<IUserFile> UserFiles { get; set; }
[InverseProperty("User")]
ICollection<IFriend> FriendIDs { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using BrightstarDB.EntityFramework;
namespace NPSharp.CommandLine.Server.Database
{
[Entity]
public interface IUserFile
{
string Id { get; }
IUser User { get; set; }
string FileName { get; set; }
byte[] FileData { get; set; }
}
}

View File

@ -1,14 +0,0 @@
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,269 +0,0 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
using NPSharp.Authentication;
using NPSharp.CommandLine.Server.Database;
using NPSharp.NP;
namespace NPSharp.CommandLine.Server
{
internal class Program
{
private static ILog _log;
private static SessionAuthenticationServer _authServer;
private static NPServer _np;
private static void Main()
{
InitializeLogging();
_log.Info("NP server is about to start up, this might take a few seconds...");
InitializeDatabase();
InitializeAuthServer();
InitializeNPServer();
_log.Info("NP server started up successfully.");
Thread.Sleep(Timeout.Infinite);
}
private static BrightstarDatabaseContext OpenDatabase(string store = "NP")
{
return
new BrightstarDatabaseContext(
"type=embedded;storesdirectory=Database\\;storename=" + store,
true);
}
private static void InitializeDatabase()
{
_log.Debug("Preparing database...");
using (var db = OpenDatabase())
{
// Skip user creation if there are already registered users
// ReSharper disable once UseMethodAny.0
// since SPARQL-to-LINQ does not have support for Any() yet
if (db.Users.Count() > 0)
return;
// Create first user
var testUser = db.CreateUser("test", "test@localhost", "test");
db.SaveChanges();
_log.InfoFormat(
"Created first user with following details:" + Environment.NewLine + Environment.NewLine +
"Username: {0}" + Environment.NewLine +
"Password: {1}" + Environment.NewLine,
testUser.UserName,
"test");
}
// Cleanup thread
Task.Factory.StartNew(() =>
{
while (true)
{
using (var dbForCleanup = OpenDatabase())
{
_log.Debug("Starting cleanup...");
foreach (var session in dbForCleanup.Sessions.Where(s => s.ExpiryTime < DateTime.Now).ToArray())
{
_log.DebugFormat("Session {0} became invalid", session.Id);
dbForCleanup.DeleteObject(session);
}
foreach (var ban in dbForCleanup.Bans.Where(s => s.ExpiryTime < DateTime.Now).ToArray())
{
_log.DebugFormat("Ban {0} became invalid", ban.Id);
dbForCleanup.DeleteObject(ban);
}
foreach (var cheatDetection in dbForCleanup.CheatDetections.Where(s => s.ExpiryTime < DateTime.Now).ToArray())
{
_log.DebugFormat("Cheat detection {0} became invalid", cheatDetection.Id);
dbForCleanup.DeleteObject(cheatDetection);
}
dbForCleanup.SaveChanges();
_log.Debug("Cleanup done.");
}
Thread.Sleep(TimeSpan.FromSeconds(30));
}
// TODO: implement some way to cancel this loop
// ReSharper disable once FunctionNeverReturns
});
}
private static void InitializeAuthServer()
{
_log.Debug("Starting authentication server...");
_authServer = new SessionAuthenticationServer();
_authServer.Authenticating += (loginUsername, loginPassword) =>
{
using (var db = OpenDatabase())
{
var user = db.GetUser(loginUsername);
if (user == null || !BCrypt.Net.BCrypt.Verify(loginPassword, user.PasswordHash))
return new SessionAuthenticationResult {Reason = "Invalid credentials"};
// Check for bans
var bans = user.Bans.Where(b => b.ExpiryTime > DateTime.Now).ToArray();
if (bans.Any())
{
var ban = bans.First();
return new SessionAuthenticationResult
{
Reason = string.Format("You're banned: {0} (until {1})", ban.Reason, ban.ExpiryTime)
};
}
// Check for cheat detections
var cheatDetections =
user.CheatDetections.Where(c => c.ExpiryTime > DateTime.Now).ToArray();
if (cheatDetections.Any())
{
var cheatDetection = cheatDetections.First();
return new SessionAuthenticationResult
{
Reason =
string.Format("Detected cheat #{0}: {1} (until {2})", cheatDetection.CheatId,
cheatDetection.Reason, cheatDetection.ExpiryTime)
};
}
// Create user session
var session = db.CreateSession(user);
_log.DebugFormat("Created session {0}", session.Id);
// Update user's last login data
user.LastLogin = DateTime.Now;
// Save to database
db.SaveChanges();
// Return session information
return new SessionAuthenticationResult
{
Success = true,
SessionToken = session.Id,
UserID = user.UserNumber,
UserMail = user.UserMail,
UserName = user.UserName
};
}
}
;
_authServer.Start();
}
private static void InitializeNPServer()
{
_log.Debug("Starting NP server...");
_np = new NPServer(3036)
{
AuthenticationHandler = new BrightstarDatabaseAuthenticationHandler(OpenDatabase()),
FileServingHandler = new BrightstarDatabaseFileServingHandler(OpenDatabase()),
FriendsHandler = null,
UserAvatarHandler = null
};
_np.Start();
}
private static void InitializeLogging()
{
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
{
var appender = new ConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
BasicConfigurator.Configure(
new IAppender[]
{
appender,
new DebugAppender {Layout = appender.Layout, Threshold = Level.All}
});
}
else
{
var appender = new ColoredConsoleAppender
{
#if DEBUG
Threshold = Level.Debug,
#else
Threshold = Level.Info,
#endif
Layout = new PatternLayout("<%d{HH:mm:ss}> [%logger:%thread] %level: %message%newline"),
};
appender.AddMapping(
new ColoredConsoleAppender.LevelColors
{
Level = Level.Debug,
ForeColor = ColoredConsoleAppender.Colors.Cyan | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(
new ColoredConsoleAppender.LevelColors
{
Level = Level.Info,
ForeColor =
ColoredConsoleAppender.Colors.Green | ColoredConsoleAppender.Colors.HighIntensity
}
);
appender.AddMapping(
new ColoredConsoleAppender.LevelColors
{
Level = Level.Warn,
ForeColor =
ColoredConsoleAppender.Colors.Purple | ColoredConsoleAppender.Colors.HighIntensity
});
appender.AddMapping(
new ColoredConsoleAppender.LevelColors
{
Level = Level.Error,
ForeColor = ColoredConsoleAppender.Colors.Red | ColoredConsoleAppender.Colors.HighIntensity
}
);
appender.AddMapping(
new ColoredConsoleAppender.LevelColors
{
Level = Level.Fatal,
ForeColor =
ColoredConsoleAppender.Colors.White | ColoredConsoleAppender.Colors.HighIntensity,
BackColor = ColoredConsoleAppender.Colors.Red
});
appender.ActivateOptions();
BasicConfigurator.Configure(
new IAppender[]
{
appender,
new DebugAppender {Layout = appender.Layout, Threshold = Level.All}
});
}
_log = LogManager.GetLogger("Main");
}
}
}

View File

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1FF77692-D07C-4131-95AE-21AD2A74CA11}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NPSharp.CommandLine.Server</RootNamespace>
<AssemblyName>npserv</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntDir>
<IntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</IntermediateOutputPath>
<BaseIntermediateOutputPath>$(SolutionDir)\obj\$(TargetName)\$(Configuration)\$(Platform)\</BaseIntermediateOutputPath>
<OutputPath>$(SolutionDir)\bin\$(Configuration)\$(Platform)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="BCrypt.Net">
<HintPath>..\..\packages\BCrypt-Official.0.1.109\lib\BCrypt.Net.dll</HintPath>
</Reference>
<Reference Include="BrightstarDB">
<HintPath>..\..\packages\BrightstarDBLibs.1.6.2.0\lib\net45\BrightstarDB.dll</HintPath>
</Reference>
<Reference Include="dotNetRDF">
<HintPath>..\..\packages\dotNetRDF.1.0.4.3225\lib\net40\dotNetRDF.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack">
<HintPath>..\..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<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>
</Reference>
<Reference Include="Remotion.Linq">
<HintPath>..\..\packages\BrightstarDBLibs.1.6.2.0\lib\net45\Remotion.Linq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="uhttpsharp">
<HintPath>..\..\packages\uHttpSharp.0.1.4.8\lib\net40\uhttpsharp.dll</HintPath>
</Reference>
<Reference Include="VDS.Common">
<HintPath>..\..\packages\VDS.Common.1.2.0\lib\net40-client\VDS.Common.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Database\BrightstarDatabaseContext.custom.cs" />
<Compile Include="Database\DatabaseUserExistsException.cs" />
<Compile Include="Database\IBan.cs" />
<Compile Include="Database\ICheatDetection.cs" />
<Compile Include="Database\IFriend.cs" />
<Compile Include="Database\IPublisherFile.cs" />
<Compile Include="Database\ISession.cs" />
<Compile Include="Database\IUser.cs" />
<Compile Include="Database\IUserFile.cs" />
<Compile Include="BrightstarDatabaseAuthenticationHandler.cs" />
<Compile Include="BrightstarDatabaseFileServingHandler.cs" />
<Compile Include="Database\BrightstarDatabaseContext.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>BrightstarDatabaseContext.tt</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Database\BrightstarDatabaseContext.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>BrightstarDatabaseContext.cs</LastGenOutput>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libnpsharp\libnpsharp.csproj">
<Project>{1a5ac63a-250e-4bc8-b81a-822ac31f5e37}</Project>
<Name>libnpsharp</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="LICENSE.txt" />
</ItemGroup>
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BCrypt-Official" version="0.1.109" targetFramework="net45" />
<package id="BrightstarDB" version="1.6.2.0" targetFramework="net45" />
<package id="BrightstarDBLibs" version="1.6.2.0" targetFramework="net45" />
<package id="dotNetRDF" version="1.0.4.3225" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
<package id="uHttpSharp" version="0.1.4.8" targetFramework="net45" />
<package id="VDS.Common" version="1.2.0" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,123 @@
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.Master.Messages;
using NPSharp.Master.Messages.Client;
using NPSharp.NP;
namespace NPSharp.Master
{
public class MasterServer
{
// TODO: !! Avoid socket fail if stopping then restarting
private readonly Socket _socket4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private readonly Socket _socket6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
private readonly ILog _log;
private readonly ushort _port;
private readonly List<KeyValuePair<Type, Action<MasterClientMessage>>> _callbacks =
new List<KeyValuePair<Type, Action<MasterClientMessage>>>();
// TODO: Use the same kind of interfaces as in NP server to handle server addition and deletion
private readonly List<DedicatedServerEntry> _registeredServers = new List<DedicatedServerEntry>();
public MasterServer(ushort port = 20810)
{
_port = port;
_log = LogManager.GetLogger("MasterServer");
// Internal callbacks
AddCallback<MasterGetServersMessage>(messages =>
{
});
}
internal void AddCallback<T>(Action<T> callback) where T : MasterClientMessage
{
_callbacks.Add(
new KeyValuePair<Type, Action<MasterClientMessage>>(
typeof(T),
msg => callback.Invoke((T)msg)));
}
/// <summary>
/// Starts up the NP server.
/// </summary>
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<byte>();
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);
}
}
}

View File

@ -32,7 +32,35 @@ namespace NPSharp.Master.Messages
get { return GetType().GetCustomAttribute<MasterServerMessageAttribute>().Name; } get { return GetType().GetCustomAttribute<MasterServerMessageAttribute>().Name; }
} }
internal MasterServerMessage Deserialize(Socket sock) internal static MasterServerMessage Deserialize(byte[] buffer)
{
var header = buffer.Take(4).ToArray();
var command = Encoding.ASCII.GetString(buffer, 4, buffer.Length - 4).Trim();
var commandSplit = command.Split(new[] { '\t', '\r', '\n', '\0', ' ' }, // TODO: Response consists of multipart messages separated by \ instead of <space>?? Try to be stay as close to client messages as possible.
StringSplitOptions.RemoveEmptyEntries);
var commandName = commandSplit[0];
var commandArguments = commandSplit.Skip(1).ToArray();
// Search for a message class which fits to the commandName
var message =
(MasterServerMessage)Activator.CreateInstance(Assembly.GetExecutingAssembly()
.GetTypes()
.Single(
t =>
t.IsSubclassOf(typeof(MasterServerMessage)) &&
t.GetCustomAttribute<MasterServerMessageAttribute>()
.Name.Equals(commandName, StringComparison.OrdinalIgnoreCase)));
// Call the individual deserialize method
message.Deserialize(commandArguments);
message.Header = header;
return message;
}
internal static MasterServerMessage DeserializeTcp(Socket sock)
{ {
while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead)) while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead))
{ {
@ -51,35 +79,14 @@ namespace NPSharp.Master.Messages
Log.Debug("Received 0 bytes"); Log.Debug("Received 0 bytes");
return null; return null;
} }
if (length < 4) if (length < 4)
{ {
Log.ErrorFormat("Received incomplete 4-byte header (received {0} bytes instead)", length); Log.ErrorFormat("Received incomplete 4-byte header (received {0} bytes instead)", length);
throw new ProtocolViolationException("Received incomplete header"); throw new ProtocolViolationException("Received incomplete header");
} }
var header = buffer.Take(4).ToArray(); return Deserialize(buffer.Take(length).ToArray());
var command = Encoding.ASCII.GetString(buffer, 4, length - 4).Trim();
var commandSplit = command.Split(new[] {'\t', '\r', '\n', '\0', ' '}, // TODO: Response consists of multipart messages separated by \ instead of <space>?? Try to be stay as close to client messages as possible.
StringSplitOptions.RemoveEmptyEntries);
var commandName = commandSplit[0];
var commandArguments = commandSplit.Skip(1).ToArray();
// Search for a message class which fits to the commandName
var message =
(MasterServerMessage) Activator.CreateInstance(Assembly.GetExecutingAssembly()
.GetTypes()
.Single(
t =>
t.IsSubclassOf(typeof (MasterServerMessage)) &&
t.GetCustomAttribute<MasterServerMessageAttribute>()
.Name.Equals(commandName, StringComparison.OrdinalIgnoreCase)));
// Call the individual deserialize method
message.Deserialize(commandArguments);
message.Header = header;
return message;
} }
catch (SocketException) catch (SocketException)
{ {

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NPSharp.Master.Messages namespace NPSharp.Master.Messages
{ {

Some files were not shown because too many files have changed in this diff Show More