diff --git a/Assets/NetworkLobbyClient/Runtime/LobbyClient.deps.json b/Assets/NetworkLobbyClient/Runtime/LobbyClient.deps.json new file mode 100644 index 0000000..486b0cd --- /dev/null +++ b/Assets/NetworkLobbyClient/Runtime/LobbyClient.deps.json @@ -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": "" + } + } +} \ No newline at end of file diff --git a/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll b/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll new file mode 100644 index 0000000..b750ab3 Binary files /dev/null and b/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll differ diff --git a/Assets/NetworkLobbyClient/Runtime/LobbyServerDto.dll b/Assets/NetworkLobbyClient/Runtime/LobbyServerDto.dll new file mode 100644 index 0000000..b270f47 Binary files /dev/null and b/Assets/NetworkLobbyClient/Runtime/LobbyServerDto.dll differ diff --git a/Assets/NetworkLobbyClient/Runtime/Unity.LobbyClient.Runtime.asmdef b/Assets/NetworkLobbyClient/Runtime/Unity.LobbyClient.Runtime.asmdef new file mode 100644 index 0000000..70a7dad --- /dev/null +++ b/Assets/NetworkLobbyClient/Runtime/Unity.LobbyClient.Runtime.asmdef @@ -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 +} \ No newline at end of file diff --git a/Assets/NetworkLobbyClient/package.json b/Assets/NetworkLobbyClient/package.json new file mode 100644 index 0000000..b21672f --- /dev/null +++ b/Assets/NetworkLobbyClient/package.json @@ -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" + } +} \ No newline at end of file diff --git a/LobbyClient/LobbyClient.cs b/LobbyClient/LobbyClient.cs index e6a7ec6..3554cb2 100644 --- a/LobbyClient/LobbyClient.cs +++ b/LobbyClient/LobbyClient.cs @@ -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 lobbyInformation = new Dictionary(); 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 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 }); } } diff --git a/LobbyClient/LobbyClient.csproj b/LobbyClient/LobbyClient.csproj index 2d6db45..37470c9 100644 --- a/LobbyClient/LobbyClient.csproj +++ b/LobbyClient/LobbyClient.csproj @@ -1,13 +1,14 @@  - net7.0 + netstandard2.1 latest enable + ..\Assets\NetworkLobbyClient\Runtime + false - diff --git a/LobbyClient/PasswordHash.cs b/LobbyClient/PasswordHash.cs new file mode 100644 index 0000000..675bc5d --- /dev/null +++ b/LobbyClient/PasswordHash.cs @@ -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); + } + } + } +} diff --git a/LobbyClient/TcpClient.cs b/LobbyClient/TcpClient.cs index 790af20..5968dff 100644 --- a/LobbyClient/TcpClient.cs +++ b/LobbyClient/TcpClient.cs @@ -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 buffer = new byte[4096]; diff --git a/LobbyClientTest/LobbyClientTest.csproj b/LobbyClientTest/LobbyClientTest.csproj index d2c3ee6..e25cdbf 100644 --- a/LobbyClientTest/LobbyClientTest.csproj +++ b/LobbyClientTest/LobbyClientTest.csproj @@ -9,6 +9,7 @@ + diff --git a/LobbyServer.sln b/LobbyServer.sln index 02b567d..aaad659 100644 --- a/LobbyServer.sln +++ b/LobbyServer.sln @@ -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 diff --git a/LobbyServer/Lobby.cs b/LobbyServer/Lobby.cs index da5ca88..5ba8b79 100644 --- a/LobbyServer/Lobby.cs +++ b/LobbyServer/Lobby.cs @@ -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; } } diff --git a/LobbyServer/Program.cs b/LobbyServer/Program.cs index 61e4dc6..7473bf0 100644 --- a/LobbyServer/Program.cs +++ b/LobbyServer/Program.cs @@ -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 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); diff --git a/LobbyServerDto/LobbyCreate.cs b/LobbyServerDto/LobbyCreate.cs index 7893dc0..f3159a6 100644 --- a/LobbyServerDto/LobbyCreate.cs +++ b/LobbyServerDto/LobbyCreate.cs @@ -33,9 +33,14 @@ namespace LobbyServerDto /// /// The hash of a password to protect the lobby. Only users with the password can request host information/nat punch. /// - [MaxLength(26)] + [MaxLength(64)] public byte[]? PasswordHash { get; set; } /// + /// The salt used to hash the password. + /// + [MaxLength(16)] + public byte[]? PasswordSalt { get; set; } + /// /// The hosts ip. Used the the host information send to clients on their request. /// [MaxLength(32)] diff --git a/LobbyServerDto/LobbyInfo.cs b/LobbyServerDto/LobbyInfo.cs index 22d3a39..c9a5106 100644 --- a/LobbyServerDto/LobbyInfo.cs +++ b/LobbyServerDto/LobbyInfo.cs @@ -1,4 +1,6 @@ -namespace LobbyServerDto +using System.ComponentModel.DataAnnotations; + +namespace LobbyServerDto { /// /// Send when a lobby is created or updates, this contains the lobby information @@ -29,6 +31,11 @@ /// /// True if the lobby requires a password to gain access /// - public bool PasswordProtected { get; set; } + public bool PasswordProtected { get; set; } + /// + /// The salt used to hash the password. + /// + [MaxLength(16)] + public byte[]? PasswordSalt { get; set; } } } diff --git a/LobbyServerDto/LobbyMessageAttribute.cs b/LobbyServerDto/LobbyMessageAttribute.cs new file mode 100644 index 0000000..71ad783 --- /dev/null +++ b/LobbyServerDto/LobbyMessageAttribute.cs @@ -0,0 +1,7 @@ +namespace LobbyServerDto +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] + public class LobbyMessageAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/LobbyServerDto/LobbyMessageIdentifier.cs b/LobbyServerDto/LobbyMessageIdentifier.cs index 93443c2..59952a1 100644 --- a/LobbyServerDto/LobbyMessageIdentifier.cs +++ b/LobbyServerDto/LobbyMessageIdentifier.cs @@ -1,4 +1,6 @@ -namespace LobbyServerDto +using System; + +namespace LobbyServerDto { /// /// Used to read the message identifer from a received object diff --git a/LobbyServerDto/LobbyServerDto.csproj b/LobbyServerDto/LobbyServerDto.csproj index 7e1cc03..99aa9b0 100644 --- a/LobbyServerDto/LobbyServerDto.csproj +++ b/LobbyServerDto/LobbyServerDto.csproj @@ -3,12 +3,17 @@ enable enable - net7.0 + netstandard2.0 + latest true + + + + - + diff --git a/LobbyServerDto/LobbyUpdate.cs b/LobbyServerDto/LobbyUpdate.cs index 2dbceab..d9dd5d1 100644 --- a/LobbyServerDto/LobbyUpdate.cs +++ b/LobbyServerDto/LobbyUpdate.cs @@ -29,6 +29,11 @@ namespace LobbyServerDto /// public byte[]? PasswordHash { get; set; } /// + /// The salt used to hash the password. + /// + [MaxLength(16)] + public byte[]? PasswordSalt { get; set; } + /// /// The hosts ip /// [MaxLength(32)] diff --git a/LobbyServerSourceGenerator/LobbyMessageSourceGenerator.cs b/LobbyServerSourceGenerator/LobbyMessageSourceGenerator.cs index f79219d..973b5e4 100644 --- a/LobbyServerSourceGenerator/LobbyMessageSourceGenerator.cs +++ b/LobbyServerSourceGenerator/LobbyMessageSourceGenerator.cs @@ -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 - { - } } diff --git a/LobbyServerSourceGenerator/LobbyServerSourceGenerator.csproj b/LobbyServerSourceGenerator/LobbyServerSourceGenerator.csproj index a6941ba..8845a69 100644 --- a/LobbyServerSourceGenerator/LobbyServerSourceGenerator.csproj +++ b/LobbyServerSourceGenerator/LobbyServerSourceGenerator.csproj @@ -15,6 +15,10 @@ + + + +