mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-24 05:27:30 +01:00
@@ -3,7 +3,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: Code coverage collection -->
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
@@ -18,9 +18,9 @@
|
||||
<!-- Pinned: Be VERY careful about updating https://github.com/moq/moq/issues/1372 -->
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<!-- Usage: MSTest execution -->
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.6.4" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.7.3" />
|
||||
<!-- Usage: MSTest asserts etc... -->
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.6.4" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.7.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+3
-3
@@ -5,12 +5,12 @@
|
||||
<PropertyGroup>
|
||||
<TgsCoreVersion>6.12.3</TgsCoreVersion>
|
||||
<TgsConfigVersion>5.4.0</TgsConfigVersion>
|
||||
<TgsRestVersion>10.12.0</TgsRestVersion>
|
||||
<TgsRestVersion>10.12.1</TgsRestVersion>
|
||||
<TgsGraphQLVersion>0.5.0</TgsGraphQLVersion>
|
||||
<TgsCommonLibraryVersion>7.0.0</TgsCommonLibraryVersion>
|
||||
<TgsApiLibraryVersion>17.0.0</TgsApiLibraryVersion>
|
||||
<TgsApiLibraryVersion>17.0.1</TgsApiLibraryVersion>
|
||||
<TgsClientVersion>20.0.0</TgsClientVersion>
|
||||
<TgsDmapiVersion>7.3.0</TgsDmapiVersion>
|
||||
<TgsDmapiVersion>7.3.1</TgsDmapiVersion>
|
||||
<TgsInteropVersion>5.10.0</TgsInteropVersion>
|
||||
<TgsHostWatchdogVersion>1.6.0</TgsHostWatchdogVersion>
|
||||
<TgsSwarmProtocolVersion>8.0.0</TgsSwarmProtocolVersion>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
inputs@{
|
||||
config,
|
||||
lib,
|
||||
systemdUtils,
|
||||
nixpkgs,
|
||||
pkgs,
|
||||
writeShellScriptBin,
|
||||
@@ -53,7 +54,7 @@ in
|
||||
};
|
||||
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "tgstation-server";
|
||||
description = ''
|
||||
The name of the user used to execute tgstation-server.
|
||||
@@ -61,7 +62,7 @@ in
|
||||
};
|
||||
|
||||
groupname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "tgstation-server";
|
||||
description = ''
|
||||
The name of group the user used to execute tgstation-server will belong to.
|
||||
@@ -69,7 +70,7 @@ in
|
||||
};
|
||||
|
||||
home-directory = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "/home/tgstation-server";
|
||||
description = ''
|
||||
The home directory of TGS. Should be persistent.
|
||||
@@ -99,6 +100,14 @@ in
|
||||
Environment file as defined in {manpage}`systemd.exec(5)`
|
||||
'';
|
||||
};
|
||||
|
||||
wants = lib.mkOption {
|
||||
type = lib.types.listOf systemdUtils.lib.unitNameType;
|
||||
default = [];
|
||||
description = ''
|
||||
Start the specified units when this unit is started.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -5,7 +5,8 @@
|
||||
"documentPrivateElements": true,
|
||||
"documentPrivateFields": true,
|
||||
"excludeFromPunctuationCheck": [
|
||||
"remarks"
|
||||
"remarks",
|
||||
"example"
|
||||
]
|
||||
},
|
||||
"indentation": {
|
||||
|
||||
+28
-1
@@ -1,7 +1,7 @@
|
||||
// tgstation-server DMAPI
|
||||
// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119.
|
||||
|
||||
#define TGS_DMAPI_VERSION "7.3.0"
|
||||
#define TGS_DMAPI_VERSION "7.3.1"
|
||||
|
||||
// All functions and datums outside this document are subject to change with any version and should not be relied on.
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
#define TGS_FILE2TEXT_NATIVE file2text
|
||||
#endif
|
||||
|
||||
// SpacemanDMM compatibility
|
||||
#ifndef CAN_BE_REDEFINED
|
||||
#define CAN_BE_REDEFINED(X)
|
||||
#endif
|
||||
|
||||
// EVENT CODES
|
||||
|
||||
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums.
|
||||
@@ -160,6 +165,7 @@
|
||||
* * http_handler - Optional user defined [/datum/tgs_http_handler].
|
||||
*/
|
||||
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -170,6 +176,7 @@
|
||||
* This function should not be called before ..() in [/world/proc/New].
|
||||
*/
|
||||
/world/proc/TgsInitializationComplete()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Consumers MUST run this macro at the start of [/world/proc/Topic].
|
||||
@@ -177,6 +184,7 @@
|
||||
|
||||
/// Consumers MUST call this as late as possible in [world/proc/Reboot] (BEFORE ..()).
|
||||
/world/proc/TgsReboot()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
// DATUM DEFINITIONS
|
||||
@@ -214,6 +222,7 @@
|
||||
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
|
||||
*/
|
||||
/datum/tgs_version/proc/Wildcard()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -222,6 +231,7 @@
|
||||
* other_version - The [/datum/tgs_version] to compare against.
|
||||
*/
|
||||
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Represents a merge of a GitHub pull request.
|
||||
@@ -459,16 +469,19 @@
|
||||
|
||||
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
|
||||
/world/proc/TgsMaximumApiVersion()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
|
||||
/world/proc/TgsMinimumApiVersion()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
|
||||
*/
|
||||
/world/proc/TgsAvailable()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
|
||||
@@ -480,6 +493,7 @@
|
||||
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again.
|
||||
*/
|
||||
/world/proc/TgsEndProcess()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -490,6 +504,7 @@
|
||||
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
|
||||
*/
|
||||
/world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -500,6 +515,7 @@
|
||||
* user: The [/datum/tgs_chat_user] to PM.
|
||||
*/
|
||||
/world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -510,42 +526,52 @@
|
||||
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
|
||||
*/
|
||||
/world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsVersion()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the running engine type
|
||||
/world/proc/TgsEngine()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsApiVersion()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsInstanceName()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsRevision()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsSecurityLevel()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsVisibility()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsTestMerges()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
|
||||
/world/proc/TgsChatChannelInfo()
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -556,6 +582,7 @@
|
||||
* wait_for_completion - If set, this function will not return until the event has run to completion.
|
||||
*/
|
||||
/world/proc/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
|
||||
CAN_BE_REDEFINED(TRUE)
|
||||
return
|
||||
|
||||
/*
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace Tgstation.Server.Api
|
||||
else
|
||||
{
|
||||
var auth = authorization.First();
|
||||
var splits = new List<string>(auth.Split(' '));
|
||||
var splits = new List<string>(auth?.Split(' ') ?? Enumerable.Empty<string>());
|
||||
var scheme = splits.First();
|
||||
if (String.IsNullOrWhiteSpace(scheme))
|
||||
AddError(HeaderErrorTypes.AuthorizationInvalid, "Missing authentication scheme!");
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Tgstation.Server.Api.Models
|
||||
/// For <see cref="ChatProvider.Irc"/>, it's the IRC channel name and optional password colon separated.
|
||||
/// For <see cref="ChatProvider.Discord"/>, it's the stringified Discord channel snowflake.
|
||||
/// </summary>
|
||||
/// <example>124823852418</example>
|
||||
[Required]
|
||||
[StringLength(Limits.MaximumIndexableStringLength, MinimumLength = 1)]
|
||||
public string? ChannelData { get; set; }
|
||||
|
||||
@@ -26,12 +26,14 @@ namespace Tgstation.Server.Api.Models
|
||||
/// <summary>
|
||||
/// The <see cref="System.Version"/> of the engine. Currently only valid when <see cref="Engine"/> is <see cref="EngineType.Byond"/>.
|
||||
/// </summary>
|
||||
/// <example>516.1651.0</example>
|
||||
[ResponseOptions]
|
||||
public Version? Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The git commit SHA of the engine. Currently only valid when <see cref="Engine"/> is <see cref="EngineType.OpenDream"/>.
|
||||
/// </summary>
|
||||
/// <example>caa1e1f400c8b6a535e03cff28cf57f919e9378c</example>
|
||||
[ResponseOptions]
|
||||
[StringLength(Limits.MaximumCommitShaLength, MinimumLength = Limits.MaximumCommitShaLength)]
|
||||
public string? SourceSHA { get; set; }
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/// <summary>
|
||||
/// The ID of the entity.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
[RequestOptions(FieldPresence.Required)]
|
||||
[RequestOptions(FieldPresence.Ignored, PutOnly = true)]
|
||||
public virtual long? Id { get; set; }
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The time interval in minutes the chat bot attempts to reconnect if <see cref="Enabled"/> and disconnected. Must not be zero.
|
||||
/// </summary>
|
||||
/// <example>60</example>
|
||||
[Required]
|
||||
[Range(1, UInt32.MaxValue)]
|
||||
public uint? ReconnectionInterval { get; set; }
|
||||
@@ -23,6 +24,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The maximum number of <see cref="ChatChannel"/>s the <see cref="ChatBotSettings"/> may contain.
|
||||
/// </summary>
|
||||
/// <example>5</example>
|
||||
[Required]
|
||||
public ushort? ChannelLimit { get; set; }
|
||||
|
||||
|
||||
@@ -10,18 +10,21 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// If the <see cref="ChatChannel"/> is an admin channel.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[Required]
|
||||
public bool? IsAdminChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="ChatChannel"/> is a watchdog channel.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[Required]
|
||||
public bool? IsWatchdogChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="ChatChannel"/> is an updates channel.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[Required]
|
||||
public bool? IsUpdatesChannel { get; set; }
|
||||
|
||||
@@ -34,6 +37,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// A custom tag users can define to group channels together.
|
||||
/// </summary>
|
||||
/// <example>system-channel-only</example>
|
||||
[ResponseOptions]
|
||||
[StringLength(Limits.MaximumStringLength)]
|
||||
public string? Tag { get; set; }
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The .dme file used for compilation.
|
||||
/// </summary>
|
||||
/// <example>tgstation.dme</example>
|
||||
[Required]
|
||||
public string? DmeName { get; set; }
|
||||
|
||||
@@ -36,6 +37,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The DMAPI <see cref="Version"/>.
|
||||
/// </summary>
|
||||
/// <example>7.3.0</example>
|
||||
[NotMapped]
|
||||
[ResponseOptions]
|
||||
public virtual Version? DMApiVersion { get; set; }
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// An incrementing ID for representing current server execution.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
[ResponseOptions]
|
||||
public long? SessionId { get; set; }
|
||||
|
||||
@@ -22,12 +23,14 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The last known count of connected players. Requires <see cref="DreamDaemonLaunchParameters.HealthCheckSeconds"/> to not be 0 and a game server interop version >= 5.10.0 to populate.
|
||||
/// </summary>
|
||||
/// <example>30</example>
|
||||
[ResponseOptions]
|
||||
public uint? ClientCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the server is undergoing a soft reset. This may be automatically set by changes to other fields.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[ResponseOptions]
|
||||
public bool? SoftRestart { get; set; }
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// If the BYOND web client can be used to connect to the game server. No-op for <see cref="EngineType.OpenDream"/>.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
public bool? AllowWebClient { get; set; }
|
||||
@@ -25,6 +26,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The <see cref="DreamDaemonVisibility"/> level of DreamDaemon. No-op for <see cref="EngineType.OpenDream"/>.
|
||||
/// </summary>
|
||||
/// <example>2</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
[EnumDataType(typeof(DreamDaemonVisibility))]
|
||||
@@ -33,6 +35,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The <see cref="DreamDaemonSecurity"/> level of DreamDaemon. No-op for <see cref="EngineType.OpenDream"/>.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
[EnumDataType(typeof(DreamDaemonSecurity))]
|
||||
@@ -41,6 +44,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The port DreamDaemon uses. This should be publically accessible.
|
||||
/// </summary>
|
||||
/// <example>1337</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
[Range(1, UInt16.MaxValue)]
|
||||
@@ -49,6 +53,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The port used by <see cref="EngineType.OpenDream"/> for its topic port.
|
||||
/// </summary>
|
||||
/// <example>2337</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
public ushort? OpenDreamTopicPort { get; set; }
|
||||
@@ -56,6 +61,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The DreamDaemon startup timeout in seconds.
|
||||
/// </summary>
|
||||
/// <example>5</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
[Range(1, UInt32.MaxValue)]
|
||||
@@ -64,6 +70,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The number of seconds between each watchdog health check. 0 disables.
|
||||
/// </summary>
|
||||
/// <example>5</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
public uint? HealthCheckSeconds { get; set; }
|
||||
@@ -78,6 +85,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The timeout for sending and receiving BYOND topics in milliseconds.
|
||||
/// </summary>
|
||||
/// <example>500</example>
|
||||
[Required]
|
||||
[ResponseOptions]
|
||||
[Range(1, UInt32.MaxValue)]
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// English description of the <see cref="Job"/>.
|
||||
/// </summary>
|
||||
/// <remarks>May not match the <see cref="System.ComponentModel.DescriptionAttribute"/> listed on the <see cref="Models.JobCode"/>.</remarks>
|
||||
/// <example>Installing and configuring important objects.</example>
|
||||
[Required]
|
||||
public string? Description { get; set; }
|
||||
|
||||
@@ -50,6 +51,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// If the <see cref="Job"/> was cancelled.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[Required]
|
||||
public bool? Cancelled { get; set; }
|
||||
|
||||
|
||||
@@ -10,26 +10,31 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// Minimum length of database user passwords.
|
||||
/// </summary>
|
||||
/// <example>20</example>
|
||||
public uint MinimumPasswordLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of <see cref="Instance"/>s allowed.
|
||||
/// </summary>
|
||||
/// <example>100</example>
|
||||
public uint InstanceLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of users allowed.
|
||||
/// </summary>
|
||||
/// <example>100</example>
|
||||
public uint UserLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of user groups allowed.
|
||||
/// </summary>
|
||||
/// <example>50</example>
|
||||
public uint UserGroupLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limits the locations instances may be created or attached from.
|
||||
/// </summary>
|
||||
/// <example>["/home/tgstation-server/my-server-1", "/home/tgstation-server/my-server-2"]</example>
|
||||
[ResponseOptions]
|
||||
public List<string>? ValidInstancePaths { get; set; }
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The server's identifier.
|
||||
/// </summary>
|
||||
/// <example>myserver-us-east</example>
|
||||
[Required]
|
||||
public string? Identifier { get; set; }
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// If the <see cref="SwarmServerResponse"/> is the controller.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
public bool Controller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The ID of the <see cref="TestMergeApiBase"/>.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -11,18 +11,21 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The title of the test merge source.
|
||||
/// </summary>
|
||||
/// <example>Fixes and Breaks everything</example>
|
||||
[Required]
|
||||
public string? TitleAtMerge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The body of the test merge source.
|
||||
/// </summary>
|
||||
/// <example># GitHub markdown\n\rI assume?</example>
|
||||
[Required]
|
||||
public string? BodyAtMerge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL of the test merge source.
|
||||
/// </summary>
|
||||
/// <example>https://github.com/tgstation/tgstation/pull/31026</example>
|
||||
[Required]
|
||||
#pragma warning disable CA1056 // Uri properties should not be strings
|
||||
public string? Url { get; set; }
|
||||
@@ -31,6 +34,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The author of the test merge source.
|
||||
/// </summary>
|
||||
/// <example>MrStonedOne</example>
|
||||
[Required]
|
||||
public string? Author { get; set; }
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The latest available version of the Tgstation.Server.Host assembly from the upstream repository. If <see cref="Version.Major"/> is less than 4 the update cannot be applied due to API changes.
|
||||
/// </summary>
|
||||
/// <example>1.0.0</example>
|
||||
public Version? LatestVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models
|
||||
/// <summary>
|
||||
/// The name of the entity represented by the <see cref="NamedEntity"/>.
|
||||
/// </summary>
|
||||
/// <example>MyThingyName</example>
|
||||
[Required]
|
||||
[RequestOptions(FieldPresence.Required, PutOnly = true)]
|
||||
[StringLength(Limits.MaximumIndexableStringLength, MinimumLength = 1)]
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Request
|
||||
/// <summary>
|
||||
/// Changes the version of tgstation-server to the given version from the upstream repository.
|
||||
/// </summary>
|
||||
/// <example>6.12.3</example>
|
||||
[RequestOptions(FieldPresence.Required)]
|
||||
public Version? NewVersion { get; set; }
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The GitHub repository the server is built to receive updates from.
|
||||
/// </summary>
|
||||
/// <example>https://github.com/tgstation/tgstation</example>
|
||||
public Uri? TrackedRepositoryUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The current <see cref="WatchdogStatus"/>.
|
||||
/// </summary>
|
||||
/// <example>2</example>
|
||||
[EnumDataType(typeof(WatchdogStatus))]
|
||||
[ResponseOptions]
|
||||
public WatchdogStatus? Status { get; set; }
|
||||
@@ -31,6 +32,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The current <see cref="DreamDaemonSecurity"/>. May be upgraded. due to requirements of <see cref="ActiveCompileJob"/>.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
[EnumDataType(typeof(DreamDaemonSecurity))]
|
||||
[ResponseOptions]
|
||||
public DreamDaemonSecurity? CurrentSecurity { get; set; }
|
||||
@@ -38,6 +40,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The current <see cref="DreamDaemonVisibility"/>.
|
||||
/// </summary>
|
||||
/// <example>2</example>
|
||||
[EnumDataType(typeof(DreamDaemonVisibility))]
|
||||
[ResponseOptions]
|
||||
public DreamDaemonVisibility? CurrentVisibility { get; set; }
|
||||
@@ -45,24 +48,28 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The port the running <see cref="DreamDaemonResponse"/> instance is set to.
|
||||
/// </summary>
|
||||
/// <example>1337</example>
|
||||
[ResponseOptions]
|
||||
public ushort? CurrentPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="EngineType.OpenDream"/> topic port the running <see cref="DreamDaemonResponse"/> instance is set to.
|
||||
/// </summary>
|
||||
/// <example>3000</example>
|
||||
[ResponseOptions]
|
||||
public ushort? CurrentTopicPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The webclient status the running <see cref="DreamDaemonResponse"/> instance is set to.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
[ResponseOptions]
|
||||
public bool? CurrentAllowWebclient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of RAM in use by the game server in bytes.
|
||||
/// </summary>
|
||||
/// <example>1073741824</example>
|
||||
[ResponseOptions]
|
||||
public long? ImmediateMemoryUsage { get; set; }
|
||||
}
|
||||
|
||||
@@ -13,16 +13,19 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The version of the API the server is using.
|
||||
/// </summary>
|
||||
/// <example>9.3.0</example>
|
||||
public Version? ServerApiVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A human readable description of the error.
|
||||
/// A human-readable description of the error.
|
||||
/// </summary>
|
||||
/// <example>Oopsie woopsie, we did a fucky wucky!</example>
|
||||
public string? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional data associated with the error message.
|
||||
/// </summary>
|
||||
/// <example>Error at thing.app.dependency.class.function in line 32</example>
|
||||
[ResponseOptions]
|
||||
public string? AdditionalData { get; set; }
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/// <summary>
|
||||
/// The <see cref="EntityId.Id"/> of the <see cref="Instance"/>.
|
||||
/// </summary>
|
||||
/// <example>1</example>
|
||||
public long? InstanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -24,12 +25,14 @@
|
||||
/// <summary>
|
||||
/// Optional progress between 0 and 100 inclusive.
|
||||
/// </summary>
|
||||
/// <example>25</example>
|
||||
[ResponseOptions]
|
||||
public int? Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional description of the job's current .
|
||||
/// Optional description of the job's current progress.
|
||||
/// </summary>
|
||||
/// <example>Doing something important</example>
|
||||
[ResponseOptions]
|
||||
public string? Stage { get; set; }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The name of the log file.
|
||||
/// </summary>
|
||||
/// <example>tgs-20250118.log</example>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,16 +18,19 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The total number of pages in the query.
|
||||
/// </summary>
|
||||
/// <example>5</example>
|
||||
public int TotalPages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current size of pages in the query.
|
||||
/// </summary>
|
||||
/// <example>20</example>
|
||||
public int PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total items across all pages.
|
||||
/// </summary>
|
||||
/// <example>100</example>
|
||||
public int TotalItems { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,19 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The version of the host.
|
||||
/// </summary>
|
||||
/// <example>6.12.3</example>
|
||||
public Version? Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Api"/> version of the host.
|
||||
/// </summary>
|
||||
/// <example>10.12.0</example>
|
||||
public Version? ApiVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The DMAPI interop version the server uses.
|
||||
/// </summary>
|
||||
/// <example>7.3.0</example>
|
||||
public Version? DMApiVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -36,6 +39,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// If there is a server update in progress.
|
||||
/// </summary>
|
||||
/// <example>false</example>
|
||||
public bool UpdateInProgress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The version of tgstation-server pending update.
|
||||
/// </summary>
|
||||
/// <example>6.12.3</example>
|
||||
public Version NewVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Tgstation.Server.Api.Models.Response
|
||||
/// <summary>
|
||||
/// The value of the JWT.
|
||||
/// </summary>
|
||||
/// <example>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwibmJmIjoxNzM3MDkzNDgwLCJleHAiOjE3MzcwOTQzODAsImlhdCI6MTczNzA5MzQ4MCwiaXNzIjoiVGdzdGF0aW9uLlNlcnZlci5Ib3N0IiwiYXVkIjoiVGdzdGF0aW9uLlNlcnZlci5BcGkifQ.v64KX34_YOpH-HCbwqlx1p8u-MNbb4L6a9qEyXhcNcU</example>
|
||||
public string? Bearer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,18 +10,21 @@ namespace Tgstation.Server.Api.Models
|
||||
/// <summary>
|
||||
/// The number of the test merge source.
|
||||
/// </summary>
|
||||
/// <example>31026</example>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The sha of the test merge revision to merge. If not specified, the latest commit from the source will be used.
|
||||
/// </summary>
|
||||
/// <example>caa1e1f400c8b6a535e03cff28cf57f919e9378c</example>
|
||||
[Required]
|
||||
[StringLength(40)]
|
||||
[StringLength(Limits.MaximumCommitShaLength, MinimumLength = Limits.MaximumCommitShaLength)]
|
||||
public virtual string? TargetCommitSha { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional comment about the test.
|
||||
/// </summary>
|
||||
/// <example>this will fix everything -Admin</example>
|
||||
[ResponseOptions]
|
||||
[StringLength(Limits.MaximumStringLength)]
|
||||
public string? Comment { get; set; }
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
public class UserName : NamedEntity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <example>Admin</example>
|
||||
[RequestOptions(FieldPresence.Optional)]
|
||||
public override string? Name
|
||||
{
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: HTTP constants reference -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.3.0" />
|
||||
<!-- Usage: Decoding the 'nbf' property of JWTs -->
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.4.0" />
|
||||
<!-- Usage: Data model annotating -->
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.0" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- GraphQL connector and code generator -->
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0" />
|
||||
<PackageReference Include="StrawberryShake.Server" Version="14.2.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.1" />
|
||||
<PackageReference Include="StrawberryShake.Server" Version="15.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: Connecting to SignalR hubs in API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.1" />
|
||||
<!-- Usage: Using target JSON serializer for API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: Identifying if we're running under SystemD -->
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.1" />
|
||||
<!-- Usage: Console logging plugin -->
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
<!-- Usage: Command line argument support -->
|
||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" />
|
||||
<!-- Usage: Identifies when we are running in the context of the Windows SCM -->
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.1" />
|
||||
<!-- Usage: Windows event log logging plugin -->
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="9.0.1" />
|
||||
<!-- Usage: Console logging plugin -->
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
|
||||
<!-- Usage: Updated transitive dependency of Core.System.ServiceProcess -->
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<!-- Usage: Updated transitive dependency of Core.System.ServiceProcess -->
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.1" />
|
||||
<!-- Usage: Updated transitive dependency, unable to tell what of -->
|
||||
<PackageReference Include="System.Private.Uri" Version="4.3.2" />
|
||||
<!-- Usage: OS identification -->
|
||||
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
|
||||
<!-- Usage: Windows Service Manager intergration -->
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="9.0.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -177,6 +177,10 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
|
||||
var watchdogVersion = executingAssembly.GetName().Version?.Semver().ToString();
|
||||
|
||||
var serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (!File.Exists(assemblyPath))
|
||||
@@ -214,10 +218,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
bootstrapperSettingsFile,
|
||||
JsonSerializer.Serialize(
|
||||
bootstrapSettings,
|
||||
new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
}),
|
||||
serializerOptions),
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -258,6 +259,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
process.StartInfo.UseShellExecute = false; // runs in the same console
|
||||
|
||||
var killedHostProcess = false;
|
||||
var createdShutdownFile = false;
|
||||
try
|
||||
{
|
||||
Task? processTask = null;
|
||||
@@ -279,6 +281,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
{
|
||||
logger.LogInformation("Cancellation requested! Writing shutdown lock file...");
|
||||
File.WriteAllBytes(updateDirectory, Array.Empty<byte>());
|
||||
createdShutdownFile = true;
|
||||
}
|
||||
else
|
||||
logger.LogWarning("Cancellation requested while update directory exists!");
|
||||
@@ -330,15 +333,16 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
logger.LogWarning(ex2, "Error killing host process!");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(updateDirectory))
|
||||
File.Delete(updateDirectory);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
logger.LogWarning(ex2, "Error deleting comms file!");
|
||||
}
|
||||
if (createdShutdownFile)
|
||||
try
|
||||
{
|
||||
if (File.Exists(updateDirectory))
|
||||
File.Delete(updateDirectory);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
logger.LogWarning(ex2, "Error deleting comms file!");
|
||||
}
|
||||
|
||||
logger.LogInformation("Host exited!");
|
||||
}
|
||||
|
||||
@@ -173,5 +173,11 @@
|
||||
/// </summary>
|
||||
[EventScript("EngineInstallComplete")]
|
||||
EngineInstallComplete,
|
||||
|
||||
/// <summary>
|
||||
/// Before game server process is created. No parameters.
|
||||
/// </summary>
|
||||
[EventScript("DreamDaemonPreLaunch")]
|
||||
DreamDaemonPreLaunch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -516,6 +517,14 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
? logFilePath
|
||||
: null);
|
||||
|
||||
// If this isnt a staging DD (From a Deployment), fire off events
|
||||
if (!apiValidate)
|
||||
await eventConsumer.HandleEvent(
|
||||
EventType.DreamDaemonPreLaunch,
|
||||
Enumerable.Empty<string?>(),
|
||||
false,
|
||||
cancellationToken);
|
||||
|
||||
var process = await processExecutor.LaunchProcess(
|
||||
engineLock.ServerExePath,
|
||||
dmbProvider.Directory,
|
||||
@@ -539,7 +548,6 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
if (!engineLock.HasStandardOutput)
|
||||
networkPromptReaper.RegisterProcess(process);
|
||||
|
||||
// If this isnt a staging DD (From a Deployment), fire off an event
|
||||
if (!apiValidate)
|
||||
await eventConsumer.HandleEvent(
|
||||
EventType.DreamDaemonLaunch,
|
||||
|
||||
@@ -527,6 +527,7 @@ namespace Tgstation.Server.Host.Core
|
||||
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/>.</param>
|
||||
/// <param name="controlPanelConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="ControlPanelConfiguration"/> to use.</param>
|
||||
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="GeneralConfiguration"/> to use.</param>
|
||||
/// <param name="databaseConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="DatabaseConfiguration"/> to use.</param>
|
||||
/// <param name="swarmConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="SwarmConfiguration"/> to use.</param>
|
||||
/// <param name="internalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="InternalConfiguration"/> to use.</param>
|
||||
/// <param name="logger">The <see cref="Microsoft.Extensions.Logging.ILogger"/> for the <see cref="Application"/>.</param>
|
||||
@@ -538,6 +539,7 @@ namespace Tgstation.Server.Host.Core
|
||||
IAssemblyInformationProvider assemblyInformationProvider,
|
||||
IOptions<ControlPanelConfiguration> controlPanelConfigurationOptions,
|
||||
IOptions<GeneralConfiguration> generalConfigurationOptions,
|
||||
IOptions<DatabaseConfiguration> databaseConfigurationOptions,
|
||||
IOptions<SwarmConfiguration> swarmConfigurationOptions,
|
||||
IOptions<InternalConfiguration> internalConfigurationOptions,
|
||||
ILogger<Application> logger)
|
||||
@@ -552,11 +554,13 @@ namespace Tgstation.Server.Host.Core
|
||||
|
||||
var controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
|
||||
var generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
|
||||
var databaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions));
|
||||
var swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions));
|
||||
var internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions));
|
||||
|
||||
ArgumentNullException.ThrowIfNull(logger);
|
||||
|
||||
logger.LogDebug("Database provider: {provider}", databaseConfiguration.DatabaseType);
|
||||
logger.LogDebug("Content Root: {contentRoot}", hostingEnvironment.ContentRootPath);
|
||||
logger.LogTrace("Web Root: {webRoot}", hostingEnvironment.WebRootPath);
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace Tgstation.Server.Host.Extensions
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IAssemblyInformationProvider>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IOptions<ControlPanelConfiguration>>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IOptions<GeneralConfiguration>>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IOptions<DatabaseConfiguration>>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IOptions<SwarmConfiguration>>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<IOptions<InternalConfiguration>>(),
|
||||
applicationBuilder.ApplicationServices.GetRequiredService<ILogger<Application>>());
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Tgstation.Server.Host.GraphQL
|
||||
return error;
|
||||
|
||||
var errorBuilder = ErrorBuilder.FromError(error)
|
||||
.RemoveException()
|
||||
.SetException(null)
|
||||
.ClearExtensions();
|
||||
|
||||
const string ErrorCodeFieldName = "errorCode";
|
||||
|
||||
@@ -100,21 +100,21 @@
|
||||
<!-- Usage: GitLab interop -->
|
||||
<PackageReference Include="GitLabApiClient" Version="1.8.0" />
|
||||
<!-- Usage: GraphQL API Engine -->
|
||||
<PackageReference Include="HotChocolate.AspNetCore" Version="14.2.0" />
|
||||
<PackageReference Include="HotChocolate.AspNetCore" Version="15.0.3" />
|
||||
<!-- Usage: GraphQL Authorization Plugin -->
|
||||
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="14.2.0" />
|
||||
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="15.0.3" />
|
||||
<!-- Usage: GraphQL IDatabaseContext support -->
|
||||
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="14.2.0" />
|
||||
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="15.0.3" />
|
||||
<!-- Usage: DataLoader source generation -->
|
||||
<PackageReference Include="HotChocolate.Types.Analyzers" Version="14.2.0" />
|
||||
<PackageReference Include="HotChocolate.Types.Analyzers" Version="15.0.3" />
|
||||
<!-- Usage: GraphQL additional scalar type definitions -->
|
||||
<PackageReference Include="HotChocolate.Types.Scalars" Version="14.2.0" />
|
||||
<PackageReference Include="HotChocolate.Types.Scalars" Version="15.0.3" />
|
||||
<!-- Usage: git interop -->
|
||||
<PackageReference Include="LibGit2Sharp" Version="0.31.0" />
|
||||
<!-- Usage: Support ""legacy"" Newotonsoft.Json in HTTP pipeline. The rest of our codebase uses Newtonsoft. -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.12" />
|
||||
<!-- Usage: Using target JSON serializer for API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="9.0.1" />
|
||||
<!-- Usage: Generating dumps of dotnet engine processes -->
|
||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.553101" />
|
||||
<!-- Usage: Database ORM -->
|
||||
@@ -154,11 +154,11 @@
|
||||
<!-- Usage: Newtonsoft.Json plugin for OpenAPI spec generator -->
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="7.2.0" />
|
||||
<!-- Usage: Windows authentication plugin allowing searching for users by name -->
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.1" />
|
||||
<!-- Usage: Identifying owning user of Windows Process objects -->
|
||||
<PackageReference Include="System.Management" Version="9.0.0" />
|
||||
<PackageReference Include="System.Management" Version="9.0.1" />
|
||||
<!-- Usage: Temporary resolution to compatibility issues with EFCore 7 and .NET 8 -->
|
||||
<PackageReference Include="System.Security.Permissions" Version="9.0.0" />
|
||||
<PackageReference Include="System.Security.Permissions" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
@@ -99,6 +100,7 @@ namespace Tgstation.Server.Host.Utils
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Name = HeaderNames.Authorization,
|
||||
Description = "Username & Password authentication to obtain an JWT token when doing a (POST /api).",
|
||||
Scheme = ApiHeaders.BasicAuthenticationScheme,
|
||||
});
|
||||
|
||||
@@ -107,16 +109,18 @@ namespace Tgstation.Server.Host.Utils
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Name = HeaderNames.Authorization,
|
||||
Description = "OAuth2 based authentication.",
|
||||
Scheme = ApiHeaders.OAuthAuthenticationScheme,
|
||||
});
|
||||
|
||||
swaggerGenOptions.AddSecurityDefinition(TokenSecuritySchemeId, new OpenApiSecurityScheme
|
||||
{
|
||||
BearerFormat = "JWT",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Name = HeaderNames.Authorization,
|
||||
Description = "JWT Bearer token generated by the server (POST /api). You need this for most endpoints to work.",
|
||||
Scheme = ApiHeaders.BearerAuthenticationScheme,
|
||||
BearerFormat = "JWT",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -368,14 +372,11 @@ namespace Tgstation.Server.Host.Utils
|
||||
},
|
||||
};
|
||||
|
||||
operation.Security = new List<OpenApiSecurityRequirement>
|
||||
operation.Security = new List<OpenApiSecurityRequirement>()
|
||||
{
|
||||
new()
|
||||
{
|
||||
{
|
||||
tokenScheme,
|
||||
new List<string>()
|
||||
},
|
||||
{ tokenScheme, new List<string>() },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -493,7 +494,6 @@ namespace Tgstation.Server.Host.Utils
|
||||
var productHeaderSchema = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Format = "productheader",
|
||||
};
|
||||
|
||||
swaggerDoc.Components.Parameters.Add(ApiHeaders.ApiVersionHeader, new OpenApiParameter
|
||||
@@ -541,6 +541,28 @@ namespace Tgstation.Server.Host.Utils
|
||||
Id = HeaderNames.UserAgent,
|
||||
},
|
||||
});
|
||||
|
||||
// flatten (Tgstation.Server.*).MyClass
|
||||
if (operation.Description?.Length > 0)
|
||||
operation.Description = Regex.Replace(operation.Description, @"Tgstation\.Server\.(\w+\.)+(?=\w+)", string.Empty);
|
||||
|
||||
if (operation.Summary?.Length > 0)
|
||||
operation.Summary = Regex.Replace(operation.Summary, @"Tgstation\.Server\.(\w+\.)+(?=\w+)", string.Empty);
|
||||
|
||||
if (operation.RequestBody?.Description != null)
|
||||
operation.RequestBody.Description = Regex.Replace(operation.RequestBody.Description, @"Tgstation\.Server\.(\w+\.)+(?=\w+)", string.Empty);
|
||||
|
||||
foreach (var opPar in operation.Parameters)
|
||||
{
|
||||
if (opPar.Description != null)
|
||||
opPar.Description = Regex.Replace(opPar.Description, @"Tgstation\.Server\.(\w+\.)+(?=\w+)", string.Empty);
|
||||
}
|
||||
|
||||
foreach (var (_, opRes) in operation.Responses)
|
||||
{
|
||||
if (opRes.Description != null)
|
||||
opRes.Description = Regex.Replace(opRes.Description, @"Tgstation\.Server\.(\w+\.)+(?=\w+)", string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
AddDefaultResponses(swaggerDoc);
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: JWT injection into HTTP pipeline -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
|
||||
<!-- Usage: GitHub.com interop -->
|
||||
<PackageReference Include="Octokit" Version="13.0.1" />
|
||||
<PackageReference Include="Octokit" Version="14.0.0" />
|
||||
<!-- Usage: YAML conversion of Version objects -->
|
||||
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -40,39 +40,43 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.ConfigureServices(mockServiceCollection, null, null));
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(null, null, null, null, null, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(null, null, null, null, null, null, null, null, null, null, null));
|
||||
|
||||
var mockAppBuilder = new Mock<IApplicationBuilder>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, null, null, null, null, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, null, null, null, null, null, null, null, null, null, null));
|
||||
|
||||
var mockServerControl = new Mock<IServerControl>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, null, null, null, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, null, null, null, null, null, null, null, null, null));
|
||||
|
||||
var mockTokenFactory = new Mock<ITokenFactory>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, null, null, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, null, null, null, null, null, null, null, null));
|
||||
|
||||
var mockServerPortProvider = new Mock<IServerPortProvider>();
|
||||
mockServerPortProvider.SetupGet(x => x.HttpApiPort).Returns(5345);
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, null, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, null, null, null, null, null, null, null));
|
||||
|
||||
var mockAssemblyInformationProvider = Mock.Of<IAssemblyInformationProvider>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, null, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, null, null, null, null, null, null));
|
||||
|
||||
var mockControlPanelOptions = new Mock<IOptions<ControlPanelConfiguration>>();
|
||||
mockControlPanelOptions.SetupGet(x => x.Value).Returns(new ControlPanelConfiguration()).Verifiable();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, null, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, null, null, null, null, null));
|
||||
|
||||
var mockGeneralOptions = new Mock<IOptions<GeneralConfiguration>>();
|
||||
mockGeneralOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()).Verifiable();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, null, null, null, null));
|
||||
|
||||
var mockDatabaseOptions = new Mock<IOptions<DatabaseConfiguration>>();
|
||||
mockDatabaseOptions.SetupGet(x => x.Value).Returns(new DatabaseConfiguration()).Verifiable();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, mockDatabaseOptions.Object, null, null, null));
|
||||
|
||||
var mockSwarmOptions = new Mock<IOptions<SwarmConfiguration>>();
|
||||
mockSwarmOptions.SetupGet(x => x.Value).Returns(new SwarmConfiguration()).Verifiable();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, mockSwarmOptions.Object, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, mockDatabaseOptions.Object, mockSwarmOptions.Object, null, null));
|
||||
|
||||
var mockInternalOptions = new Mock<IOptions<InternalConfiguration>>();
|
||||
mockInternalOptions.SetupGet(x => x.Value).Returns(new InternalConfiguration()).Verifiable();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, mockSwarmOptions.Object, mockInternalOptions.Object, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(mockAppBuilder.Object, mockServerControl.Object, mockTokenFactory.Object, mockServerPortProvider.Object, mockAssemblyInformationProvider, mockControlPanelOptions.Object, mockGeneralOptions.Object, mockDatabaseOptions.Object, mockSwarmOptions.Object, mockInternalOptions.Object, null));
|
||||
|
||||
mockControlPanelOptions.VerifyAll();
|
||||
mockInternalOptions.VerifyAll();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user