Binary support

main
Thomas Woischnig 2023-12-01 22:58:44 +01:00
parent 840218f119
commit 97df572f1e
21 changed files with 310 additions and 45 deletions

View File

@ -0,0 +1,121 @@
{
"runtimeTarget": {
"name": ".NETStandard,Version=v2.1/",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETStandard,Version=v2.1": {},
".NETStandard,Version=v2.1/": {
"LobbyClient/1.0.0": {
"dependencies": {
"LobbyServerDto": "1.0.0"
},
"runtime": {
"LobbyClient.dll": {}
}
},
"System.Buffers/4.5.1": {
"runtime": {
"lib/netstandard2.0/System.Buffers.dll": {
"assemblyVersion": "4.0.3.0",
"fileVersion": "4.6.28619.1"
}
}
},
"System.ComponentModel.Annotations/5.0.0": {
"runtime": {
"lib/netstandard2.1/System.ComponentModel.Annotations.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Memory/4.5.5": {
"dependencies": {
"System.Buffers": "4.5.1",
"System.Numerics.Vectors": "4.4.0",
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
},
"runtime": {
"lib/netstandard2.0/System.Memory.dll": {
"assemblyVersion": "4.0.1.2",
"fileVersion": "4.6.31308.1"
}
}
},
"System.Numerics.Vectors/4.4.0": {
"runtime": {
"lib/netstandard2.0/System.Numerics.Vectors.dll": {
"assemblyVersion": "4.1.3.0",
"fileVersion": "4.6.25519.3"
}
}
},
"System.Runtime.CompilerServices.Unsafe/4.5.3": {
"runtime": {
"lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {
"assemblyVersion": "4.0.4.1",
"fileVersion": "4.6.28619.1"
}
}
},
"LobbyServerDto/1.0.0": {
"dependencies": {
"System.ComponentModel.Annotations": "5.0.0",
"System.Memory": "4.5.5"
},
"runtime": {
"LobbyServerDto.dll": {}
}
}
}
},
"libraries": {
"LobbyClient/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"System.Buffers/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
"path": "system.buffers/4.5.1",
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
},
"System.ComponentModel.Annotations/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==",
"path": "system.componentmodel.annotations/5.0.0",
"hashPath": "system.componentmodel.annotations.5.0.0.nupkg.sha512"
},
"System.Memory/4.5.5": {
"type": "package",
"serviceable": true,
"sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
"path": "system.memory/4.5.5",
"hashPath": "system.memory.4.5.5.nupkg.sha512"
},
"System.Numerics.Vectors/4.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==",
"path": "system.numerics.vectors/4.4.0",
"hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512"
},
"System.Runtime.CompilerServices.Unsafe/4.5.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==",
"path": "system.runtime.compilerservices.unsafe/4.5.3",
"hashPath": "system.runtime.compilerservices.unsafe.4.5.3.nupkg.sha512"
},
"LobbyServerDto/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,23 @@
{
"name": "Unity.LobbyClient.Runtime",
"rootNamespace": "",
"references": [
],
"includePlatforms": [
"Android",
"iOS",
"LinuxStandalone64",
"CloudRendering",
"macOSStandalone",
"WindowsStandalone64"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": true,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,17 @@
{
"name": "com.incobyte.lobbyclient",
"version": "1.0.0",
"displayName": "Game Lobby Client",
"description": "Provides a client for the game lobvy server to list and join lobbies",
"unity": "2022.3",
"keywords": [
"nat punch",
"lobby",
"network"
],
"author": {
"name": "Thomas Woischnig",
"email": "twoischnig@incobyte.de",
"url": "https://www.incobyte.de"
}
}

View File

@ -5,8 +5,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -20,6 +18,7 @@ namespace Lobbies
AutoResetEvent waitForExternalIp = new AutoResetEvent(false);
private Dictionary<Guid, LobbyInfo> lobbyInformation = new Dictionary<Guid, LobbyInfo>();
private string? host;
private int port;
private int connectionId;
@ -74,8 +73,15 @@ namespace Lobbies
}
}
public void HostLobby(Guid gameId, string name, int gameMode, int maxPlayerCount,string? password, string? ip, int port)
public void HostLobby(Guid gameId, string name, int gameMode, int maxPlayerCount, string? password, string? ip, int port)
{
byte[]? hash = null, salt = null;
if(!string.IsNullOrEmpty(password))
{
(hash, salt) = PasswordHash.Hash(password);
}
var lobbyCreate = new LobbyCreate()
{
GameId = gameId,
@ -83,7 +89,8 @@ namespace Lobbies
GameMode = gameMode,
MaxPlayerCount = maxPlayerCount,
PlayerCount = 0,
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
PasswordHash = hash,
PasswordSalt = salt,
HostIp = ip,
HostPort = port
};
@ -95,10 +102,14 @@ namespace Lobbies
public void RequestLobbyHostInfo(Guid lobbyId, string? password)
{
byte[]? passwordHash = null;
if(!string.IsNullOrEmpty(password) && lobbyInformation.ContainsKey(lobbyId) && lobbyInformation[lobbyId].PasswordSalt != null)
passwordHash = PasswordHash.Hash(password, lobbyInformation[lobbyId].PasswordSalt!);
var lobbyCreate = new LobbyRequestHostInfo()
{
LobbyId = lobbyId,
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
PasswordHash = passwordHash,
};
byte[] messageData = bufferRental.Rent();
@ -110,13 +121,17 @@ namespace Lobbies
public delegate void SendUdpMessageCallback(IPEndPoint remoteEndpoint, byte[] messageBuffer, int messageLength);
public void RequestLobbyNatPunch(Guid lobbyId, string? password, SendUdpMessageCallback sendUdpCallback)
{
byte[]? passwordHash = null;
if (!string.IsNullOrEmpty(password) && lobbyInformation.ContainsKey(lobbyId) && lobbyInformation[lobbyId].PasswordSalt != null)
passwordHash = PasswordHash.Hash(password, lobbyInformation[lobbyId].PasswordSalt!);
Task.Run(() =>
{
QueryExternalIpAndPort(sendUdpCallback);
var lobbyRequestNatPunch = new LobbyRequestNatPunch()
{
LobbyId = lobbyId,
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
PasswordHash = passwordHash,
ClientIp = externalIp,
ClientPort = externalPort
};
@ -129,13 +144,21 @@ namespace Lobbies
public void UpdateLobby(string name, int gameMode, int maxPlayerCount, int playerCount, string? password, string? ip, int port)
{
byte[]? hash = null, salt = null;
if (!string.IsNullOrEmpty(password))
{
(hash, salt) = PasswordHash.Hash(password);
}
var lobbyUpdate = new LobbyUpdate()
{
Name = name,
GameMode = gameMode,
MaxPlayerCount = maxPlayerCount,
PlayerCount = playerCount,
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
PasswordHash = hash,
PasswordSalt = salt,
HostIp = ip,
HostPort = port
};
@ -257,7 +280,7 @@ namespace Lobbies
private void TcpClient_DataReceived(int dataLength, Memory<byte> data)
{
try
{
{
if (dataLength > 0)
{
switch (LobbyMessageIdentifier.ReadLobbyMessageIdentifier(data.Span))
@ -277,6 +300,7 @@ namespace Lobbies
var lobbyInfo = LobbyInfo.Deserialize(data.Span);
if (lobbyInfo != null)
{
lobbyInformation[lobbyInfo.Id] = lobbyInfo;
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyUpdate, EventData = lobbyInfo });
}
}
@ -286,6 +310,7 @@ namespace Lobbies
var lobbyDelete = LobbyDelete.Deserialize(data.Span);
if (lobbyDelete != null)
{
lobbyInformation.Remove(lobbyDelete.Id);
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyDelete, EventData = lobbyDelete });
}
}

View File

@ -1,13 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<OutputPath>..\Assets\NetworkLobbyClient\Runtime</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LobbyServerDto\LobbyServerDto.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,37 @@

using System.Security.Cryptography;
namespace Lobbies
{
internal class PasswordHash
{
const int keySize = 64;
const int saltSize = 16;
const int iterations = 350000;
static HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA512;
static internal (byte[] hash, byte[] salt) Hash(string text)
{
using (var pbkdf2 = new Rfc2898DeriveBytes(
text,
saltSize,
iterations,
hashAlgorithm))
{
return (pbkdf2.GetBytes(keySize), pbkdf2.Salt);
}
}
static internal byte[] Hash(string text, byte[] salt)
{
using (var pbkdf2 = new Rfc2898DeriveBytes(
text,
salt,
iterations,
hashAlgorithm))
{
return pbkdf2.GetBytes(keySize);
}
}
}
}

View File

@ -29,9 +29,14 @@ namespace Lobbies
try
{
cancellationTokenSource!.Token.ThrowIfCancellationRequested();
running = true;
tcpClient = new TcpClient();
await tcpClient.ConnectAsync(host, port, cancellationTokenSource!.Token);
tcpClient = new TcpClient();
using (cancellationTokenSource!.Token.Register(() => { tcpClient.Close(); }))
{
await tcpClient.ConnectAsync(host, port);
}
networkStream = tcpClient.GetStream();
Memory<byte> buffer = new byte[4096];

View File

@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\LobbyClient\LobbyClient.csproj" />
<ProjectReference Include="..\LobbyServerDto\LobbyServerDto.csproj" />
</ItemGroup>
</Project>

View File

@ -5,13 +5,13 @@ VisualStudioVersion = 17.7.34003.232
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServer", "LobbyServer\LobbyServer.csproj", "{64B89314-4185-4025-B8B9-AC0D3A921E6A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerDto", "LobbyServerDto\LobbyServerDto.csproj", "{5AA6CC31-3A59-4463-8E25-56852430765C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyClientTest", "LobbyClientTest\LobbyClientTest.csproj", "{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerSourceGenerator", "LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj", "{5353E418-2365-432B-ACC6-C20448F93CC9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyClient", "LobbyClient\LobbyClient.csproj", "{5BF63DAB-4D00-4A54-9881-43464732F6AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LobbyClient", "LobbyClient\LobbyClient.csproj", "{1D6DE49F-7A41-4117-A9AF-6EE3417948EB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerDto", "LobbyServerDto\LobbyServerDto.csproj", "{46E27B7A-A879-4493-BCA4-1994A367A637}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LobbyClientTest", "LobbyClientTest\LobbyClientTest.csproj", "{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerSourceGenerator", "LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj", "{04F95131-C7EF-410B-94E5-2D9162763155}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -23,22 +23,22 @@ Global
{64B89314-4185-4025-B8B9-AC0D3A921E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64B89314-4185-4025-B8B9-AC0D3A921E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64B89314-4185-4025-B8B9-AC0D3A921E6A}.Release|Any CPU.Build.0 = Release|Any CPU
{5AA6CC31-3A59-4463-8E25-56852430765C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AA6CC31-3A59-4463-8E25-56852430765C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AA6CC31-3A59-4463-8E25-56852430765C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AA6CC31-3A59-4463-8E25-56852430765C}.Release|Any CPU.Build.0 = Release|Any CPU
{5353E418-2365-432B-ACC6-C20448F93CC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5353E418-2365-432B-ACC6-C20448F93CC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5353E418-2365-432B-ACC6-C20448F93CC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5353E418-2365-432B-ACC6-C20448F93CC9}.Release|Any CPU.Build.0 = Release|Any CPU
{1D6DE49F-7A41-4117-A9AF-6EE3417948EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D6DE49F-7A41-4117-A9AF-6EE3417948EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D6DE49F-7A41-4117-A9AF-6EE3417948EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D6DE49F-7A41-4117-A9AF-6EE3417948EB}.Release|Any CPU.Build.0 = Release|Any CPU
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Release|Any CPU.Build.0 = Release|Any CPU
{5BF63DAB-4D00-4A54-9881-43464732F6AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BF63DAB-4D00-4A54-9881-43464732F6AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BF63DAB-4D00-4A54-9881-43464732F6AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BF63DAB-4D00-4A54-9881-43464732F6AD}.Release|Any CPU.Build.0 = Release|Any CPU
{46E27B7A-A879-4493-BCA4-1994A367A637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46E27B7A-A879-4493-BCA4-1994A367A637}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46E27B7A-A879-4493-BCA4-1994A367A637}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46E27B7A-A879-4493-BCA4-1994A367A637}.Release|Any CPU.Build.0 = Release|Any CPU
{04F95131-C7EF-410B-94E5-2D9162763155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04F95131-C7EF-410B-94E5-2D9162763155}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04F95131-C7EF-410B-94E5-2D9162763155}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04F95131-C7EF-410B-94E5-2D9162763155}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -23,6 +23,7 @@ namespace LobbyServer
public int PlayerCount { get; set; }
public int MaxPlayerCount { get; set; }
public byte[]? PasswordHash { get; set; }
public byte[]? PasswordSalt { get; set; }
public required string HostIp { get; set; }
public int HostPort { get; set; }
}

View File

@ -50,6 +50,7 @@ tcpServer.DataReceived += (clientId, dataLength, data) =>
PlayerCount = lobbyCreate.PlayerCount,
MaxPlayerCount = lobbyCreate.MaxPlayerCount,
PasswordHash = lobbyCreate.PasswordHash,
PasswordSalt = lobbyCreate.PasswordSalt,
HostClientId = clientId,
HostIp = lobbyCreate.HostIp == null ? tcpServer.GetClientIp(clientId)! : lobbyCreate.HostIp,
HostPort = lobbyCreate.HostPort,
@ -110,6 +111,7 @@ tcpServer.DataReceived += (clientId, dataLength, data) =>
existingLobby.PlayerCount = lobbyUpdate.PlayerCount;
existingLobby.MaxPlayerCount = lobbyUpdate.MaxPlayerCount;
existingLobby.PasswordHash = lobbyUpdate.PasswordHash;
existingLobby.PasswordSalt = lobbyUpdate.PasswordSalt;
if (lobbyUpdate.HostIp != null)
existingLobby.HostIp = lobbyUpdate.HostIp;
@ -353,7 +355,8 @@ async Task SendLobbyUpdate(Lobby.LobbyUpdateType lobbyUpdateType, Lobby lobby)
GameMode = lobby.GameMode,
MaxPlayerCount = lobby.MaxPlayerCount,
PlayerCount = lobby.PlayerCount,
PasswordProtected = lobby.PasswordHash != null && lobby.PasswordHash.Length > 0
PasswordProtected = lobby.PasswordHash != null && lobby.PasswordHash.Length > 0,
PasswordSalt = lobby.PasswordSalt
};
messageDataLength = lobbyInfo.Serialize(messageData);
@ -401,7 +404,8 @@ async Task SendLobbiesToClient(int clientId, List<Lobby> lobbies)
GameMode = lobby.GameMode,
MaxPlayerCount = lobby.MaxPlayerCount,
PlayerCount = lobby.PlayerCount,
PasswordProtected = lobby.PasswordHash != null && lobby.PasswordHash.Length > 0
PasswordProtected = lobby.PasswordHash != null && lobby.PasswordHash.Length > 0,
PasswordSalt = lobby.PasswordSalt,
};
var messageDataLength = lobbyInfo.Serialize(messageData);

View File

@ -33,9 +33,14 @@ namespace LobbyServerDto
/// <summary>
/// The hash of a password to protect the lobby. Only users with the password can request host information/nat punch.
/// </summary>
[MaxLength(26)]
[MaxLength(64)]
public byte[]? PasswordHash { get; set; }
/// <summary>
/// The salt used to hash the password.
/// </summary>
[MaxLength(16)]
public byte[]? PasswordSalt { get; set; }
/// <summary>
/// The hosts ip. Used the the host information send to clients on their request.
/// </summary>
[MaxLength(32)]

View File

@ -1,4 +1,6 @@
namespace LobbyServerDto
using System.ComponentModel.DataAnnotations;
namespace LobbyServerDto
{
/// <summary>
/// Send when a lobby is created or updates, this contains the lobby information
@ -29,6 +31,11 @@
/// <summary>
/// True if the lobby requires a password to gain access
/// </summary>
public bool PasswordProtected { get; set; }
public bool PasswordProtected { get; set; }
/// <summary>
/// The salt used to hash the password.
/// </summary>
[MaxLength(16)]
public byte[]? PasswordSalt { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace LobbyServerDto
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public class LobbyMessageAttribute : Attribute
{
}
}

View File

@ -1,4 +1,6 @@
namespace LobbyServerDto
using System;
namespace LobbyServerDto
{
/// <summary>
/// Used to read the message identifer from a received object

View File

@ -3,12 +3,17 @@
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj" OutputItemType="Analyzer" />
<ProjectReference Include="..\LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>

View File

@ -29,6 +29,11 @@ namespace LobbyServerDto
/// </summary>
public byte[]? PasswordHash { get; set; }
/// <summary>
/// The salt used to hash the password.
/// </summary>
[MaxLength(16)]
public byte[]? PasswordSalt { get; set; }
/// <summary>
/// The hosts ip
/// </summary>
[MaxLength(32)]

View File

@ -158,7 +158,7 @@ using System.Text;
s.Append($@"
if ({name} != null)
{{
int maxLength = Math.Min(PasswordHash.Length, {maxLength});
int maxLength = Math.Min({name}.Length, {maxLength});
uint v = (uint)maxLength;
while (v >= 0x80)
{{
@ -167,7 +167,7 @@ using System.Text;
}}
buffer[offset++] = (byte)v;
Buffer.BlockCopy(PasswordHash, 0, buffer, offset, maxLength);
Buffer.BlockCopy({name}, 0, buffer, offset, maxLength);
offset += maxLength;
}}
else
@ -237,7 +237,7 @@ using System.Text;
case "Guid":
s.Append($@"
{{
ret.{name} = new Guid(buffer.Slice(offset, 16));
ret.{name} = new Guid(buffer.Slice(offset, 16).ToArray());
offset+=16;
}}");
break;
@ -262,7 +262,7 @@ using System.Text;
if(strLen > 0)
{{
ret.{name} = Encoding.UTF8.GetString(buffer.Slice(offset, strLen));
ret.{name} = Encoding.UTF8.GetString(buffer.Slice(offset, strLen).ToArray());
offset += strLen;
}}
}}");
@ -334,9 +334,4 @@ using System.Text;
return obj.Item1.GetHashCode();
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public class LobbyMessageAttribute : Attribute
{
}
}

View File

@ -15,6 +15,10 @@
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<None Remove="bin\Release\netstandard2.0\\LobbyServerSourceGenerator.dll" />
</ItemGroup>
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />