Binary support
parent
840218f119
commit
97df572f1e
|
|
@ -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.
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,6 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -20,6 +18,7 @@ namespace Lobbies
|
||||||
|
|
||||||
AutoResetEvent waitForExternalIp = new AutoResetEvent(false);
|
AutoResetEvent waitForExternalIp = new AutoResetEvent(false);
|
||||||
|
|
||||||
|
private Dictionary<Guid, LobbyInfo> lobbyInformation = new Dictionary<Guid, LobbyInfo>();
|
||||||
private string? host;
|
private string? host;
|
||||||
private int port;
|
private int port;
|
||||||
private int connectionId;
|
private int connectionId;
|
||||||
|
|
@ -76,6 +75,13 @@ 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()
|
var lobbyCreate = new LobbyCreate()
|
||||||
{
|
{
|
||||||
GameId = gameId,
|
GameId = gameId,
|
||||||
|
|
@ -83,7 +89,8 @@ namespace Lobbies
|
||||||
GameMode = gameMode,
|
GameMode = gameMode,
|
||||||
MaxPlayerCount = maxPlayerCount,
|
MaxPlayerCount = maxPlayerCount,
|
||||||
PlayerCount = 0,
|
PlayerCount = 0,
|
||||||
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
|
PasswordHash = hash,
|
||||||
|
PasswordSalt = salt,
|
||||||
HostIp = ip,
|
HostIp = ip,
|
||||||
HostPort = port
|
HostPort = port
|
||||||
};
|
};
|
||||||
|
|
@ -95,10 +102,14 @@ namespace Lobbies
|
||||||
|
|
||||||
public void RequestLobbyHostInfo(Guid lobbyId, string? password)
|
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()
|
var lobbyCreate = new LobbyRequestHostInfo()
|
||||||
{
|
{
|
||||||
LobbyId = lobbyId,
|
LobbyId = lobbyId,
|
||||||
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
|
PasswordHash = passwordHash,
|
||||||
};
|
};
|
||||||
|
|
||||||
byte[] messageData = bufferRental.Rent();
|
byte[] messageData = bufferRental.Rent();
|
||||||
|
|
@ -110,13 +121,17 @@ namespace Lobbies
|
||||||
public delegate void SendUdpMessageCallback(IPEndPoint remoteEndpoint, byte[] messageBuffer, int messageLength);
|
public delegate void SendUdpMessageCallback(IPEndPoint remoteEndpoint, byte[] messageBuffer, int messageLength);
|
||||||
public void RequestLobbyNatPunch(Guid lobbyId, string? password, SendUdpMessageCallback sendUdpCallback)
|
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(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
QueryExternalIpAndPort(sendUdpCallback);
|
QueryExternalIpAndPort(sendUdpCallback);
|
||||||
var lobbyRequestNatPunch = new LobbyRequestNatPunch()
|
var lobbyRequestNatPunch = new LobbyRequestNatPunch()
|
||||||
{
|
{
|
||||||
LobbyId = lobbyId,
|
LobbyId = lobbyId,
|
||||||
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
|
PasswordHash = passwordHash,
|
||||||
ClientIp = externalIp,
|
ClientIp = externalIp,
|
||||||
ClientPort = externalPort
|
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)
|
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()
|
var lobbyUpdate = new LobbyUpdate()
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
GameMode = gameMode,
|
GameMode = gameMode,
|
||||||
MaxPlayerCount = maxPlayerCount,
|
MaxPlayerCount = maxPlayerCount,
|
||||||
PlayerCount = playerCount,
|
PlayerCount = playerCount,
|
||||||
PasswordHash = string.IsNullOrEmpty(password) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(password)),
|
PasswordHash = hash,
|
||||||
|
PasswordSalt = salt,
|
||||||
HostIp = ip,
|
HostIp = ip,
|
||||||
HostPort = port
|
HostPort = port
|
||||||
};
|
};
|
||||||
|
|
@ -277,6 +300,7 @@ namespace Lobbies
|
||||||
var lobbyInfo = LobbyInfo.Deserialize(data.Span);
|
var lobbyInfo = LobbyInfo.Deserialize(data.Span);
|
||||||
if (lobbyInfo != null)
|
if (lobbyInfo != null)
|
||||||
{
|
{
|
||||||
|
lobbyInformation[lobbyInfo.Id] = lobbyInfo;
|
||||||
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyUpdate, EventData = lobbyInfo });
|
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyUpdate, EventData = lobbyInfo });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -286,6 +310,7 @@ namespace Lobbies
|
||||||
var lobbyDelete = LobbyDelete.Deserialize(data.Span);
|
var lobbyDelete = LobbyDelete.Deserialize(data.Span);
|
||||||
if (lobbyDelete != null)
|
if (lobbyDelete != null)
|
||||||
{
|
{
|
||||||
|
lobbyInformation.Remove(lobbyDelete.Id);
|
||||||
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyDelete, EventData = lobbyDelete });
|
events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.LobbyDelete, EventData = lobbyDelete });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputPath>..\Assets\NetworkLobbyClient\Runtime</OutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\LobbyServerDto\LobbyServerDto.csproj" />
|
<ProjectReference Include="..\LobbyServerDto\LobbyServerDto.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,9 +29,14 @@ namespace Lobbies
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
cancellationTokenSource!.Token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
tcpClient = new TcpClient();
|
tcpClient = new TcpClient();
|
||||||
await tcpClient.ConnectAsync(host, port, cancellationTokenSource!.Token);
|
using (cancellationTokenSource!.Token.Register(() => { tcpClient.Close(); }))
|
||||||
|
{
|
||||||
|
await tcpClient.ConnectAsync(host, port);
|
||||||
|
}
|
||||||
networkStream = tcpClient.GetStream();
|
networkStream = tcpClient.GetStream();
|
||||||
|
|
||||||
Memory<byte> buffer = new byte[4096];
|
Memory<byte> buffer = new byte[4096];
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\LobbyClient\LobbyClient.csproj" />
|
<ProjectReference Include="..\LobbyClient\LobbyClient.csproj" />
|
||||||
|
<ProjectReference Include="..\LobbyServerDto\LobbyServerDto.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ VisualStudioVersion = 17.7.34003.232
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServer", "LobbyServer\LobbyServer.csproj", "{64B89314-4185-4025-B8B9-AC0D3A921E6A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServer", "LobbyServer\LobbyServer.csproj", "{64B89314-4185-4025-B8B9-AC0D3A921E6A}"
|
||||||
EndProject
|
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
|
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
|
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
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{64B89314-4185-4025-B8B9-AC0D3A921E6A}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{2A5901FE-CE35-4C81-9B8A-E8180EAE7465}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ namespace LobbyServer
|
||||||
public int PlayerCount { get; set; }
|
public int PlayerCount { get; set; }
|
||||||
public int MaxPlayerCount { get; set; }
|
public int MaxPlayerCount { get; set; }
|
||||||
public byte[]? PasswordHash { get; set; }
|
public byte[]? PasswordHash { get; set; }
|
||||||
|
public byte[]? PasswordSalt { get; set; }
|
||||||
public required string HostIp { get; set; }
|
public required string HostIp { get; set; }
|
||||||
public int HostPort { get; set; }
|
public int HostPort { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ tcpServer.DataReceived += (clientId, dataLength, data) =>
|
||||||
PlayerCount = lobbyCreate.PlayerCount,
|
PlayerCount = lobbyCreate.PlayerCount,
|
||||||
MaxPlayerCount = lobbyCreate.MaxPlayerCount,
|
MaxPlayerCount = lobbyCreate.MaxPlayerCount,
|
||||||
PasswordHash = lobbyCreate.PasswordHash,
|
PasswordHash = lobbyCreate.PasswordHash,
|
||||||
|
PasswordSalt = lobbyCreate.PasswordSalt,
|
||||||
HostClientId = clientId,
|
HostClientId = clientId,
|
||||||
HostIp = lobbyCreate.HostIp == null ? tcpServer.GetClientIp(clientId)! : lobbyCreate.HostIp,
|
HostIp = lobbyCreate.HostIp == null ? tcpServer.GetClientIp(clientId)! : lobbyCreate.HostIp,
|
||||||
HostPort = lobbyCreate.HostPort,
|
HostPort = lobbyCreate.HostPort,
|
||||||
|
|
@ -110,6 +111,7 @@ tcpServer.DataReceived += (clientId, dataLength, data) =>
|
||||||
existingLobby.PlayerCount = lobbyUpdate.PlayerCount;
|
existingLobby.PlayerCount = lobbyUpdate.PlayerCount;
|
||||||
existingLobby.MaxPlayerCount = lobbyUpdate.MaxPlayerCount;
|
existingLobby.MaxPlayerCount = lobbyUpdate.MaxPlayerCount;
|
||||||
existingLobby.PasswordHash = lobbyUpdate.PasswordHash;
|
existingLobby.PasswordHash = lobbyUpdate.PasswordHash;
|
||||||
|
existingLobby.PasswordSalt = lobbyUpdate.PasswordSalt;
|
||||||
|
|
||||||
if (lobbyUpdate.HostIp != null)
|
if (lobbyUpdate.HostIp != null)
|
||||||
existingLobby.HostIp = lobbyUpdate.HostIp;
|
existingLobby.HostIp = lobbyUpdate.HostIp;
|
||||||
|
|
@ -353,7 +355,8 @@ async Task SendLobbyUpdate(Lobby.LobbyUpdateType lobbyUpdateType, Lobby lobby)
|
||||||
GameMode = lobby.GameMode,
|
GameMode = lobby.GameMode,
|
||||||
MaxPlayerCount = lobby.MaxPlayerCount,
|
MaxPlayerCount = lobby.MaxPlayerCount,
|
||||||
PlayerCount = lobby.PlayerCount,
|
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);
|
messageDataLength = lobbyInfo.Serialize(messageData);
|
||||||
|
|
@ -401,7 +404,8 @@ async Task SendLobbiesToClient(int clientId, List<Lobby> lobbies)
|
||||||
GameMode = lobby.GameMode,
|
GameMode = lobby.GameMode,
|
||||||
MaxPlayerCount = lobby.MaxPlayerCount,
|
MaxPlayerCount = lobby.MaxPlayerCount,
|
||||||
PlayerCount = lobby.PlayerCount,
|
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);
|
var messageDataLength = lobbyInfo.Serialize(messageData);
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,14 @@ namespace LobbyServerDto
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The hash of a password to protect the lobby. Only users with the password can request host information/nat punch.
|
/// The hash of a password to protect the lobby. Only users with the password can request host information/nat punch.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(26)]
|
[MaxLength(64)]
|
||||||
public byte[]? PasswordHash { get; set; }
|
public byte[]? PasswordHash { get; set; }
|
||||||
/// <summary>
|
/// <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.
|
/// The hosts ip. Used the the host information send to clients on their request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(32)]
|
[MaxLength(32)]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
namespace LobbyServerDto
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace LobbyServerDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send when a lobby is created or updates, this contains the lobby information
|
/// Send when a lobby is created or updates, this contains the lobby information
|
||||||
|
|
@ -30,5 +32,10 @@
|
||||||
/// True if the lobby requires a password to gain access
|
/// True if the lobby requires a password to gain access
|
||||||
/// </summary>
|
/// </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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace LobbyServerDto
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
|
||||||
|
public class LobbyMessageAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
namespace LobbyServerDto
|
using System;
|
||||||
|
|
||||||
|
namespace LobbyServerDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to read the message identifer from a received object
|
/// Used to read the message identifer from a received object
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
|
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj" OutputItemType="Analyzer" />
|
<ProjectReference Include="..\LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,11 @@ namespace LobbyServerDto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[]? PasswordHash { get; set; }
|
public byte[]? PasswordHash { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// The salt used to hash the password.
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(16)]
|
||||||
|
public byte[]? PasswordSalt { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// The hosts ip
|
/// The hosts ip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(32)]
|
[MaxLength(32)]
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ using System.Text;
|
||||||
s.Append($@"
|
s.Append($@"
|
||||||
if ({name} != null)
|
if ({name} != null)
|
||||||
{{
|
{{
|
||||||
int maxLength = Math.Min(PasswordHash.Length, {maxLength});
|
int maxLength = Math.Min({name}.Length, {maxLength});
|
||||||
uint v = (uint)maxLength;
|
uint v = (uint)maxLength;
|
||||||
while (v >= 0x80)
|
while (v >= 0x80)
|
||||||
{{
|
{{
|
||||||
|
|
@ -167,7 +167,7 @@ using System.Text;
|
||||||
}}
|
}}
|
||||||
buffer[offset++] = (byte)v;
|
buffer[offset++] = (byte)v;
|
||||||
|
|
||||||
Buffer.BlockCopy(PasswordHash, 0, buffer, offset, maxLength);
|
Buffer.BlockCopy({name}, 0, buffer, offset, maxLength);
|
||||||
offset += maxLength;
|
offset += maxLength;
|
||||||
}}
|
}}
|
||||||
else
|
else
|
||||||
|
|
@ -237,7 +237,7 @@ using System.Text;
|
||||||
case "Guid":
|
case "Guid":
|
||||||
s.Append($@"
|
s.Append($@"
|
||||||
{{
|
{{
|
||||||
ret.{name} = new Guid(buffer.Slice(offset, 16));
|
ret.{name} = new Guid(buffer.Slice(offset, 16).ToArray());
|
||||||
offset+=16;
|
offset+=16;
|
||||||
}}");
|
}}");
|
||||||
break;
|
break;
|
||||||
|
|
@ -262,7 +262,7 @@ using System.Text;
|
||||||
|
|
||||||
if(strLen > 0)
|
if(strLen > 0)
|
||||||
{{
|
{{
|
||||||
ret.{name} = Encoding.UTF8.GetString(buffer.Slice(offset, strLen));
|
ret.{name} = Encoding.UTF8.GetString(buffer.Slice(offset, strLen).ToArray());
|
||||||
offset += strLen;
|
offset += strLen;
|
||||||
}}
|
}}
|
||||||
}}");
|
}}");
|
||||||
|
|
@ -334,9 +334,4 @@ using System.Text;
|
||||||
return obj.Item1.GetHashCode();
|
return obj.Item1.GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
|
|
||||||
public class LobbyMessageAttribute : Attribute
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="bin\Release\netstandard2.0\\LobbyServerSourceGenerator.dll" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue