From 97df572f1e182e41b4df368a8fedaee8fe4738e3 Mon Sep 17 00:00:00 2001 From: Thomas Woischnig Date: Fri, 1 Dec 2023 22:58:44 +0100 Subject: [PATCH] Binary support --- .../Runtime/LobbyClient.deps.json | 121 ++++++++++++++++++ .../Runtime/LobbyClient.dll | Bin 0 -> 27136 bytes .../Runtime/LobbyServerDto.dll | Bin 0 -> 23040 bytes .../Runtime/Unity.LobbyClient.Runtime.asmdef | 23 ++++ Assets/NetworkLobbyClient/package.json | 17 +++ LobbyClient/LobbyClient.cs | 41 ++++-- LobbyClient/LobbyClient.csproj | 5 +- LobbyClient/PasswordHash.cs | 37 ++++++ LobbyClient/TcpClient.cs | 9 +- LobbyClientTest/LobbyClientTest.csproj | 1 + LobbyServer.sln | 32 ++--- LobbyServer/Lobby.cs | 1 + LobbyServer/Program.cs | 8 +- LobbyServerDto/LobbyCreate.cs | 7 +- LobbyServerDto/LobbyInfo.cs | 11 +- LobbyServerDto/LobbyMessageAttribute.cs | 7 + LobbyServerDto/LobbyMessageIdentifier.cs | 4 +- LobbyServerDto/LobbyServerDto.csproj | 9 +- LobbyServerDto/LobbyUpdate.cs | 5 + .../LobbyMessageSourceGenerator.cs | 13 +- .../LobbyServerSourceGenerator.csproj | 4 + 21 files changed, 310 insertions(+), 45 deletions(-) create mode 100644 Assets/NetworkLobbyClient/Runtime/LobbyClient.deps.json create mode 100644 Assets/NetworkLobbyClient/Runtime/LobbyClient.dll create mode 100644 Assets/NetworkLobbyClient/Runtime/LobbyServerDto.dll create mode 100644 Assets/NetworkLobbyClient/Runtime/Unity.LobbyClient.Runtime.asmdef create mode 100644 Assets/NetworkLobbyClient/package.json create mode 100644 LobbyClient/PasswordHash.cs create mode 100644 LobbyServerDto/LobbyMessageAttribute.cs 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 0000000000000000000000000000000000000000..b750ab335016a98502b0f22b36b790b9f341ca95 GIT binary patch literal 27136 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 VjHtgE`-5LN!+*j2{D0Kk{{_F}=l=iz literal 0 HcmV?d00001 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 @@ + + + +