Merge branch 'dev' into '1458-AddMapThreadsParam'

This commit is contained in:
Jordan Dominion
2023-07-04 20:27:39 -04:00
95 changed files with 461 additions and 493 deletions
+6 -12
View File
@@ -12,18 +12,12 @@
appveyor.yml
omnisharp.json
README.md
build/**
!build/analyzers.ruleset
!build/tgs.docker.sh
!build/tgs.ico
!build/tgs.png
!build/stylecop.json
!build/Version.props
!build/ControlPanelVersion.props
!build/Common.props
!build/NugetCommon.props
!build/uac_elevation_manifest.xml
build/package/**
build/coverlet.runsettings
build/Dockerfile
build/GenerateMigrations.sh
build/OpenApiValidationSettings.json
build/tgstation-server.service
docs
src/DMAPI
src/Tgstation.Server.Host/ClientApp
+2 -1
View File
@@ -74,8 +74,9 @@ If you don't plan on deploying TGS, the following secrets can be omitted:
- Secret `DOCKER_USERNAME`: Login username for Docker image push.
- Secret `DOCKER_PASSWORD`: Login password for Docker image push.
- Secret `NUGET_API_KEY`: Nuget.org API Key for client libraries push.
- Secret `CODE_SIGNING_BASE64`: Base64 string of a .pfx file containing a Windows code-signing certificate.
- Secret `CODE_SIGNING_BASE64`: Base64 string of a .pfx file containing an X.509 code-signing certificate.
- Secret `CODE_SIGNING_PASSWORD`: Password for importing the above .pfx.
- Variable `CODE_SIGNING_THUMBPRINT`: Thumbprint for the above .pfx
### Know your Code
+8 -8
View File
@@ -1140,10 +1140,10 @@ jobs:
run: dotnet restore
- name: Build ReleaseNotes
run: dotnet build -c Release tools/ReleaseNotes/ReleaseNotes.csproj
run: dotnet build -c Release tools/Tgstation.Server.ReleaseNotes/Tgstation.Server.ReleaseNotes.csproj
- name: Run ReleaseNotes Check
run: dotnet run -c Release --no-build --project tools/ReleaseNotes --winget-template-check ${{ steps.get-sha.outputs.pr_template_sha }}
run: dotnet run -c Release --no-build --project tools/Tgstation.Server.ReleaseNotes --winget-template-check ${{ steps.get-sha.outputs.pr_template_sha }}
ci-completion-gate: # This job exists so there isn't a moving target for branch protections
name: CI Completion Gate
@@ -1304,10 +1304,10 @@ jobs:
run: dotnet restore
- name: Build ReleaseNotes
run: dotnet build -c Release tools/ReleaseNotes/ReleaseNotes.csproj
run: dotnet build -c Release tools/Tgstation.Server.ReleaseNotes/Tgstation.Server.ReleaseNotes.csproj
- name: Run ReleaseNotes with --ensure-release
run: dotnet run -c Release --no-build --project tools/ReleaseNotes --ensure-release
run: dotnet run -c Release --no-build --project tools/Tgstation.Server.ReleaseNotes --ensure-release
deploy-tgs:
name: Deploy TGS
@@ -1332,7 +1332,7 @@ jobs:
dotnet tool restore
- name: Build ReleaseNotes
run: dotnet build -c Release tools/ReleaseNotes/ReleaseNotes.csproj
run: dotnet build -c Release tools/Tgstation.Server.ReleaseNotes/Tgstation.Server.ReleaseNotes.csproj
# We need to rebuild the installer.exe so it can be properly signed
- name: Restore
@@ -1422,7 +1422,7 @@ jobs:
&"C:/Program Files/7-Zip/7z.exe" a ServerUpdatePackage.zip ./ServerUpdatePackage/* -tzip
- name: Generate Release Notes
run: dotnet run -c Release --no-build --project tools/ReleaseNotes ${{ env.TGS_VERSION }}
run: dotnet run -c Release --no-build --project tools/Tgstation.Server.ReleaseNotes ${{ env.TGS_VERSION }}
- name: Create GitHub Release
uses: actions/create-release@v1
@@ -1571,7 +1571,7 @@ jobs:
uses: actions/checkout@v3
- name: Build ReleaseNotes
run: dotnet build -c Release tools/ReleaseNotes
run: dotnet build -c Release tools/Tgstation.Server.ReleaseNotes
- name: Execute Push Script
shell: powershell
@@ -1581,4 +1581,4 @@ jobs:
shell: powershell
run: |
Sleep 15
dotnet run -c Release --no-build --project tools/ReleaseNotes --link-winget ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
dotnet run -c Release --no-build --project tools/Tgstation.Server.ReleaseNotes --link-winget ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+2 -2
View File
@@ -20,8 +20,8 @@ artifacts/
/src/Tgstation.Server.Host/wwwroot
/src/Tgstation.Server.Host/--applicationName
/src/Tgstation.Server.Host/ClientApp
/tools/ReleaseNotes/release_notes.md
/tools/ReleaseNotes/Properties/launchSettings.json
/tools/Tgstation.Server.ReleaseNotes/release_notes.md
launchSettings.json
release_notes.md
*nupkg
*.sqlite3
+9 -7
View File
@@ -46,7 +46,7 @@ Follow the instructions for your OS below.
###### Note about Digital Signatures
Note that the Windows Service and installer executables requires administrative privileges. These are digitally signed against the Root CA managed by [Jordan Dominion](https://github.com/Cyberboss). Consider installing the certificate into your `Trusted Root Authorities` store for cleaner UAC prompts. The certificate can be downloaded [here](https://file.house/zpFb.cer), please validate the thumbprint is `70176acf7ffa2898fa5b5cd6e38b43b38ea5d07f` before installing.
Note that the Windows Service and installer executables require administrative privileges. These are digitally signed against the Root CA managed by [Jordan Dominion](https://github.com/Cyberboss). Consider installing the certificate into your `Trusted Root Authorities` store for cleaner UAC prompts. The certificate can be downloaded [here](https://file.house/zpFb.cer), please validate the thumbprint is `70176acf7ffa2898fa5b5cd6e38b43b38ea5d07f` before installing. The OCSP server for this is `http://ocsp.dextraspace.net`.
##### winget (Windows 10 or later)
@@ -252,17 +252,19 @@ Create an `appsettings.Production.yml` file next to `appsettings.yml`. This will
Password: yourpasshere
```
- `Swarm`: This section should be left `null` unless using the server swarm system. If this is to happen, ensure all swarm servers are set to connect to the same database.
- `Swarm`: This section should be left empty unless using the server swarm system. If this is to happen, ensure all swarm servers are set to connect to the same database.
- `Swarm:PrivateKey`: Should be a secure string set identically on all swarmed servers.
- `Swarm:PrivateKey`: Must be a secure string set identically on all swarmed servers.
- `Swarm:ControllerAddress`: Should be set on all swarmed servers that are **not** the controller server and should be an address the controller server may be reached at.
- `Swarm:ControllerAddress`: Must be set on all swarmed servers that are **not** the controller server and should be an address the controller server may be reached at.
- `Swarm:Address`: Should be set on all swarmed servers. Should be an address the server can be reached at by other servers in the swarm.
- `Swarm:Address`: Must be set on all swarmed servers. Should be an address the server can be reached at by other servers in the swarm.
- `Swarm:Identifier` should be set uniquely on all swarmed servers. Used to identify the current server. This is also used to select which instances exist on the current machine and should not be changed post-setup.
- `Swarm:PublicAddress`: Should be set on all swarmed servers. Should be an address the server can be reached at by other servers in the swarm.
- `Swarm:UpdateRequiredNodeCount` should be set to the total number of servers in your swarm, minus the controller. Prevents updates from occurring unless the non-controller server count in the swarm is greater than or equal to this value.
- `Swarm:Identifier`: Must be set uniquely on all swarmed servers. Used to identify the current server. This is also used to select which instances exist on the current machine and should not be changed post-setup.
- `Swarm:UpdateRequiredNodeCount`: Should be set to the total number of servers in your swarm minus 1. Prevents updates from occurring unless the non-controller server count in the swarm is greater than or equal to this value.
- `Security:OAuth:<Provider Name>`: Sets the OAuth client ID and secret for a given `<Provider Name>`. The currently supported providers are `Keycloak`, `GitHub`, `Discord`, `InvisionCommunity` and `TGForums`. Setting these fields to `null` disables logins with the provider, but does not stop users from associating their accounts using the API. Sample Entry:
```yml
-1
View File
@@ -3,7 +3,6 @@
<PropertyGroup>
<TgsFrameworkVersion>net$(TgsNetMajorVersion).0</TgsFrameworkVersion>
<TgsNugetNetVersion>netstandard2.0</TgsNugetNetVersion>
<LangVersion>latest</LangVersion>
<DebugType>Full</DebugType>
</PropertyGroup>
+1
View File
@@ -29,6 +29,7 @@ COPY build/Common.props Common.props
COPY build/NugetCommon.props NugetCommon.props
COPY build/Version.props Version.props
COPY build/ControlPanelVersion.props ControlPanelVersion.props
COPY build/SrcCommon.props SrcCommon.props
WORKDIR /repo/src/Tgstation.Server.Host
+2 -2
View File
@@ -1,9 +1,9 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="Common.props" />
<Import Project="SrcCommon.props" />
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Cyberboss/Dominion</Authors>
<Authors>Jordan Dominion</Authors>
<Company>/tg/station 13</Company>
<PackageProjectUrl>https://tgstation.github.io/tgstation-server</PackageProjectUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
+30
View File
@@ -0,0 +1,30 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="Common.props" />
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'!='Debug'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
</Project>
+19
View File
@@ -0,0 +1,19 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="Common.props" />
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
</Project>
+1
View File
@@ -15,6 +15,7 @@
<TgsContainerScriptVersion>1.2.1</TgsContainerScriptVersion>
<TgsMigratorVersion>1.0.2</TgsMigratorVersion>
<TgsNetMajorVersion>6</TgsNetMajorVersion>
<TgsNugetNetFramework>netstandard2.0</TgsNugetNetFramework>
<!-- Update this frequently with dotnet runtime patches. MAJOR MUST MATCH ABOVE! -->
<!-- You also need to update the .Bundle project's ExePackagePayload hash and file size after changing it -->
<TgsRedistUrl>https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.19/dotnet-hosting-6.0.19-win.exe</TgsRedistUrl>
+3 -3
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="myrules" Description="My rule set" ToolsVersion="16.0">
<RuleSet Name="myrules" Description="My rule set" ToolsVersion="17.0">
<Rules AnalyzerId="AsyncUsageAnalyzers" RuleNamespace="AsyncUsageAnalyzers">
<Rule Id="UseConfigureAwait" Action="Warning" />
</Rules>
@@ -1026,8 +1026,8 @@
<Rule Id="SA1101" Action="None" />
<Rule Id="SA1118" Action="None" />
<Rule Id="SA1121" Action="None" />
<Rule Id="SA1127" Action="None" />
<Rule Id="SA1128" Action="None" />
<Rule Id="SA1127" Action="Warning" />
<Rule Id="SA1128" Action="Warning" />
<Rule Id="SA1201" Action="None" />
<Rule Id="SA1400" Action="None" />
<Rule Id="SA1412" Action="Warning" />
@@ -1,4 +1,4 @@
namespace Tgstation.Server.Host.Service.Wix.SafeShutdown
namespace Tgstation.Server.Host.Service.Wix.Extensions
{
using System;
using System.ServiceProcess;
@@ -28,21 +28,21 @@
session.Log("Begin DetachStopTgsServiceIfRunning");
ServiceController serviceController = null;
session.Log($"Searching for {Constants.CanonicalPackageName} service...");
foreach (var controller in ServiceController.GetServices())
if (controller.ServiceName == Constants.CanonicalPackageName)
{
serviceController = controller;
break;
}
else
controller.Dispose();
using (serviceController)
// As much as I'd like to use Tgstation.Server.Common.Constants.CanonicalPackageName here, attempting to reference it make Tgstation.Server.Migrator.Comms fail due to referencing the net2.0 version of that library. EVEN THOUGH IT'S A TRANSITIVE DEPENDENCY OF Tgstation.Server.Client!!!!!
// If that dead-ass tool has been removed, feel free to do this
const string CanonicalPackageName = "tgstation-server";
session.Log($"Searching for {CanonicalPackageName} service...");
try
{
foreach (var controller in ServiceController.GetServices())
if (controller.ServiceName == CanonicalPackageName)
serviceController = controller;
else
controller.Dispose();
if (serviceController == null || serviceController.Status != ServiceControllerStatus.Running)
{
session.Log($"{Constants.CanonicalPackageName} service not found. Continuing.");
session.Log($"{CanonicalPackageName} service not found. Continuing.");
return ActionResult.Success;
}
@@ -50,21 +50,25 @@
PipeCommands.CommandDetachingShutdown)
.Value;
session.Log($"{Constants.CanonicalPackageName} service found. Sending command \"{PipeCommands.CommandDetachingShutdown}\" ({commandId})...");
session.Log($"{CanonicalPackageName} service found. Sending command \"{PipeCommands.CommandDetachingShutdown}\" ({commandId})...");
serviceController.ExecuteCommand(commandId);
session.Log($"Command sent. Waiting for {Constants.CanonicalPackageName} service to stop...");
session.Log($"Command sent. Waiting for {CanonicalPackageName} service to stop...");
serviceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(1));
var stopped = serviceController.Status == ServiceControllerStatus.Stopped;
session.Log($"{Constants.CanonicalPackageName} stopped {(stopped ? String.Empty : "un")}successfully.");
session.Log($"{CanonicalPackageName} stopped {(stopped ? String.Empty : "un")}successfully.");
return stopped
? ActionResult.Success
: ActionResult.NotExecuted;
}
finally
{
serviceController?.Dispose();
}
}
catch (Exception ex)
{
@@ -3,7 +3,7 @@ This file contains the declaration of all the localizable strings.
-->
<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
<String Id="DowngradeError" Value="A newer version of [ProductName] is already installed." />
<String Id="DowngradeError" Value="A newer version of [ProductName] is already installed. Downgrades are only supported via the HTTP API." />
<String Id="MainServerFeatureDescription" Value="The primary application for running [ProductName]." />
<String Id="ServerServiceDescription" Value="[ProductName] running as a Windows service." />
<String Id="ConfigureRestartDescription" Value="Runs the tgstation-server setup wizard and restarts the service (Does not stop DreamDaemon processes)." />
+8
View File
@@ -1,4 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentPrivateElements": true,
@@ -33,6 +34,13 @@
"accessibility"
],
"usingDirectivesPlacement": "outsideNamespace"
},
"namingRules": {
"allowCommonHungarianPrefixes": false,
"includeInferredTupleElementNames": true
},
"readabilityRules": {
"allowBuiltInTypeAliases": true
}
}
}
+4 -2
View File
@@ -124,7 +124,8 @@ namespace Tgstation.Server.Api
/// <param name="userAgent">The value of <see cref="UserAgent"/>.</param>
/// <param name="token">The value of <see cref="Token"/>.</param>
/// <param name="oauthProvider">The value of <see cref="OAuthProvider"/>.</param>
public ApiHeaders(ProductHeaderValue userAgent, string token, OAuthProvider? oauthProvider = null) : this(userAgent, token, null, null)
public ApiHeaders(ProductHeaderValue userAgent, string token, OAuthProvider? oauthProvider = null)
: this(userAgent, token, null, null)
{
if (userAgent == null)
throw new ArgumentNullException(nameof(userAgent));
@@ -140,7 +141,8 @@ namespace Tgstation.Server.Api
/// <param name="userAgent">The value of <see cref="UserAgent"/>.</param>
/// <param name="username">The value of <see cref="Username"/>.</param>
/// <param name="password">The value of <see cref="Password"/>.</param>
public ApiHeaders(ProductHeaderValue userAgent, string username, string password) : this(userAgent, null, username, password)
public ApiHeaders(ProductHeaderValue userAgent, string username, string password)
: this(userAgent, null, username, password)
{
if (userAgent == null)
throw new ArgumentNullException(nameof(userAgent));
+6 -3
View File
@@ -17,7 +17,8 @@ namespace Tgstation.Server.Api
/// </summary>
/// <param name="missingOrMalformedHeaders">The value of <see cref="MissingOrMalformedHeaders"/>.</param>
/// <param name="message">The error message.</param>
public HeadersException(HeaderTypes missingOrMalformedHeaders, string message) : base(message)
public HeadersException(HeaderTypes missingOrMalformedHeaders, string message)
: base(message)
{
MissingOrMalformedHeaders = missingOrMalformedHeaders;
}
@@ -33,7 +34,8 @@ namespace Tgstation.Server.Api
/// Initializes a new instance of the <see cref="HeadersException"/> class.
/// </summary>
/// <param name="message">The error message.</param>
public HeadersException(string message) : base(message)
public HeadersException(string message)
: base(message)
{
}
@@ -42,7 +44,8 @@ namespace Tgstation.Server.Api
/// </summary>
/// <param name="message">The error message.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public HeadersException(string message, Exception innerException) : base(message, innerException)
public HeadersException(string message, Exception innerException)
: base(message, innerException)
{
}
}
+3 -1
View File
@@ -1,6 +1,8 @@
using System;
using System.ComponentModel;
using Tgstation.Server.Common;
namespace Tgstation.Server.Api.Models
{
/// <summary>
@@ -60,7 +62,7 @@ namespace Tgstation.Server.Api.Models
/// <summary>
/// Attempted to change to a major version less than 4.
/// </summary>
[Description("Cannot downgrade to tgstation-server major version <4!")]
[Description($"Cannot downgrade to {Constants.CanonicalPackageName} major version <4!")]
CannotChangeServerSuite,
/// <summary>
@@ -14,6 +14,11 @@ namespace Tgstation.Server.Api.Models.Internal
[Required]
public virtual Uri? Address { get; set; }
/// <summary>
/// The address the swarm server can be publically accessed.
/// </summary>
public virtual Uri? PublicAddress { get; set; }
/// <summary>
/// The server's identifier.
/// </summary>
+2 -1
View File
@@ -24,7 +24,8 @@
/// </summary>
/// <typeparam name="TResultType">The child of <see cref="UserName"/> to create.</typeparam>
/// <returns>A new <typeparamref name="TResultType"/> copied from <see langword="this"/>.</returns>
protected virtual TResultType CreateUserName<TResultType>() where TResultType : UserName, new() => new TResultType
protected virtual TResultType CreateUserName<TResultType>()
where TResultType : UserName, new() => new TResultType
{
Id = Id,
Name = Name,
@@ -38,7 +38,8 @@ namespace Tgstation.Server.Api.Rights
/// <typeparam name="TRight">The <see cref="RightsType"/>.</typeparam>
/// <param name="right">The <typeparamref name="TRight"/>.</param>
/// <returns>A <see cref="string"/> representing the claim role name.</returns>
public static string RoleNames<TRight>(TRight right) where TRight : Enum
public static string RoleNames<TRight>(TRight right)
where TRight : Enum
{
IEnumerable<string> GetRoleNames()
{
@@ -75,7 +76,8 @@ namespace Tgstation.Server.Api.Rights
/// </summary>
/// <typeparam name="TRight">The <see cref="RightsType"/>.</typeparam>
/// <returns>All rights for the given <typeparamref name="TRight"/>.</returns>
public static TRight AllRights<TRight>() where TRight : Enum
public static TRight AllRights<TRight>()
where TRight : Enum
{
ulong rights = 0;
foreach (Enum right in Enum.GetValues(typeof(TRight)))
@@ -91,7 +93,8 @@ namespace Tgstation.Server.Api.Rights
/// <typeparam name="TRight">The <see cref="RightsType"/>.</typeparam>
/// <param name="rights">The <typeparamref name="TRight"/>s to clamp.</param>
/// <returns>The clamped <paramref name="rights"/>.</returns>
public static TRight Clamp<TRight>(TRight rights) where TRight : Enum
public static TRight Clamp<TRight>(TRight rights)
where TRight : Enum
{
var allRights = AllRights<TRight>();
@@ -2,22 +2,14 @@
<Import Project="../../build/NugetCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsNugetNetVersion)</TargetFramework>
<TargetFramework>$(TgsNugetNetFramework)</TargetFramework>
<Version>$(TgsApiLibraryVersion)</Version>
<Description>API definitions for tgstation-server.</Description>
<PackageTags>json web api tgstation-server tgstation ss13 byond http</PackageTags>
<PackageReleaseNotes>Added support for -map-threads DreamDaemon parameter and UploadZip Administration update option.</PackageReleaseNotes>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
<NoWarn>CA1028</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<Target Name="ApplyApiVersionAttribute" BeforeTargets="CoreCompile">
<ItemGroup>
<AssemblyAttributes Include="Tgstation.Server.Api.Properties.ApiVersionAttribute">
@@ -36,11 +28,6 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<!-- Usage: Primary JSON library -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- Usage: Data model annotating -->
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
+39 -16
View File
@@ -168,55 +168,78 @@ namespace Tgstation.Server.Client
}
/// <inheritdoc />
public Task<TResult> Create<TResult>(string route, CancellationToken cancellationToken) => RunRequest<object, TResult>(route, new object(), HttpMethod.Put, null, false, cancellationToken);
public Task<TResult> Create<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Put, null, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Read<TResult>(string route, CancellationToken cancellationToken) => RunRequest<object, TResult>(route, null, HttpMethod.Get, null, false, cancellationToken);
public Task<TResult> Read<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, null, HttpMethod.Get, null, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Update<TResult>(string route, CancellationToken cancellationToken) => RunRequest<object, TResult>(route, new object(), HttpMethod.Post, null, false, cancellationToken);
public Task<TResult> Update<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Post, null, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, TResult>(route, body, HttpMethod.Post, null, false, cancellationToken);
public Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Post, null, false, cancellationToken);
/// <inheritdoc />
public Task Patch(string route, CancellationToken cancellationToken) => RunRequest<object>(route, null, HttpPatch, null, false, cancellationToken);
/// <inheritdoc />
public Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, object>(route, body, HttpMethod.Post, null, false, cancellationToken);
public Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, object>(route, body, HttpMethod.Post, null, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, TResult>(route, body, HttpMethod.Put, null, false, cancellationToken);
public Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Put, null, false, cancellationToken);
/// <inheritdoc />
public Task Delete(string route, CancellationToken cancellationToken) => RunRequest<object>(route, null, HttpMethod.Delete, null, false, cancellationToken);
public Task Delete(string route, CancellationToken cancellationToken)
=> RunRequest<object>(route, null, HttpMethod.Delete, null, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Create<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, TResult>(route, body, HttpMethod.Put, instanceId, false, cancellationToken);
public Task<TResult> Create<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Put, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Read<TResult>(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<TResult>(route, null, HttpMethod.Get, instanceId, false, cancellationToken);
public Task<TResult> Read<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<TResult>(route, null, HttpMethod.Get, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Update<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, TResult>(route, body, HttpMethod.Post, instanceId, false, cancellationToken);
public Task<TResult> Update<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Post, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task Delete(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<object>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);
public Task Delete(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, object>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);
public Task Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, object>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Delete<TResult>(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<TResult>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);
public Task<TResult> Delete<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<TResult>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest<TBody, TResult>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);
public Task<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Create<TResult>(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<object, TResult>(route, new object(), HttpMethod.Put, instanceId, false, cancellationToken);
public Task<TResult> Create<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Put, instanceId, false, cancellationToken);
/// <inheritdoc />
public Task<TResult> Patch<TResult>(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<object, TResult>(route, new object(), HttpPatch, instanceId, false, cancellationToken);
public Task<TResult> Patch<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpPatch, instanceId, false, cancellationToken);
/// <inheritdoc />
public void AddRequestLogger(IRequestLogger requestLogger) => requestLoggers.Add(requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)));
@@ -15,7 +15,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public ApiConflictException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public ApiConflictException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ApiConflictException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public ApiConflictException(string message) : base(message)
public ApiConflictException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public ApiConflictException(string message, Exception innerException) : base(message, innerException)
public ApiConflictException(string message, Exception innerException)
: base(message, innerException)
{
}
}
+10 -8
View File
@@ -31,9 +31,10 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> returned from the API.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/>.</param>
protected ApiException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(
responseMessage,
errorMessage?.Message ?? $"HTTP {responseMessage?.StatusCode ?? throw new ArgumentNullException(nameof(responseMessage))}. Unknown API error, ErrorMessage payload not present!")
protected ApiException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(
responseMessage,
errorMessage?.Message ?? $"HTTP {responseMessage?.StatusCode ?? throw new ArgumentNullException(nameof(responseMessage))}. Unknown API error, ErrorMessage payload not present!")
{
ServerApiVersion = errorMessage?.ServerApiVersion;
AdditionalServerData = errorMessage?.AdditionalData;
@@ -45,9 +46,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/>.</param>
/// <param name="message">The <see cref="Exception.Message"/>.</param>
protected ApiException(HttpResponseMessage responseMessage, string message) : base(
responseMessage,
message)
protected ApiException(HttpResponseMessage responseMessage, string message)
: base(responseMessage, message)
{
}
@@ -62,7 +62,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
protected ApiException(string message) : base(message)
protected ApiException(string message)
: base(message)
{
}
@@ -71,7 +72,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
protected ApiException(string message, Exception innerException) : base(message, innerException)
protected ApiException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -19,7 +19,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> that generated the <see cref="ClientException"/>.</param>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
protected ClientException(HttpResponseMessage responseMessage, string message) : base(message)
protected ClientException(HttpResponseMessage responseMessage, string message)
: base(message)
{
ResponseMessage = responseMessage ?? throw new ArgumentNullException(nameof(responseMessage));
}
@@ -35,7 +36,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ClientException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
protected ClientException(string message) : base(message)
protected ClientException(string message)
: base(message)
{
}
@@ -44,7 +46,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
protected ClientException(string message, Exception innerException) : base(message, innerException)
protected ClientException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -15,7 +15,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public ConflictException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public ConflictException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ConflictException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public ConflictException(string message) : base(message)
public ConflictException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public ConflictException(string message, Exception innerException) : base(message, innerException)
public ConflictException(string message, Exception innerException)
: base(message, innerException)
{
}
}
+10 -5
View File
@@ -44,7 +44,8 @@ namespace Tgstation.Server.Client
/// <param name="body">The request body.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the response body as a <typeparamref name="TResult"/>.</returns>
Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken) where TBody : class;
Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class;
/// <summary>
/// Run an HTTP PUT request.
@@ -73,7 +74,8 @@ namespace Tgstation.Server.Client
/// <param name="body">The request body.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the response body as a <typeparamref name="TResult"/>.</returns>
Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken) where TBody : class;
Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class;
/// <summary>
/// Run an HTTP POST request.
@@ -92,7 +94,8 @@ namespace Tgstation.Server.Client
/// <param name="body">The request body.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken) where TBody : class;
Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class;
/// <summary>
/// Run an HTTP PATCH request.
@@ -192,7 +195,8 @@ namespace Tgstation.Server.Client
/// <param name="instanceId">The instance <see cref="EntityId.Id"/> to make the request to.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class;
Task Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class;
/// <summary>
/// Run an HTTP DELETE request.
@@ -214,7 +218,8 @@ namespace Tgstation.Server.Client
/// <param name="instanceId">The instance <see cref="EntityId.Id"/> to make the request to.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class;
Task<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class;
/// <summary>
/// Downloads a file <see cref="Stream"/> for a given <paramref name="ticket"/>.
@@ -12,9 +12,10 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="InsufficientPermissionsException"/> class.
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public InsufficientPermissionsException(HttpResponseMessage responseMessage) : base(
responseMessage,
"The current user has insufficient permissions to perform the requested operation!")
public InsufficientPermissionsException(HttpResponseMessage responseMessage)
: base(
responseMessage,
"The current user has insufficient permissions to perform the requested operation!")
{
}
@@ -29,7 +30,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="InsufficientPermissionsException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public InsufficientPermissionsException(string message) : base(message)
public InsufficientPermissionsException(string message)
: base(message)
{
}
@@ -38,7 +40,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public InsufficientPermissionsException(string message, Exception innerException) : base(message, innerException)
public InsufficientPermissionsException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -15,7 +15,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public MethodNotSupportedException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public MethodNotSupportedException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="MethodNotSupportedException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public MethodNotSupportedException(string message) : base(message)
public MethodNotSupportedException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public MethodNotSupportedException(string message, Exception innerException) : base(message, innerException)
public MethodNotSupportedException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -23,7 +23,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public RateLimitException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public RateLimitException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
if (responseMessage == null)
throw new ArgumentNullException(nameof(responseMessage));
@@ -47,7 +48,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="RateLimitException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public RateLimitException(string message) : base(message)
public RateLimitException(string message)
: base(message)
{
}
@@ -56,7 +58,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public RateLimitException(string message, Exception innerException) : base(message, innerException)
public RateLimitException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -12,7 +12,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="RequestTimeoutException"/> class.
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public RequestTimeoutException(HttpResponseMessage responseMessage) : base(responseMessage, "The request timed out!")
public RequestTimeoutException(HttpResponseMessage responseMessage)
: base(responseMessage, "The request timed out!")
{
}
@@ -27,7 +28,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="RequestTimeoutException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public RequestTimeoutException(string message) : base(message)
public RequestTimeoutException(string message)
: base(message)
{
}
@@ -36,7 +38,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public RequestTimeoutException(string message, Exception innerException) : base(message, innerException)
public RequestTimeoutException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -22,7 +22,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public ServerErrorException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public ServerErrorException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ServerErrorException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public ServerErrorException(string message) : base(message)
public ServerErrorException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public ServerErrorException(string message, Exception innerException) : base(message, innerException)
public ServerErrorException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -12,7 +12,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ServiceUnavailableException"/> class.
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/>.</param>
public ServiceUnavailableException(HttpResponseMessage responseMessage) : base(responseMessage, "The service is unavailable!")
public ServiceUnavailableException(HttpResponseMessage responseMessage)
: base(responseMessage, "The service is unavailable!")
{
}
@@ -27,7 +28,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="ServiceUnavailableException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public ServiceUnavailableException(string message) : base(message)
public ServiceUnavailableException(string message)
: base(message)
{
}
@@ -36,7 +38,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public ServiceUnavailableException(string message, Exception innerException) : base(message, innerException)
public ServiceUnavailableException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -2,34 +2,15 @@
<Import Project="../../build/NugetCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsNugetNetVersion)</TargetFramework>
<TargetFramework>$(TgsNugetNetFramework)</TargetFramework>
<Version>$(TgsClientVersion)</Version>
<Description>Client library for tgstation-server.</Description>
<PackageTags>json web api tgstation-server tgstation ss13 byond client http</PackageTags>
<PackageReleaseNotes>Added support for .zip uploads for server updates. Added missing Dispose() call to the StringContents for requests with bodies and added missing ConfigureAwait(false) to async call.</PackageReleaseNotes>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Api\Tgstation.Server.Api.csproj" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
</Project>
@@ -15,7 +15,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> returned by the API.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/>.</param>
public UnauthorizedException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public UnauthorizedException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="UnauthorizedException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public UnauthorizedException(string message) : base(message)
public UnauthorizedException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public UnauthorizedException(string message, Exception innerException) : base(message, innerException)
public UnauthorizedException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -12,7 +12,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="UnrecognizedResponseException"/> class.
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/>.</param>
public UnrecognizedResponseException(HttpResponseMessage responseMessage) : base(responseMessage, "Unrecognized response body!")
public UnrecognizedResponseException(HttpResponseMessage responseMessage)
: base(responseMessage, "Unrecognized response body!")
{
}
@@ -27,7 +28,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="UnrecognizedResponseException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public UnrecognizedResponseException(string message) : base(message)
public UnrecognizedResponseException(string message)
: base(message)
{
}
@@ -36,7 +38,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public UnrecognizedResponseException(string message, Exception innerException) : base(message, innerException)
public UnrecognizedResponseException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -15,7 +15,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="errorMessage">The <see cref="ErrorMessageResponse"/> for the <see cref="ApiException"/>.</param>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> for the <see cref="ClientException"/>.</param>
public VersionMismatchException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage) : base(errorMessage, responseMessage)
public VersionMismatchException(ErrorMessageResponse? errorMessage, HttpResponseMessage responseMessage)
: base(errorMessage, responseMessage)
{
}
@@ -30,7 +31,8 @@ namespace Tgstation.Server.Client
/// Initializes a new instance of the <see cref="VersionMismatchException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public VersionMismatchException(string message) : base(message)
public VersionMismatchException(string message)
: base(message)
{
}
@@ -39,7 +41,8 @@ namespace Tgstation.Server.Client
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the base <see cref="Exception"/>.</param>
public VersionMismatchException(string message, Exception innerException) : base(message, innerException)
public VersionMismatchException(string message, Exception innerException)
: base(message, innerException)
{
}
}
@@ -1,4 +1,4 @@
namespace Tgstation.Server.Host.Common
namespace Tgstation.Server.Common
{
/// <summary>
/// Constant values.
@@ -2,30 +2,11 @@
<Import Project="../../build/NugetCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsNugetNetVersion)</TargetFramework>
<TargetFrameworks>$(TgsNugetNetFramework)</TargetFrameworks>
<Version>$(TgsCommonLibraryVersion)</Version>
<Description>Common functions for tgstation-server.</Description>
<PackageTags>web tgstation-server tgstation ss13 byond client http</PackageTags>
<PackageReleaseNotes>Added CachedResponseStream.</PackageReleaseNotes>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
</Project>
@@ -1,30 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/SrcCommon.props" />
<PropertyGroup>
<TargetFrameworks>$(TgsFrameworkVersion);net2.0</TargetFrameworks>
<Version>$(TgsCoreVersion)</Version>
<IsPackable>false</IsPackable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
</Project>
+3 -1
View File
@@ -5,6 +5,8 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Tgstation.Server.Common;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Host.Watchdog;
@@ -35,7 +37,7 @@ namespace Tgstation.Server.Host.Console
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
internal static async Task<int> Main(string[] args)
{
System.Console.Title = $"tgstation-server Host Watchdog v{Assembly.GetExecutingAssembly().GetName().Version.Semver()}";
System.Console.Title = $"{Constants.CanonicalPackageName} Host Watchdog v{Assembly.GetExecutingAssembly().GetName().Version.Semver()}";
var arguments = new List<string>(args);
var trace = arguments.Remove("--trace-host-watchdog");
@@ -1,15 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/SrcCommon.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
<Version>$(TgsCoreVersion)</Version>
<UseAppHost>false</UseAppHost>
<IsPackable>false</IsPackable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
<ApplicationManifest>../../build/uac_elevation_manifest.xml</ApplicationManifest>
</PropertyGroup>
@@ -27,11 +23,6 @@
<ItemGroup>
<!-- Usage: Console logging plugin -->
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
@@ -48,7 +39,6 @@
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
<AdditionalFiles Include="../../build/uac_elevation_manifest.xml" />
</ItemGroup>
</Project>
+54 -26
View File
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Configuration.Install;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
@@ -87,27 +88,58 @@ namespace Tgstation.Server.Host.Service
/// Runs sc.exe to either uninstall a given <paramref name="serviceToUninstall"/> or install the running <see cref="ServerService"/>.
/// </summary>
/// <param name="serviceToUninstall">The name of a service to uninstall.</param>
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
static async ValueTask InvokeSC(string serviceToUninstall)
static void InvokeSC(string serviceToUninstall)
{
using var process = new Process();
process.StartInfo.FileName = "C:/Windows/System32/sc.exe";
using var installer = new ServiceInstaller();
if (serviceToUninstall != null)
{
installer.Context = new InstallContext($"old-{serviceToUninstall}-uninstall.log", null);
installer.ServiceName = serviceToUninstall;
installer.Uninstall(null);
}
else
{
var fullPathToAssembly = Path.GetFullPath(
Assembly.GetExecutingAssembly().Location);
var fullPathToAssembly = Path.GetFullPath(
Assembly.GetExecutingAssembly().Location);
var assemblyDirectory = Path.GetDirectoryName(fullPathToAssembly);
var assemblyNameWithoutExtension = Path.GetFileNameWithoutExtension(fullPathToAssembly);
var exePath = Path.Combine(assemblyDirectory, $"{assemblyNameWithoutExtension}.exe");
var assemblyDirectory = Path.GetDirectoryName(fullPathToAssembly);
var assemblyNameWithoutExtension = Path.GetFileNameWithoutExtension(fullPathToAssembly);
var exePath = Path.Combine(assemblyDirectory, $"{assemblyNameWithoutExtension}.exe");
var programDataDirectory = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
Server.Common.Constants.CanonicalPackageName);
process.StartInfo.Arguments = serviceToUninstall == null
? $"create tgstation-server binPath=\"{exePath}\" start=auto depend=Tcpip/Dhcp/Dnscache"
: $"delete {serviceToUninstall}";
process.StartInfo.CreateNoWindow = false;
using var processInstaller = new ServiceProcessInstaller();
processInstaller.Account = ServiceAccount.LocalSystem;
process.Start();
// Mimicing Tgstation.Server.Host.Service.Wix here, which is the source of truth for this data
installer.Context = new InstallContext(
Path.Combine(programDataDirectory, $"tgs-install-{Guid.NewGuid()}.log"),
new[]
{
$"assemblypath=\"{exePath}\" -p=--appsettings-base-path={programDataDirectory}",
});
installer.Description = $"{Server.Common.Constants.CanonicalPackageName} running as a Windows service.";
installer.DisplayName = Server.Common.Constants.CanonicalPackageName;
installer.StartType = ServiceStartMode.Automatic;
installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" };
installer.ServiceName = ServerService.Name;
installer.Parent = processInstaller;
await process.WaitForExitAsync();
var state = new ListDictionary();
try
{
installer.Install(state);
installer.Commit(state);
}
catch
{
installer.Rollback(state);
throw;
}
}
}
/// <summary>
@@ -156,17 +188,14 @@ namespace Tgstation.Server.Host.Service
}
if (match)
{
await InvokeSC(ServerService.Name);
break;
}
InvokeSC(ServerService.Name);
}
stopped = true;
}
if (Install)
stopped |= await RunServiceInstall();
stopped |= RunServiceInstall();
if (Restart)
foreach (ServiceController sc in ServiceController.GetServices())
@@ -177,15 +206,14 @@ namespace Tgstation.Server.Host.Service
RestartService(sc);
sc.Start();
break;
}
}
/// <summary>
/// Attempt to install the TGS Service.
/// </summary>
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if the service was stopped or detached as a result, <see langword="false"/> otherwise.</returns>
async ValueTask<bool> RunServiceInstall()
/// <returns><see langword="true"/> if the service was stopped or detached as a result, <see langword="false"/> otherwise.</returns>
bool RunServiceInstall()
{
// First check if the service already exists
bool serviceStopped = false;
@@ -210,11 +238,11 @@ namespace Tgstation.Server.Host.Service
RestartService(sc);
// And remove it
await InvokeSC(sc.ServiceName);
InvokeSC(sc.ServiceName);
}
}
await InvokeSC(null);
InvokeSC(null);
return serviceStopped;
}
@@ -12,6 +12,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventLog;
using Tgstation.Server.Common;
using Tgstation.Server.Host.Common;
using Tgstation.Server.Host.Watchdog;
@@ -1,43 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/SrcCommon.props" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>$(TgsFrameworkVersion)-windows</TargetFramework>
<Version>$(TgsCoreVersion)</Version>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<!-- DO NOT ENABLE THIS, It makes the service require the desktop runtime instead of the ASP NET Core Hosting Bundle -->
<UseWindowsForms>false</UseWindowsForms>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(RuntimeIdentifier)/$(AssemblyName).xml</DocumentationFile>
<ApplicationIcon>../../build/tgs.ico</ApplicationIcon>
<ApplicationManifest>../../build/uac_elevation_manifest.xml</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;SA1652</NoWarn>
</PropertyGroup>
<ItemGroup>
<!-- Usage: Installing service programatically -->
<PackageReference Include="Core.System.ServiceProcess" Version="2.0.1" />
<!-- Usage: Command line argument support -->
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.2" />
<!-- Usage: Identifies when we are running in the context of the Windows SCM -->
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<!-- Usage: Windows event log logging plugin -->
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="7.0.0" />
<!-- Usage: Console logging plugin -->
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- Usage: OS identification -->
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
<!-- Usage: Windows Service Manager intergration -->
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.1" />
</ItemGroup>
@@ -46,7 +33,6 @@
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
<AdditionalFiles Include="../../build/uac_elevation_manifest.xml" />
</ItemGroup>
@@ -1,24 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/SrcCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
<DebugType>Full</DebugType>
<AddSyntheticProjectReferencesForSolutionDependencies>false</AddSyntheticProjectReferencesForSolutionDependencies>
<Version>$(TgsHostWatchdogVersion)</Version>
<IsPackable>false</IsPackable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;SA1652</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -26,11 +12,6 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<!-- Usage: POSIX support for signals -->
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
@@ -39,10 +20,6 @@
</None>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Common\Tgstation.Server.Common.csproj" />
<ProjectReference Include="..\Tgstation.Server.Host.Common\Tgstation.Server.Host.Common.csproj" />
@@ -11,7 +11,6 @@ using Microsoft.Extensions.Logging;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Components.Events;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Utils;
@@ -14,7 +14,6 @@ using Tgstation.Server.Host.Components.Chat.Commands;
using Tgstation.Server.Host.Components.Chat.Providers;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components.Chat
@@ -7,7 +7,6 @@ using Microsoft.Extensions.Logging;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Utils;
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Common;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Configuration;
@@ -633,7 +634,7 @@ namespace Tgstation.Server.Host.Components
using (var systemIdentity = systemIdentityFactory.GetCurrent())
{
if (!systemIdentity.CanCreateSymlinks)
throw new InvalidOperationException("The user running tgstation-server cannot create symlinks! Please try running as an administrative user!");
throw new InvalidOperationException($"The user running {Constants.CanonicalPackageName} cannot create symlinks! Please try running as an administrative user!");
}
// This runs before the real socket is opened, ensures we don't perform reattaches unless we're fairly certain the bind won't fail
@@ -37,7 +37,8 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
/// </summary>
/// <param name="testMerge">The <see cref="Models.TestMerge"/> to build from.</param>
/// <param name="revision">The value of <see cref="Revision"/>.</param>
public TestMergeInformation(Models.TestMerge testMerge, RevisionInformation revision) : base(testMerge)
public TestMergeInformation(Models.TestMerge testMerge, RevisionInformation revision)
: base(testMerge)
{
TimeMerged = testMerge?.MergedAt.Ticks.ToString(CultureInfo.InvariantCulture) ?? throw new ArgumentNullException(nameof(testMerge));
Revision = revision ?? throw new ArgumentNullException(nameof(revision));
@@ -7,7 +7,6 @@ using Microsoft.Extensions.Logging;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Host.Extensions;
namespace Tgstation.Server.Host.Components.Repository
{
@@ -48,7 +48,8 @@ namespace Tgstation.Server.Host.Components.Session
Models.ReattachInformation copy,
IDmbProvider dmb,
IDmbProvider initialDmb,
TimeSpan topicRequestTimeout) : base(copy)
TimeSpan topicRequestTimeout)
: base(copy)
{
Dmb = dmb ?? throw new ArgumentNullException(nameof(dmb));
InitialDmb = initialDmb;
@@ -23,6 +23,14 @@ namespace Tgstation.Server.Host.Configuration
set => base.Address = value;
}
/// <inheritdoc />
[YamlMember(SerializeAs = typeof(string))]
public override Uri PublicAddress
{
get => base.PublicAddress;
set => base.PublicAddress = value;
}
/// <summary>
/// The <see cref="SwarmServer.Address"/> of the swarm controller. If <see langword="null"/>, the current server is considered the controller.
/// </summary>
@@ -1,4 +1,6 @@
namespace Tgstation.Server.Host.Configuration
using Tgstation.Server.Common;
namespace Tgstation.Server.Host.Configuration
{
/// <summary>
/// Configuration for the automatic update system.
@@ -18,7 +20,7 @@
/// <summary>
/// The default value of <see cref="GitTagPrefix"/>.
/// </summary>
const string DefaultGitTagPrefix = "tgstation-server-v";
const string DefaultGitTagPrefix = $"{Constants.CanonicalPackageName}-v";
/// <summary>
/// The default value of <see cref="UpdatePackageAssetName"/>.
@@ -284,7 +284,8 @@ namespace Tgstation.Server.Host.Core
services.AddHttpClient();
services.AddSingleton<IAbstractHttpClientFactory, AbstractHttpClientFactory>();
void AddTypedContext<TContext>() where TContext : DatabaseContext
void AddTypedContext<TContext>()
where TContext : DatabaseContext
{
var configureAction = DatabaseContext.GetConfigureAction<TContext>();
@@ -10,7 +10,6 @@ using Microsoft.Extensions.Options;
using Tgstation.Server.Host.Common;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Extensions;
namespace Tgstation.Server.Host.Core
{
@@ -10,7 +10,8 @@ using Microsoft.EntityFrameworkCore;
namespace Tgstation.Server.Host.Database
{
/// <inheritdoc />
sealed class DatabaseCollection<TModel> : IDatabaseCollection<TModel> where TModel : class
sealed class DatabaseCollection<TModel> : IDatabaseCollection<TModel>
where TModel : class
{
/// <summary>
/// The backing <see cref="DbSet{TEntity}"/>.
@@ -257,7 +257,8 @@ namespace Tgstation.Server.Host.Database
/// Initializes a new instance of the <see cref="DatabaseContext"/> class.
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions"/> for the <see cref="DatabaseContext"/>.</param>
protected DatabaseContext(DbContextOptions dbContextOptions) : base(dbContextOptions)
protected DatabaseContext(DbContextOptions dbContextOptions)
: base(dbContextOptions)
{
usersCollection = new DatabaseCollection<User>(Users);
instancesCollection = new DatabaseCollection<Instance>(Instances);
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore.Design;
using Tgstation.Server.Common;
using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database.Design
@@ -14,6 +15,6 @@ namespace Tgstation.Server.Host.Database.Design
=> new PostgresSqlDatabaseContext(
DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions<PostgresSqlDatabaseContext>(
DatabaseType.PostgresSql,
"Application Name=tgstation-server;Host=127.0.0.1;Password=fake;Username=postgres;Database=TGS_Design"));
$"Application Name={Constants.CanonicalPackageName};Host=127.0.0.1;Password=fake;Username=postgres;Database=TGS_Design"));
}
}
@@ -22,7 +22,8 @@ namespace Tgstation.Server.Host.Database
/// Initializes a new instance of the <see cref="MySqlDatabaseContext"/> class.
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/>.</param>
public MySqlDatabaseContext(DbContextOptions<MySqlDatabaseContext> dbContextOptions) : base(dbContextOptions)
public MySqlDatabaseContext(DbContextOptions<MySqlDatabaseContext> dbContextOptions)
: base(dbContextOptions)
{
}
@@ -16,7 +16,8 @@ namespace Tgstation.Server.Host.Database
/// Initializes a new instance of the <see cref="SqlServerDatabaseContext"/> class.
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/>.</param>
public SqlServerDatabaseContext(DbContextOptions<SqlServerDatabaseContext> dbContextOptions) : base(dbContextOptions)
public SqlServerDatabaseContext(DbContextOptions<SqlServerDatabaseContext> dbContextOptions)
: base(dbContextOptions)
{
}
@@ -56,7 +56,8 @@ namespace Tgstation.Server.Host.Extensions
/// Change the <see cref="Type"/> used as an implementation for calls to <see cref="AddChatProviderFactory(IServiceCollection)"/>.
/// </summary>
/// <typeparam name="TProviderFactory">The <see cref="IProviderFactory"/> implementation to use.</typeparam>
public static void UseChatProviderFactory<TProviderFactory>() where TProviderFactory : IProviderFactory
public static void UseChatProviderFactory<TProviderFactory>()
where TProviderFactory : IProviderFactory
{
chatProviderFactoryType = typeof(TProviderFactory);
}
@@ -65,7 +66,8 @@ namespace Tgstation.Server.Host.Extensions
/// Change the <see cref="Type"/> used as an implementation for calls to <see cref="AddGitHub(IServiceCollection)"/>.
/// </summary>
/// <typeparam name="TGitHubServiceFactory">The <see cref="IGitHubServiceFactory"/> implementation to use.</typeparam>
public static void UseGitHubServiceFactory<TGitHubServiceFactory>() where TGitHubServiceFactory : IGitHubServiceFactory
public static void UseGitHubServiceFactory<TGitHubServiceFactory>()
where TGitHubServiceFactory : IGitHubServiceFactory
{
gitHubServiceFactoryType = typeof(TGitHubServiceFactory);
}
@@ -74,7 +76,8 @@ namespace Tgstation.Server.Host.Extensions
/// Change the <see cref="Type"/> used as an implementation for calls to <see cref="AddGitHub(IServiceCollection)"/>.
/// </summary>
/// <typeparam name="TFileDownloader">The <see cref="IFileDownloader"/> implementation to use.</typeparam>
public static void UseFileDownloader<TFileDownloader>() where TFileDownloader : IFileDownloader
public static void UseFileDownloader<TFileDownloader>()
where TFileDownloader : IFileDownloader
{
fileDownloaderType = typeof(TFileDownloader);
}
@@ -112,7 +115,8 @@ namespace Tgstation.Server.Host.Extensions
/// Add an additional <see cref="ILoggerProvider"/> to <see cref="IServiceCollection"/>s that call <see cref="SetupLogging(IServiceCollection, Action{LoggerConfiguration}, Action{LoggerSinkConfiguration}, ElasticsearchSinkOptions, InternalConfiguration, FileLoggingConfiguration)"/>.
/// </summary>
/// <typeparam name="TLoggerProvider">The <see cref="Type"/> of <see cref="ILoggerProvider"/> to add.</typeparam>
public static void UseAdditionalLoggerProvider<TLoggerProvider>() where TLoggerProvider : class, ILoggerProvider
public static void UseAdditionalLoggerProvider<TLoggerProvider>()
where TLoggerProvider : class, ILoggerProvider
{
if (additionalLoggerProvider != null)
throw new InvalidOperationException("Cannot have multiple additionalLoggerProviders!");
@@ -138,7 +142,8 @@ namespace Tgstation.Server.Host.Extensions
/// <param name="serviceCollection">The <see cref="IServiceCollection"/> to configure.</param>
/// <param name="configuration">The <see cref="IConfiguration"/> containing the <typeparamref name="TConfig"/>.</param>
/// <returns><paramref name="serviceCollection"/>.</returns>
public static IServiceCollection UseStandardConfig<TConfig>(this IServiceCollection serviceCollection, IConfiguration configuration) where TConfig : class
public static IServiceCollection UseStandardConfig<TConfig>(this IServiceCollection serviceCollection, IConfiguration configuration)
where TConfig : class
{
ArgumentNullException.ThrowIfNull(serviceCollection);
ArgumentNullException.ThrowIfNull(configuration);
@@ -6,7 +6,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.IO
@@ -25,7 +25,8 @@ namespace Tgstation.Server.Host.Jobs
/// Initializes a new instance of the <see cref="JobException"/> class.
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
public JobException(string message) : base(message)
public JobException(string message)
: base(message)
{
}
@@ -34,7 +35,8 @@ namespace Tgstation.Server.Host.Jobs
/// </summary>
/// <param name="message">The message for the <see cref="Exception"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the nase <see cref="Exception"/>.</param>
public JobException(string message, Exception innerException) : base(message, innerException)
public JobException(string message, Exception innerException)
: base(message, innerException)
{
}
@@ -42,7 +44,8 @@ namespace Tgstation.Server.Host.Jobs
/// Initializes a new instance of the <see cref="JobException"/> class.
/// </summary>
/// <param name="errorCode">The associated <see cref="Api.Models.ErrorCode"/>.</param>
public JobException(ErrorCode errorCode) : base(errorCode.Describe())
public JobException(ErrorCode errorCode)
: base(errorCode.Describe())
{
ErrorCode = errorCode;
}
@@ -52,7 +55,8 @@ namespace Tgstation.Server.Host.Jobs
/// </summary>
/// <param name="errorCode">The associated <see cref="Api.Models.ErrorCode"/>.</param>
/// <param name="innerException">The inner <see cref="Exception"/> for the nase <see cref="Exception"/>.</param>
public JobException(ErrorCode errorCode, Exception innerException) : base(errorCode.Describe(), innerException)
public JobException(ErrorCode errorCode, Exception innerException)
: base(errorCode.Describe(), innerException)
{
ErrorCode = errorCode;
}
@@ -2,8 +2,6 @@
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Extensions;
namespace Tgstation.Server.Host.Jobs
{
/// <summary>
+1 -1
View File
@@ -55,7 +55,7 @@ namespace Tgstation.Server.Host.Models
public ICollection<Job> Jobs { get; set; }
/// <inheritdoc />
public InstanceResponse ToApi() => new InstanceResponse
public InstanceResponse ToApi() => new ()
{
AutoUpdateInterval = AutoUpdateInterval,
ConfigurationType = ConfigurationType,
@@ -69,7 +69,7 @@ namespace Tgstation.Server.Host.Security
var prop = typeToCheck.GetProperties().Where(x => x.PropertyType == nullableRightsType).First();
var right = prop.GetMethod.Invoke(isInstance ? (object)InstancePermissionSet : PermissionSet, Array.Empty<object>());
var right = prop.GetMethod.Invoke(isInstance ? InstancePermissionSet : PermissionSet, Array.Empty<object>());
if (right == null)
throw new InvalidOperationException("A user right was null!");
+11 -2
View File
@@ -21,6 +21,7 @@ using MySqlConnector;
using Npgsql;
using Tgstation.Server.Common;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Database;
using Tgstation.Server.Host.Extensions.Converters;
@@ -874,9 +875,15 @@ namespace Tgstation.Server.Host.Setup
async Task<Uri> ParseAddress(string question)
{
var first = true;
Uri address;
do
{
if (first)
first = false;
else
await console.WriteAsync("Invalid address!", true, cancellationToken);
await console.WriteAsync(question, false, cancellationToken);
var addressString = await console.ReadLineAsync(false, cancellationToken);
if (Uri.TryCreate(addressString, UriKind.Absolute, out address)
@@ -889,7 +896,8 @@ namespace Tgstation.Server.Host.Setup
return address;
}
var address = await ParseAddress("Enter this server's HTTP(S) address: ");
var address = await ParseAddress("Enter this server's INTERNAL http(s) address: ");
var publicAddress = await ParseAddress("Enter this server's PUBLIC https(s) address: ");
string privateKey;
do
{
@@ -906,6 +914,7 @@ namespace Tgstation.Server.Host.Setup
return new SwarmConfiguration
{
Address = address,
PublicAddress = publicAddress,
ControllerAddress = controllerAddress,
Identifier = identifer,
PrivateKey = privateKey,
@@ -1012,7 +1021,7 @@ namespace Tgstation.Server.Host.Setup
async Task RunWizard(string userConfigFileName, CancellationToken cancellationToken)
{
// welcome message
await console.WriteAsync("Welcome to tgstation-server!", true, cancellationToken);
await console.WriteAsync($"Welcome to {Constants.CanonicalPackageName}!", true, cancellationToken);
await console.WriteAsync("This wizard will help you configure your server.", true, cancellationToken);
var hostingPort = await PromptForHostingPort(cancellationToken);
@@ -199,6 +199,7 @@ namespace Tgstation.Server.Host.Swarm
new SwarmServerResponse
{
Address = swarmConfiguration.Address,
PublicAddress = swarmConfiguration.PublicAddress,
Controller = swarmController,
Identifier = swarmConfiguration.Identifier,
},
@@ -571,6 +572,7 @@ namespace Tgstation.Server.Host.Swarm
swarmServers.Add(new SwarmServerResponse
{
PublicAddress = node.PublicAddress,
Address = node.Address,
Identifier = node.Identifier,
Controller = false,
@@ -1239,6 +1241,7 @@ namespace Tgstation.Server.Host.Swarm
ServerVersion = assemblyInformationProvider.Version,
Identifier = swarmConfiguration.Identifier,
Address = swarmConfiguration.Address,
PublicAddress = swarmConfiguration.PublicAddress,
},
requestedRegistrationId);
@@ -2,8 +2,8 @@
using System.Net.Http.Headers;
using System.Reflection;
using Tgstation.Server.Common;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Host.Common;
namespace Tgstation.Server.Host.System
{
@@ -10,7 +10,6 @@ using Mono.Unix;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Extensions;
namespace Tgstation.Server.Host.System
{
@@ -1,26 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="../../build/Common.props" />
<Import Project="../../build/SrcCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
<Version>$(TgsCoreVersion)</Version>
<IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<UseAppHost>false</UseAppHost>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml</DocumentationFile>
<NoWarn>API1000</NoWarn>
<NodeModulesFolder>ClientApp/node_modules</NodeModulesFolder>
<NpmInstallStampFile>ClientApp/node_modules/.install-stamp</NpmInstallStampFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<ApplicationManifest>../../build/uac_elevation_manifest.xml</ApplicationManifest>
<Configurations>Debug;Release;Installer</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'!='Debug'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -99,7 +90,7 @@
<!-- Usage: PostgresSQL ORM plugin -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
<!-- Usage: GitHub.com interop -->
<PackageReference Include="Octokit" Version="6.1.0" />
<PackageReference Include="Octokit" Version="7.0.0" />
<!-- Usage: MYSQL/MariaDB ORM plugin -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
<!-- Usage: Discord interop -->
@@ -130,14 +121,6 @@
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="7.22.3" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'!='Installer'">
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Api\Tgstation.Server.Api.csproj" />
<ProjectReference Include="..\Tgstation.Server.Host.Common\Tgstation.Server.Host.Common.csproj" />
@@ -147,7 +130,6 @@
<Content Remove="ClientApp\**\*.json" />
<None Include="ClientApp\**\*.json" />
<ClientApp Include="ClientApp\src\**\*;ClientApp\public\**\*;ClientApp\tsconfig.json;ClientApp\package.json;ClientApp\package-lock.json" />
<AdditionalFiles Include="../../build/stylecop.json" />
<AdditionalFiles Include="../../build/uac_elevation_manifest.xml" />
</ItemGroup>
@@ -8,7 +8,6 @@ using Microsoft.Extensions.Logging;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Response;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.Utils;
@@ -7,7 +7,6 @@ using Microsoft.AspNetCore.WebUtilities;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Response;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
namespace Tgstation.Server.Host.Transfer
@@ -66,3 +66,10 @@ Security:
TGForums: # https://tgstation13.org OAuth configuration
Keycloak: # Keycloak OAuth configuration.
InvisionCommunity: # Invision Community OAuth configuration.
Swarm: # Should be left empty if using swarm mode is not desired
# Identifier: # Required: The string identifier of the swarm node
# PrivateKey: # Required: The shared API key used for inter-server communication in the swarm. Must be the same secure string on all nodes
# Address: # Required: The internal address of the swarm node's API
# PublicAddress: # The public address of the swarm node
# ControllerAddress: # Required on non-controller nodes. The internal address of the swarm controller's API'. Should be left empty on the controller itself
# UpdateRequiredNodeCount: # The number of nodes expected to be in the swarm before initiating an update. This should count every server irrespective of whether or not they are the controller MINUS 1
@@ -1,23 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
@@ -1,25 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Client\Tgstation.Server.Client.csproj" />
</ItemGroup>
@@ -1,25 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Host.Console\Tgstation.Server.Host.Console.csproj" />
</ItemGroup>
@@ -1,30 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)-windows</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Host.Service\Tgstation.Server.Host.Service.csproj" />
<ProjectReference Include="..\..\src\Tgstation.Server.Host.Watchdog\Tgstation.Server.Host.Watchdog.csproj" />
@@ -7,7 +7,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Utils;
@@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
</ItemGroup>
<ItemGroup>
@@ -240,7 +240,8 @@ namespace Tgstation.Server.Host.Setup.Tests
"node1",
"not a url",
"net.tcp://notandhttpAddress.com",
"http://node1:3400",
"http://node1internal:3400",
"http://node1public:3400",
"privatekey",
"n",
"http://controller.com",
@@ -274,7 +275,8 @@ namespace Tgstation.Server.Host.Setup.Tests
//swarm config
"y",
"controller",
"https://controller.com",
"https://controllerinternal.com",
"https://controllerpublic.com",
"privatekey",
"y"
};
@@ -1,25 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Host\Tgstation.Server.Host.csproj" />
</ItemGroup>
@@ -1,30 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Host.Watchdog\Tgstation.Server.Host.Watchdog.csproj" />
</ItemGroup>
@@ -168,6 +168,7 @@ namespace Tgstation.Server.Tests.Live
swarmArgs.Add($"Swarm:PrivateKey={swarmConfiguration.PrivateKey}");
swarmArgs.Add($"Swarm:Identifier={swarmConfiguration.Identifier}");
swarmArgs.Add($"Swarm:Address={swarmConfiguration.Address}");
swarmArgs.Add($"Swarm:PublicAddress={swarmConfiguration.PublicAddress}");
if (swarmConfiguration.ControllerAddress != null)
swarmArgs.Add($"Swarm:ControllerAddress={swarmConfiguration.ControllerAddress}");
@@ -735,6 +735,7 @@ namespace Tgstation.Server.Tests.Live
{
Address = controllerAddress,
Identifier = "controller",
PublicAddress = new Uri("http://fakecontroller.com"),
PrivateKey = PrivateKey,
UpdateRequiredNodeCount = 2,
}, false, 15011))
@@ -743,6 +744,7 @@ namespace Tgstation.Server.Tests.Live
{
Address = new Uri("http://localhost:15012"),
ControllerAddress = controllerAddress,
PublicAddress = new Uri("http://fakenode1.com"),
Identifier = "node1",
PrivateKey = PrivateKey
}, false, 15012);
@@ -792,16 +794,19 @@ namespace Tgstation.Server.Tests.Live
Assert.IsNotNull(node1);
Assert.AreEqual(node1.Address, new Uri("http://localhost:15012"));
Assert.IsFalse(node1.Controller);
Assert.AreEqual(node1.PublicAddress, new Uri("http://fakenode1.com"));
var node2 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node2");
Assert.IsNotNull(node2);
Assert.AreEqual(node2.Address, new Uri("http://localhost:15013"));
Assert.IsFalse(node2.Controller);
Assert.IsNull(node2.PublicAddress);
var controller = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "controller");
Assert.IsNotNull(controller);
Assert.AreEqual(controller.Address, new Uri("http://localhost:15011"));
Assert.IsTrue(controller.Controller);
Assert.AreEqual(controller.PublicAddress, new Uri("http://fakecontroller.com"));
}
CheckInfo(controllerInfo);
@@ -1,25 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Common.props" />
<Import Project="../../build/TestCommon.props" />
<PropertyGroup>
<TargetFramework>$(TgsFrameworkVersion)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.Client\Tgstation.Server.Client.csproj" />
<ProjectReference Include="..\..\src\Tgstation.Server.Host.Watchdog\Tgstation.Server.Host.Watchdog.csproj" />
+17 -15
View File
@@ -32,7 +32,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6FF654E6
build\GenerateMigrations.sh = build\GenerateMigrations.sh
build\NugetCommon.props = build\NugetCommon.props
build\OpenApiValidationSettings.json = build\OpenApiValidationSettings.json
build\SrcCommon.props = build\SrcCommon.props
build\stylecop.json = build\stylecop.json
build\TestCommon.props = build\TestCommon.props
build\tgs.docker.sh = build\tgs.docker.sh
build\tgs.ico = build\tgs.ico
build\tgs.png = build\tgs.png
@@ -130,8 +132,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{E821
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Tests", "tests\Tgstation.Server.Tests\Tgstation.Server.Tests.csproj", "{09056964-1C74-445A-96EC-33F6DFC07916}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReleaseNotes", "tools\ReleaseNotes\ReleaseNotes.csproj", "{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".vscode", ".vscode", "{14B3FF87-5600-4981-B40C-9CC838964645}"
ProjectSection(SolutionItems) = preProject
.vscode\extensions.json = .vscode\extensions.json
@@ -252,6 +252,8 @@ Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "Tgstation.Server.Host.Servi
EndProject
Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "Tgstation.Server.Host.Service.Wix.Bundle", "build\package\winget\Tgstation.Server.Host.Service.Wix.Bundle\Tgstation.Server.Host.Service.Wix.Bundle.wixproj", "{9E66C6F1-E235-4979-83B5-C2B3FDAD6E01}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.ReleaseNotes", "tools\Tgstation.Server.ReleaseNotes\Tgstation.Server.ReleaseNotes.csproj", "{69944039-65C2-40E1-9D86-0608FA0C2D70}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -414,18 +416,6 @@ Global
{09056964-1C74-445A-96EC-33F6DFC07916}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU
{09056964-1C74-445A-96EC-33F6DFC07916}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU
{09056964-1C74-445A-96EC-33F6DFC07916}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.DebugNoWindows|Any CPU.Build.0 = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.DebugNoWix|Any CPU.ActiveCfg = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.DebugNoWix|Any CPU.Build.0 = Debug|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.Release|Any CPU.Build.0 = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.ReleaseNoWindows|Any CPU.ActiveCfg = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU
{5813CC33-B16C-485D-A74D-20204DDF6542}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5813CC33-B16C-485D-A74D-20204DDF6542}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5813CC33-B16C-485D-A74D-20204DDF6542}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU
@@ -510,6 +500,18 @@ Global
{9E66C6F1-E235-4979-83B5-C2B3FDAD6E01}.Release|Any CPU.Build.0 = Release|x86
{9E66C6F1-E235-4979-83B5-C2B3FDAD6E01}.ReleaseNoWindows|Any CPU.ActiveCfg = Release|x86
{9E66C6F1-E235-4979-83B5-C2B3FDAD6E01}.ReleaseNoWix|Any CPU.ActiveCfg = Release|x86
{69944039-65C2-40E1-9D86-0608FA0C2D70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.DebugNoWindows|Any CPU.Build.0 = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.DebugNoWix|Any CPU.ActiveCfg = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.DebugNoWix|Any CPU.Build.0 = Debug|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.Release|Any CPU.Build.0 = Release|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.ReleaseNoWindows|Any CPU.ActiveCfg = Release|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU
{69944039-65C2-40E1-9D86-0608FA0C2D70}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -528,7 +530,6 @@ Global
{82066812-6C73-4360-943B-B23F2F491261} = {7E4E7CF6-A48D-410E-8191-C49C6B5AB9CC}
{057FAC33-CC31-4948-91C6-B0977C335890} = {F7765A4B-021C-454E-ABB1-2AB1B85F91B4}
{09056964-1C74-445A-96EC-33F6DFC07916} = {316141B0-CD21-4769-A013-D53DA9B9EC09}
{5CB51532-55F0-4255-B6E5-69ED5CCD14CD} = {A55C1117-5808-4AB2-BEA6-4D4A3E66A2F2}
{FAEAD3B5-2EAB-465C-A9C3-E8CB6AAA7131} = {F7765A4B-021C-454E-ABB1-2AB1B85F91B4}
{EB1DDE8C-CA6F-4BE3-947B-597CA8EABEA5} = {82066812-6C73-4360-943B-B23F2F491261}
{7B8FC2AF-1B64-4A89-8480-F0FE360DC9EC} = {82066812-6C73-4360-943B-B23F2F491261}
@@ -547,6 +548,7 @@ Global
{28669D98-E15D-4A62-B1D1-7C11D4CB1DE0} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
{82996E9D-5E63-4CC5-8179-612C71B4F56C} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
{9E66C6F1-E235-4979-83B5-C2B3FDAD6E01} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
{69944039-65C2-40E1-9D86-0608FA0C2D70} = {A55C1117-5808-4AB2-BEA6-4D4A3E66A2F2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DFD36C95-3E49-41C7-ACDB-86BAF5B18A79}
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
@@ -53,7 +52,7 @@ static class Program
{
#if DEBUG
Console.WriteLine("Test log line...");
Debugger.Launch();
System.Diagnostics.Debugger.Launch();
#endif
Console.WriteLine("Connecting to TGS3...");
var status = tgs3Client.ConnectionStatus(out var tgs3Error);
+8 -8
View File
@@ -21,6 +21,7 @@ using Octokit;
using Tgstation.Server.Api;
using Tgstation.Server.Client;
using Tgstation.Server.Common;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Common.Http;
using Tgstation.Server.Host.Common;
@@ -134,13 +135,12 @@ try
if (service == tgs3Service)
continue;
if (checkNewOneIsntInstalled && (service.ServiceName == NewServiceName || service.ServiceName == "tgstation-server-4"))
{
Console.WriteLine("Detected existing TGS4+ install! Cannot continue. Please uninstall any versions of TGS4+ before continuing.");
ExitPause(10);
}
service.Dispose();
using (service)
if (checkNewOneIsntInstalled && (service.ServiceName == NewServiceName || service.ServiceName == "tgstation-server-4"))
{
Console.WriteLine("Detected existing TGS4+ install! Cannot continue. Please uninstall any versions of TGS4+ before continuing.");
ExitPause(10);
}
}
if (checkNewOneIsntInstalled)
@@ -438,7 +438,7 @@ try
$"assemblypath={Path.Combine(tgsInstallPath, "Tgstation.Server.Host.Service.exe")}"
});
installer.Description = "/tg/station 13 server running as a windows service";
installer.DisplayName = "/tg/station server";
installer.DisplayName = "tgstation-server";
installer.StartType = ServiceStartMode.Automatic;
installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" };
installer.ServiceName = NewServiceName;
@@ -9,7 +9,7 @@ using System.Xml.Linq;
using Octokit;
using Octokit.GraphQL;
namespace ReleaseNotes
namespace Tgstation.Server.ReleaseNotes
{
/// <summary>
/// Contains the application entrypoint
@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="octokit" Version="6.0.0" />
<PackageReference Include="octokit" Version="7.0.0" />
<PackageReference Include="Octokit.GraphQL" Version="0.2.0-beta" />
</ItemGroup>