Skip to content

Commit

Permalink
Update to .NET 9 + use System.Text.Json (#100)
Browse files Browse the repository at this point in the history
* Change to .NET 8

* Update packages

* Drop Newtonsoft.Json (needs to wait for .NET 9)

* Switch to .NET 9

* Switch libraries to RC1

* Update BytexDigital.Steam

* Update .NET version in workflows

* Update to .NET 9 release version

* Replace OnFailure() with TapError()
  • Loading branch information
3Mydlo3 authored Nov 17, 2024
1 parent 5fc4356 commit 2c08d47
Show file tree
Hide file tree
Showing 47 changed files with 259 additions and 252 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet-core-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: 9.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dotnet-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
with:
fetch-depth: 0

- name: Install .NET 6.0
- name: Install .NET 9.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
dotnet-version: '9.0.x'

- name: Build, Tests, Cover, Pack and Publish (on push tag)
shell: bash
Expand Down
23 changes: 12 additions & 11 deletions ArmaForces.Arma.Server.Tests/ArmaForces.Arma.Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@

<PropertyGroup>
<Version>0.1</Version>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="AutoFixture" Version="4.18.1" />
<PackageReference Include="FluentAssertions" Version="6.12.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<!-- TODO: Replace Moq with something else if needed. Do not update. -->
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="System.IO.Abstractions" Version="17.0.15" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="17.0.15" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="System.IO.Abstractions" Version="21.0.29" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.29" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
21 changes: 10 additions & 11 deletions ArmaForces.Arma.Server/ArmaForces.Arma.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
<PropertyGroup>
<Version>0.1</Version>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CSharpFunctionalExtensions" Version="2.29.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
<PackageReference Include="CSharpFunctionalExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.IO.Abstractions" Version="17.0.15" />
<PackageReference Include="System.Management" Version="6.0.0" />
<PackageReference Include="System.IO.Abstractions" Version="19.2.91" />
<PackageReference Include="System.Management" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
9 changes: 4 additions & 5 deletions ArmaForces.Arma.Server/Config/ModsetConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using CSharpFunctionalExtensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace ArmaForces.Arma.Server.Config
Expand Down Expand Up @@ -70,7 +69,7 @@ private string LoadServerPassword()
if (_fileSystem.File.Exists(ConfigJson))
{
var modsetConfigModel =
JsonConvert.DeserializeObject<ConfigSimpleModel>(_fileSystem.File.ReadAllText(ConfigJson));
JsonSerializer.Deserialize<ConfigSimpleModel>(_fileSystem.File.ReadAllText(ConfigJson));
if (modsetConfigModel.Server?.Password != null)

Check warning on line 73 in ArmaForces.Arma.Server/Config/ModsetConfig.cs

View workflow job for this annotation

GitHub Actions / tests

Dereference of a possibly null reference.
{
return modsetConfigModel.Server.Password;
Expand All @@ -80,7 +79,7 @@ private string LoadServerPassword()
if (!_fileSystem.File.Exists(_serverConfig.ConfigJson)) return string.Empty;

var serverConfigModel =
JsonConvert.DeserializeObject<ConfigSimpleModel>(
JsonSerializer.Deserialize<ConfigSimpleModel>(
_fileSystem.File.ReadAllText(_serverConfig.ConfigJson));

return serverConfigModel.Server?.Password ?? string.Empty;

Check warning on line 85 in ArmaForces.Arma.Server/Config/ModsetConfig.cs

View workflow job for this annotation

GitHub Actions / tests

Dereference of a possibly null reference.
Expand Down Expand Up @@ -127,8 +126,8 @@ private Result PrepareModsetConfig()
{
// Apply modset config on top of default config
var modsetConfig = new ConfigurationBuilder()
.AddJsonStream(_fileSystem.FileStream.Create(_serverConfig.ConfigJson, FileMode.Open))
.AddJsonStream(_fileSystem.FileStream.Create(ConfigJson, FileMode.Open))
.AddJsonStream(_fileSystem.FileStream.New(_serverConfig.ConfigJson, FileMode.Open))
.AddJsonStream(_fileSystem.FileStream.New(ConfigJson, FileMode.Open))
.Build();

ServerPassword = modsetConfig["server:password"] ?? string.Empty;
Expand Down
2 changes: 1 addition & 1 deletion ArmaForces.Arma.Server/Config/ServerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Result CopyConfigFiles() {

return GetOrCreateServerConfigDir()
.Tap(() => _logger.LogInformation("ServerConfig files copied"))
.OnFailure(error => _logger.LogError("ServerConfig files could not be copied: {Error}", error));
.TapError(error => _logger.LogError("ServerConfig files could not be copied: {Error}", error));
}

private void SetProperties() {
Expand Down
7 changes: 4 additions & 3 deletions ArmaForces.Arma.Server/Config/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using System.IO;
using System.IO.Abstractions;
using System.Text.Json;
using System.Threading.Tasks;
using ArmaForces.Arma.Server.Constants;
using ArmaForces.Arma.Server.Exceptions;
using CSharpFunctionalExtensions;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;

namespace ArmaForces.Arma.Server.Config
{
Expand Down Expand Up @@ -50,7 +51,7 @@ public Settings(
public static Settings LoadSettings(IServiceProvider serviceProvider)
{
var json = File.ReadAllTextAsync(SettingsJsonPath).Result;
return JsonConvert.DeserializeObject<Settings>(json);
return JsonSerializer.Deserialize<Settings>(json);

Check warning on line 54 in ArmaForces.Arma.Server/Config/Settings.cs

View workflow job for this annotation

GitHub Actions / tests

Possible null reference return.
}

public Result LoadSettings()
Expand Down Expand Up @@ -86,7 +87,7 @@ public async Task<Result> ReloadSettings(ISettings settings)
SteamUser = settings.SteamUser;
SteamPassword = settings.SteamPassword;

var json = JsonConvert.SerializeObject(this, Formatting.Indented);
var json = JsonSerializer.Serialize(this, JsonOptions.Default);
await _fileSystem.File.WriteAllTextAsync(SettingsJsonPath, json);

return Result.Success();
Expand Down
23 changes: 23 additions & 0 deletions ArmaForces.Arma.Server/Constants/JsonOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace ArmaForces.Arma.Server.Constants;

public static class JsonOptions
{
public static JsonSerializerOptions Legacy = new()
{
WriteIndented = true
};

public static JsonSerializerOptions Default = new()
{
WriteIndented = true,
Converters =
{
new JsonStringEnumConverter()
},
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.Never
};
}
4 changes: 2 additions & 2 deletions ArmaForces.Arma.Server/Features/Keys/KeysPreparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ private Result CopyNewKeys(Modset modset)
{
CopyKeysForMod(mod)
.Tap(modBikeys => modBikeysList.Add(modBikeys))
.OnFailure(error => LogKeysCopyError(mod, error))
.OnFailure(_ => modBikeysList.Add(new ModBikeys(mod)));
.TapError(error => LogKeysCopyError(mod, error))
.TapError(_ => modBikeysList.Add(new ModBikeys(mod)));
}

_logger.LogInformation(
Expand Down
77 changes: 27 additions & 50 deletions ArmaForces.Arma.Server/Features/Servers/DTOs/ServerStatus.cs
Original file line number Diff line number Diff line change
@@ -1,57 +1,34 @@
using System;
using Newtonsoft.Json;

namespace ArmaForces.Arma.Server.Features.Servers.DTOs
{
public class ServerStatus
public class ServerStatus(
ServerStatusEnum status = ServerStatusEnum.Stopped,
string? name = null,
string? modsetName = null,
string? mapName = null,
int? playersCount = null,
int? playersMaxCount = null,
int? port = null,
DateTimeOffset? startTime = null,
int? headlessClientsCount = null)
{
public ServerStatus(
ServerStatusEnum serverStatusEnum = ServerStatusEnum.Stopped,
string? name = null,
string? modsetName = null,
string? mapName = null,
int? playersCount = null,
int? playersMaxCount = null,
int? port = null,
DateTimeOffset? startTime = null,
int? headlessClientsCount = null)
{
Status = serverStatusEnum;
Name = name;
ModsetName = modsetName;
Map = mapName;
Players = playersCount;
PlayersMax = playersMaxCount;
Port = port;
StartTime = startTime;
HeadlessClientsConnected = headlessClientsCount;
}

[JsonProperty(Required = Required.Always)]
public ServerStatusEnum Status { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? Name { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? ModsetName { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? Map { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? Players { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? PlayersMax { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? Port {get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public DateTimeOffset? StartTime { get; }

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? HeadlessClientsConnected { get; }
public ServerStatusEnum Status { get; init; } = status;

public string? Name { get; init; } = name;

public string? ModsetName { get; init; } = modsetName;

public string? Map { get; init; } = mapName;

public int? Players { get; init; } = playersCount;

public int? PlayersMax { get; init; } = playersMaxCount;

public int? Port {get; init; } = port;

public DateTimeOffset? StartTime { get; init; } = startTime;

public int? HeadlessClientsConnected { get; init; } = headlessClientsCount;
}
}
22 changes: 12 additions & 10 deletions ArmaForces.Arma.Server/Features/Servers/ServerStatusFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ public async Task<ServerStatus> GetServerStatus(IDedicatedServer dedicatedServer
var ipEndPoint = new IPEndPoint(IPAddress.Loopback, dedicatedServer.SteamQueryPort);
var serverInfo = await A2SInfo.GetServerInfoAsync(ipEndPoint, cancellationToken, _logger);

return new ServerStatus(
GetServerStatusEnum(dedicatedServer, serverInfo),
serverInfo?.Name,
dedicatedServer?.Modset.Name,
serverInfo?.Map,
serverInfo?.Players,
serverInfo?.MaxPlayers,
dedicatedServer?.Port,
dedicatedServer?.StartTime,
dedicatedServer?.HeadlessClientsConnected);
return new ServerStatus
{
Status = GetServerStatusEnum(dedicatedServer, serverInfo),
Name = serverInfo?.Name,
ModsetName = dedicatedServer.Modset.Name,
Map = serverInfo?.Map,
Players = serverInfo?.Players,
PlayersMax = serverInfo?.MaxPlayers,
Port = dedicatedServer?.Port,
StartTime = dedicatedServer?.StartTime,
HeadlessClientsConnected = dedicatedServer?.HeadlessClientsConnected
};
}

private static ServerStatusEnum GetServerStatusEnum(IDedicatedServer? dedicatedServer, A2SInfo? serverInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@

<PropertyGroup>
<Version>0.1</Version>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="AutoFixture" Version="4.18.1" />
<PackageReference Include="FluentAssertions" Version="6.12.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<!-- TODO: Replace Moq with something else if needed. Do not update. -->
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="17.0.15" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.29" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using ArmaForces.Arma.Server.Config;
using ArmaForces.Arma.Server.Extensions;
Expand All @@ -17,7 +18,6 @@
using FluentAssertions.Execution;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Newtonsoft.Json;
using Xunit;

namespace ArmaForces.ArmaServerManager.Tests.Features.Mods
Expand Down Expand Up @@ -133,7 +133,7 @@ public async Task ModExists_LoadCacheModCachedNoDirectory_ReturnsFalse() {
var cacheFilePath = $"{_settingsMock.ModsDirectory}\\{_settingsMock.ModsManagerCacheFileName}.json";
ISet<Mod> mods = new HashSet<Mod>();
mods.Add(_mod);
await _fileSystemMock.File.WriteAllTextAsync(cacheFilePath, JsonConvert.SerializeObject(mods));
await _fileSystemMock.File.WriteAllTextAsync(cacheFilePath, JsonSerializer.Serialize(mods));

var modsCache = GetModsCache();

Expand All @@ -149,7 +149,7 @@ public async Task ModExists_LoadCacheModCachedDirectoryPresent_ReturnsTrue() {
var cacheFilePath = $"{_settingsMock.ModsDirectory}\\{_settingsMock.ModsManagerCacheFileName}.json";
ISet<Mod> mods = new HashSet<Mod>();
mods.Add(_mod);
await _fileSystemMock.File.WriteAllTextAsync(cacheFilePath, JsonConvert.SerializeObject(mods));
await _fileSystemMock.File.WriteAllTextAsync(cacheFilePath, JsonSerializer.Serialize(mods));
_fileSystemMock.Directory.CreateDirectory(_mod.Directory);

var modsCache = GetModsCache();
Expand Down
Loading

0 comments on commit 2c08d47

Please sign in to comment.