From 53a18ba16f461fb7048e28583081ff364ba35686 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 14:01:38 -0400 Subject: [PATCH 1/7] Added Discord replies to commands --- .../Components/Chat/ChatManager.cs | 27 +++++++++------- .../Components/Chat/Message.cs | 2 +- .../Chat/Providers/DiscordMessage.cs | 16 ++++++++++ .../Chat/Providers/DiscordProvider.cs | 32 +++++++++++++++---- .../Components/Chat/Providers/IProvider.cs | 5 +-- .../Components/Chat/Providers/IrcProvider.cs | 8 +++-- .../Components/Chat/Providers/Provider.cs | 2 +- 7 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 src/Tgstation.Server.Host/Components/Chat/Providers/DiscordMessage.cs diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 97460ba2fd..5814e7b14e 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -329,7 +329,7 @@ namespace Tgstation.Server.Host.Components.Chat if (channelIds == null) throw new ArgumentNullException(nameof(channelIds)); - var task = SendMessage(message, channelIds, handlerCts.Token); + var task = SendMessage(channelIds, null, message, handlerCts.Token); AddMessageTask(task); } @@ -499,7 +499,7 @@ namespace Tgstation.Server.Host.Components.Chat .Select(x => x.Key) .ToList(); - return SendMessage(message, wdChannels, cancellationToken); + return SendMessage(wdChannels, null, message, cancellationToken); } /// @@ -641,11 +641,12 @@ namespace Tgstation.Server.Host.Components.Chat providerId, message.User.Channel.RealId); await SendMessage( - "Processing error, check logs!", new List { message.User.Channel.RealId, }, + null, + "Processing error, check logs!", cancellationToken) ; return; @@ -685,7 +686,7 @@ namespace Tgstation.Server.Host.Components.Chat if (splits.Count == 0) { // just a mention - await SendMessage("Hi!", new List { message.User.Channel.RealId }, cancellationToken); + await SendMessage(new List { message.User.Channel.RealId }, message, "Hi!", cancellationToken); return; } @@ -731,7 +732,7 @@ namespace Tgstation.Server.Host.Components.Chat helpText = UnknownCommandMessage; } - await SendMessage(helpText, new List { message.User.Channel.RealId }, cancellationToken); + await SendMessage(new List { message.User.Channel.RealId }, message, helpText, cancellationToken); return; } @@ -739,19 +740,19 @@ namespace Tgstation.Server.Host.Components.Chat if (commandHandler == default) { - await SendMessage(UnknownCommandMessage, new List { message.User.Channel.RealId }, cancellationToken); + await SendMessage(new List { message.User.Channel.RealId }, message, UnknownCommandMessage, cancellationToken); return; } if (commandHandler.AdminOnly && !message.User.Channel.IsAdminChannel) { - await SendMessage("Use this command in an admin channel!", new List { message.User.Channel.RealId }, cancellationToken); + await SendMessage(new List { message.User.Channel.RealId }, message, "Use this command in an admin channel!", cancellationToken); return; } var result = await commandHandler.Invoke(arguments, message.User, cancellationToken); if (result != null) - await SendMessage(result, new List { message.User.Channel.RealId }, cancellationToken); + await SendMessage(new List { message.User.Channel.RealId }, message, result, cancellationToken); } catch (OperationCanceledException ex) { @@ -763,8 +764,9 @@ namespace Tgstation.Server.Host.Components.Chat // error bc custom commands should reply about why it failed logger.LogError(e, "Error processing chat command"); await SendMessage( - "TGS: Internal error processing command! Check server logs!", new List { message.User.Channel.RealId }, + message, + "TGS: Internal error processing command! Check server logs!", cancellationToken) ; } @@ -861,11 +863,12 @@ namespace Tgstation.Server.Host.Components.Chat /// /// Asynchronously send a given to a set of . /// - /// The message to send. /// The s of the s to send to. + /// The to reply to. + /// The message to send. /// The for the operation. /// A representing the running operation. - Task SendMessage(string message, IEnumerable channelIds, CancellationToken cancellationToken) + Task SendMessage(IEnumerable channelIds, Message replyTo, string message, CancellationToken cancellationToken) { logger.LogTrace("Chat send \"{message}\" to channels: {channelIdsCommaSeperated}", message, String.Join(", ", channelIds)); @@ -880,7 +883,7 @@ namespace Tgstation.Server.Host.Components.Chat lock (providers) if (!providers.TryGetValue(channelMapping.ProviderId, out provider)) return Task.CompletedTask; - return provider.SendMessage(channelMapping.ProviderChannelId, message, cancellationToken); + return provider.SendMessage(replyTo, message, channelMapping.ProviderChannelId, cancellationToken); })); } diff --git a/src/Tgstation.Server.Host/Components/Chat/Message.cs b/src/Tgstation.Server.Host/Components/Chat/Message.cs index ba4befa0a9..321907029b 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Message.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Message.cs @@ -3,7 +3,7 @@ /// /// Represents a message recieved by a . /// - sealed class Message + class Message { /// /// The text of the message. diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordMessage.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordMessage.cs new file mode 100644 index 0000000000..b0b3fbb56e --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordMessage.cs @@ -0,0 +1,16 @@ +using Remora.Discord.API.Abstractions.Objects; +using Remora.Rest.Core; + +namespace Tgstation.Server.Host.Components.Chat.Providers +{ + /// + /// A containing the source . + /// + sealed class DiscordMessage : Message + { + /// + /// The of the source . + /// + public Optional MessageReference { get; set; } + } +} diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index aba57ae759..6ca3fc990b 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -219,14 +219,21 @@ namespace Tgstation.Server.Host.Components.Chat.Providers } /// - public override async Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken) + public override async Task SendMessage(Message replyTo, string message, ulong channelId, CancellationToken cancellationToken) { + Optional replyToReference = default; + if (replyTo != null && replyTo is DiscordMessage discordMessage) + { + replyToReference = discordMessage.MessageReference; + } + var channelsClient = serviceProvider.GetRequiredService(); async Task SendToChannel(Snowflake channelId) { var result = await channelsClient.CreateMessageAsync( channelId, message, + messageReference: replyToReference, ct: cancellationToken); if (!result.IsSuccess) @@ -273,8 +280,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers Logger.LogTrace("Dispatching to {0} unmapped channels...", unmappedTextChannels.Count()); await Task.WhenAll( unmappedTextChannels.Select( - x => SendToChannel(x.ID))) - ; + x => SendToChannel(x.ID))); } return; @@ -430,14 +436,25 @@ namespace Tgstation.Server.Host.Components.Chat.Providers || messageCreateEvent.Author.ID == currentUserId) return Result.FromSuccess(); + var messageReference = new MessageReference + { + ChannelID = messageCreateEvent.ChannelID, + GuildID = messageCreateEvent.GuildID, + MessageID = messageCreateEvent.ID, + FailIfNotExists = false, + }; + if (basedMeme && messageCreateEvent.Content.Equals("Based on what?", StringComparison.OrdinalIgnoreCase)) { // DCT: None available await SendMessage( - messageCreateEvent.ChannelID.Value, + new DiscordMessage + { + MessageReference = messageReference, + }, "https://youtu.be/LrNu-SuFF_o", - default) - ; + messageCreateEvent.ChannelID.Value, + default); return Result.FromSuccess(); } @@ -491,8 +508,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers messageCreateEvent.ID); } - var result = new Message + var result = new DiscordMessage { + MessageReference = messageReference, Content = content, User = new ChatUser { diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs index 702a51e984..732abfc829 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs @@ -63,11 +63,12 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// /// Send a message to the . /// - /// The to send to. + /// The to reply to. /// The message contents. + /// The to send to. /// The for the operation. /// A representing the running operation. - Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken); + Task SendMessage(Message replyTo, string message, ulong channelId, CancellationToken cancellationToken); /// /// Set the interval at which the provider starts jobs to try to reconnect. diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs index 42c26c813f..1297221e49 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -159,7 +159,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers } /// - public override Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken) => Task.Factory.StartNew( + public override Task SendMessage(Message replyTo, string message, ulong channelId, CancellationToken cancellationToken) => Task.Factory.StartNew( () => { // IRC doesn't allow newlines @@ -230,7 +230,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers }))); await SendMessage( - channelId, + null, String.Format( CultureInfo.InvariantCulture, "DM: Deploying revision: {0}{1}{2} BYOND Version: {3}{4}", @@ -243,11 +243,13 @@ namespace Tgstation.Server.Host.Components.Chat.Providers estimatedCompletionTime.HasValue ? $" ETA: {estimatedCompletionTime - DateTimeOffset.UtcNow}" : String.Empty), + channelId, cancellationToken); return (errorMessage, dreamMakerOutput) => SendMessage( - channelId, + null, $"DM: Deployment {(errorMessage == null ? "complete" : "failed")}!", + channelId, cancellationToken); } diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs index 3c339a6666..9ccee80725 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs @@ -165,7 +165,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers } /// - public abstract Task SendMessage(ulong channelId, string message, CancellationToken cancellationToken); + public abstract Task SendMessage(Message replyTo, string message, ulong channelId, CancellationToken cancellationToken); /// public abstract Task> SendUpdateMessage( From b44e141b780ba9c7d300d96cc83f39c11b37d20f Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 14:02:34 -0400 Subject: [PATCH 2/7] Version bump to 5.4.0 --- build/Version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Version.props b/build/Version.props index d192e1adb2..e9db76049d 100644 --- a/build/Version.props +++ b/build/Version.props @@ -3,7 +3,7 @@ - 5.3.3 + 5.4.0 4.4.0 9.8.1 10.2.0 From de39cd2a8088c4f2611d97ae9ca49b634780d35d Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 15:15:13 -0400 Subject: [PATCH 3/7] Update Nuget Packages. Fix Test projects. Etc... --- .../Models/Internal/ChatBotApiBase.cs | 2 + .../Tgstation.Server.Api.csproj | 2 +- src/Tgstation.Server.Host.Console/Program.cs | 6 +- .../Tgstation.Server.Host.Console.csproj | 2 +- src/Tgstation.Server.Host.Service/Program.cs | 123 +++++++++++------- .../ServerService.cs | 38 ++++-- .../Tgstation.Server.Host.Service.csproj | 6 +- .../.config/dotnet-tools.json | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 7 +- .../Tgstation.Server.Host.csproj | 32 ++--- .../Tgstation.Server.Api.Tests.csproj | 8 +- .../Tgstation.Server.Client.Tests.csproj | 10 +- ...Tgstation.Server.Host.Console.Tests.csproj | 10 +- .../TestServerService.cs | 20 ++- ...Tgstation.Server.Host.Service.Tests.csproj | 9 +- ...Tgstation.Server.Host.Tests.Signals.csproj | 4 +- .../Tgstation.Server.Host.Tests.csproj | 10 +- ...gstation.Server.Host.Watchdog.Tests.csproj | 10 +- .../Tgstation.Server.Tests/IntegrationTest.cs | 14 +- .../Tgstation.Server.Tests.csproj | 12 +- tools/ReleaseNotes/Program.cs | 42 +----- tools/ReleaseNotes/ReleaseNotes.csproj | 2 +- 22 files changed, 189 insertions(+), 182 deletions(-) diff --git a/src/Tgstation.Server.Api/Models/Internal/ChatBotApiBase.cs b/src/Tgstation.Server.Api/Models/Internal/ChatBotApiBase.cs index 2c4dcd8875..231a94ffbe 100644 --- a/src/Tgstation.Server.Api/Models/Internal/ChatBotApiBase.cs +++ b/src/Tgstation.Server.Api/Models/Internal/ChatBotApiBase.cs @@ -22,8 +22,10 @@ namespace Tgstation.Server.Api.Models.Internal return true; return Provider.Value switch { +#pragma warning disable CS0618 ChatProvider.Discord => Channels?.Select(x => (x.DiscordChannelId.HasValue || ulong.TryParse(x.ChannelData, out _)) && x.IrcChannel == null).All(x => x) ?? true, ChatProvider.Irc => Channels?.Select(x => !x.DiscordChannelId.HasValue && (x.IrcChannel != null || x.ChannelData != null)).All(x => x) ?? true, +#pragma warning restore CS0618 _ => throw new InvalidOperationException("Invalid provider type!"), }; } diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj index ceddbf5fc8..f079f488db 100644 --- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj +++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj @@ -47,7 +47,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Tgstation.Server.Host.Console/Program.cs b/src/Tgstation.Server.Host.Console/Program.cs index 6155a68460..f88188d7b4 100644 --- a/src/Tgstation.Server.Host.Console/Program.cs +++ b/src/Tgstation.Server.Host.Console/Program.cs @@ -26,15 +26,11 @@ namespace Tgstation.Server.Host.Console /// A representing the running operation. internal static async Task Main(string[] args) { - using var loggerFactory = new LoggerFactory(); + using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var arguments = new List(args); var trace = arguments.Remove("--trace-host-watchdog"); var debug = arguments.Remove("--debug-host-watchdog"); -#pragma warning disable CS0618 // Type or member is obsolete - loggerFactory.AddConsole(); -#pragma warning restore CS0618 // Type or member is obsolete - if (trace && debug) { loggerFactory.CreateLogger(nameof(Program)).LogCritical("Please specify only 1 of --trace-host-watchdog or --debug-host-watchdog!"); diff --git a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj index b76c2bcc1c..9ab96c2f7b 100644 --- a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj +++ b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj @@ -25,7 +25,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Tgstation.Server.Host.Service/Program.cs b/src/Tgstation.Server.Host.Service/Program.cs index ca5facbfd4..47eb8647dd 100644 --- a/src/Tgstation.Server.Host.Service/Program.cs +++ b/src/Tgstation.Server.Host.Service/Program.cs @@ -77,6 +77,54 @@ namespace Tgstation.Server.Host.Service /// A resulting in the 's exit code. static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); + /// + /// Attempt to install the TGS Service. + /// + static void RunServiceInstall() + { + // First check if the service already exists + if (Environment.UserInteractive) + foreach (ServiceController sc in ServiceController.GetServices()) + if (sc.ServiceName == "tgstation-server" || sc.ServiceName == "tgstation-server-4") + { + DialogResult result = MessageBox.Show($"You already have another TGS service installed ({sc.ServiceName}). Would you like to uninstall it now? Pressing \"No\" will cancel this install.", "TGS Service", MessageBoxButtons.YesNo); + if (result != DialogResult.Yes) + return; // is this needed after exit? + + // Stop it first to give it some cleanup time + if (sc.Status == ServiceControllerStatus.Running) + { + sc.Stop(); + sc.WaitForStatus(ServiceControllerStatus.Stopped); + } + + // And remove it + using (ServiceInstaller si = new ServiceInstaller()) + { + si.Context = new InstallContext($"old-{sc.ServiceName}-uninstall.log", null); + si.ServiceName = sc.ServiceName; + si.Uninstall(null); + } + } + + using (var processInstaller = new ServiceProcessInstaller()) + using (var installer = new ServiceInstaller()) + { + processInstaller.Account = ServiceAccount.LocalSystem; + + installer.Context = new InstallContext("tgs-install.log", new string[] { String.Format(CultureInfo.InvariantCulture, "/assemblypath={0}", Assembly.GetEntryAssembly().Location) }); + installer.Description = "/tg/station 13 server running as a windows service"; + installer.DisplayName = "/tg/station server"; + installer.StartType = ServiceStartMode.Automatic; + installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" }; + installer.ServiceName = ServerService.Name; + installer.Parent = processInstaller; + + var state = new ListDictionary(); + installer.Install(state); + } + } + /// /// Command line handler, always runs. /// @@ -112,54 +160,35 @@ namespace Tgstation.Server.Host.Service } } - using (var loggerFactory = new LoggerFactory()) + ServerService service = null; + ILoggerFactory loggerFactory; + try + { + loggerFactory = LoggerFactory.Create(builder => + { + if (Configure) + { + builder.AddConsole(); + } + + service = new ServerService(builder, Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information); + }); + } + catch + { + service?.Dispose(); + throw; + } + + using (loggerFactory) + using (service) { if (Install) { if (Uninstall) return; // oh no, it's retarded... - // First check if the service already exists - if (Environment.UserInteractive) - foreach (ServiceController sc in ServiceController.GetServices()) - if (sc.ServiceName == "tgstation-server" || sc.ServiceName == "tgstation-server-4") - { - DialogResult result = MessageBox.Show($"You already have another TGS service installed ({sc.ServiceName}). Would you like to uninstall it now? Pressing \"No\" will cancel this install.", "TGS Service", MessageBoxButtons.YesNo); - if (result != DialogResult.Yes) - return; // is this needed after exit? - - // Stop it first to give it some cleanup time - if (sc.Status == ServiceControllerStatus.Running) - { - sc.Stop(); - sc.WaitForStatus(ServiceControllerStatus.Stopped); - } - - // And remove it - using (ServiceInstaller si = new ServiceInstaller()) - { - si.Context = new InstallContext($"old-{sc.ServiceName}-uninstall.log", null); - si.ServiceName = sc.ServiceName; - si.Uninstall(null); - } - } - - using (var processInstaller = new ServiceProcessInstaller()) - using (var installer = new ServiceInstaller()) - { - processInstaller.Account = ServiceAccount.LocalSystem; - - installer.Context = new InstallContext("tgs-install.log", new string[] { String.Format(CultureInfo.InvariantCulture, "/assemblypath={0}", Assembly.GetEntryAssembly().Location) }); - installer.Description = "/tg/station 13 server running as a windows service"; - installer.DisplayName = "/tg/station server"; - installer.StartType = ServiceStartMode.Automatic; - installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" }; - installer.ServiceName = ServerService.Name; - installer.Parent = processInstaller; - - var state = new ListDictionary(); - installer.Install(state); - } + RunServiceInstall(); if (Configure) { @@ -175,15 +204,13 @@ namespace Tgstation.Server.Host.Service installer.Uninstall(null); } else if (!Configure) - using (var service = new ServerService(WatchdogFactory, loggerFactory, Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information)) - ServiceBase.Run(service); + { + service.SetupWatchdog(WatchdogFactory.CreateWatchdog(loggerFactory)); + ServiceBase.Run(service); + } if (Configure) { -#pragma warning disable CS0618 // Type or member is obsolete - loggerFactory.AddConsole(); -#pragma warning restore CS0618 // Type or member is obsolete - // DCT: None available await WatchdogFactory.CreateWatchdog(loggerFactory).RunAsync(true, Array.Empty(), default); } diff --git a/src/Tgstation.Server.Host.Service/ServerService.cs b/src/Tgstation.Server.Host.Service/ServerService.cs index a583c707ae..a2696d02df 100644 --- a/src/Tgstation.Server.Host.Service/ServerService.cs +++ b/src/Tgstation.Server.Host.Service/ServerService.cs @@ -25,7 +25,7 @@ namespace Tgstation.Server.Host.Service /// /// The for the . /// - readonly IWatchdog watchdog; + IWatchdog watchdog; /// /// The recieved from of . @@ -40,28 +40,39 @@ namespace Tgstation.Server.Host.Service /// /// Initializes a new instance of the class. /// - /// The to create with. - /// The for . + /// The to configure. /// The minimum to record in the event log. - public ServerService(IWatchdogFactory watchdogFactory, ILoggerFactory loggerFactory, LogLevel minumumLogLevel) + public ServerService(ILoggingBuilder loggingBuilder, LogLevel minumumLogLevel) { - if (watchdogFactory == null) - throw new ArgumentNullException(nameof(watchdogFactory)); - if (loggerFactory == null) - throw new ArgumentNullException(nameof(loggerFactory)); + if (loggingBuilder == null) + throw new ArgumentNullException(nameof(loggingBuilder)); -#pragma warning disable CS0618 // Type or member is obsolete - loggerFactory.AddEventLog(new EventLogSettings + loggingBuilder.AddEventLog(new EventLogSettings { LogName = EventLog.Log, MachineName = EventLog.MachineName, SourceName = EventLog.Source, Filter = (message, logLevel) => logLevel >= minumumLogLevel, }); -#pragma warning restore CS0618 // Type or member is obsolete ServiceName = Name; - watchdog = watchdogFactory.CreateWatchdog(loggerFactory); + } + + /// + /// Setup the for the service. + /// + /// The value of . + public void SetupWatchdog(IWatchdog watchdog) + { + if (watchdog == null) +#pragma warning disable IDE0016 // Use 'throw' expression + throw new ArgumentNullException(nameof(watchdog)); +#pragma warning restore IDE0016 // Use 'throw' expression + + if (this.watchdog != null) + throw new InvalidOperationException("SetupWatchdog called twice!"); + + this.watchdog = watchdog; } /// @@ -74,6 +85,9 @@ namespace Tgstation.Server.Host.Service /// protected override void OnStart(string[] args) { + if (watchdog == null) + throw new InvalidOperationException("Cannot start without watchdog!"); + cancellationTokenSource?.Dispose(); cancellationTokenSource = new CancellationTokenSource(); watchdogTask = RunWatchdog(args, cancellationTokenSource.Token); diff --git a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj index 79d5554a33..23ad2e5d76 100644 --- a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj +++ b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj @@ -23,13 +23,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Tgstation.Server.Host/.config/dotnet-tools.json b/src/Tgstation.Server.Host/.config/dotnet-tools.json index 9504514167..b8b93fc6c0 100644 --- a/src/Tgstation.Server.Host/.config/dotnet-tools.json +++ b/src/Tgstation.Server.Host/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "6.0.8", + "version": "6.0.15", "commands": [ "dotnet-ef" ] diff --git a/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs b/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs index 1ae2809a75..04c168dd7a 100644 --- a/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs @@ -6,6 +6,7 @@ using Elastic.CommonSchema.Serilog; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using Serilog; using Serilog.Configuration; using Serilog.Sinks.Elasticsearch; @@ -82,10 +83,10 @@ namespace Tgstation.Server.Host.Extensions .WriteTo .Async(sinkConfiguration => { - sinkConfiguration.Console( - outputTemplate: "[{Timestamp:HH:mm:ss}] {Level:w3}: {SourceContext:l} " + var template = "[{Timestamp:HH:mm:ss}] {Level:w3}: {SourceContext:l} " + SerilogContextTemplate - + "|IR:{InstanceReference}){NewLine} {Message:lj}{NewLine}{Exception}"); + + "|IR:{InstanceReference}){NewLine} {Message:lj}{NewLine}{Exception}"; + sinkConfiguration.Console(outputTemplate: template, formatProvider: CultureInfo.InvariantCulture); sinkConfigurationAction?.Invoke(sinkConfiguration); }); diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index 0b38eb0c60..f10673f97a 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -68,39 +68,39 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + - - - + + + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + - + diff --git a/tests/Tgstation.Server.Api.Tests/Tgstation.Server.Api.Tests.csproj b/tests/Tgstation.Server.Api.Tests/Tgstation.Server.Api.Tests.csproj index 1261f90b16..101deff1ef 100644 --- a/tests/Tgstation.Server.Api.Tests/Tgstation.Server.Api.Tests.csproj +++ b/tests/Tgstation.Server.Api.Tests/Tgstation.Server.Api.Tests.csproj @@ -8,14 +8,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/tests/Tgstation.Server.Client.Tests/Tgstation.Server.Client.Tests.csproj b/tests/Tgstation.Server.Client.Tests/Tgstation.Server.Client.Tests.csproj index 199af48d0d..ce4a0b2d71 100644 --- a/tests/Tgstation.Server.Client.Tests/Tgstation.Server.Client.Tests.csproj +++ b/tests/Tgstation.Server.Client.Tests/Tgstation.Server.Client.Tests.csproj @@ -8,14 +8,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/tests/Tgstation.Server.Host.Console.Tests/Tgstation.Server.Host.Console.Tests.csproj b/tests/Tgstation.Server.Host.Console.Tests/Tgstation.Server.Host.Console.Tests.csproj index 824e107ec6..af8cc25ccb 100644 --- a/tests/Tgstation.Server.Host.Console.Tests/Tgstation.Server.Host.Console.Tests.csproj +++ b/tests/Tgstation.Server.Host.Console.Tests/Tgstation.Server.Host.Console.Tests.csproj @@ -8,14 +8,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs index 7c16af5646..a01c4b5181 100644 --- a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs +++ b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; @@ -19,11 +19,9 @@ namespace Tgstation.Server.Host.Service.Tests [TestMethod] public void TestConstructionAndDisposal() { - Assert.ThrowsException(() => new ServerService(null, null, default)); - var mockWatchdogFactory = new Mock(); - Assert.ThrowsException(() => new ServerService(mockWatchdogFactory.Object, null, default)); - var mockLoggerFactory = new LoggerFactory(); - new ServerService(mockWatchdogFactory.Object, mockLoggerFactory, default).Dispose(); + Assert.ThrowsException(() => new ServerService(null, default)); + var mockLoggingBuilder = Mock.Of(); + new ServerService(mockLoggingBuilder, default).Dispose(); } [TestMethod] @@ -37,18 +35,16 @@ namespace Tgstation.Server.Host.Service.Tests var args = Array.Empty(); CancellationToken cancellationToken; mockWatchdog.Setup(x => x.RunAsync(false, args, It.IsAny())).Callback((bool x, string[] _, CancellationToken token) => cancellationToken = token).Returns(Task.CompletedTask).Verifiable(); - var mockWatchdogFactory = new Mock(); - var mockLoggerFactory = new LoggerFactory(); - mockWatchdogFactory.Setup(x => x.CreateWatchdog(mockLoggerFactory)).Returns(mockWatchdog.Object).Verifiable(); + var mockLoggerFactory = Mock.Of(); - using (var service = new ServerService(mockWatchdogFactory.Object, mockLoggerFactory, default)) + using (var service = new ServerService(mockLoggerFactory, default)) { + Assert.ThrowsException(() => onStart.Invoke(service, new object[] { args })); + service.SetupWatchdog(mockWatchdog.Object); onStart.Invoke(service, new object[] { args }); onStop.Invoke(service, Array.Empty()); mockWatchdog.VerifyAll(); } - - mockWatchdogFactory.VerifyAll(); } } } diff --git a/tests/Tgstation.Server.Host.Service.Tests/Tgstation.Server.Host.Service.Tests.csproj b/tests/Tgstation.Server.Host.Service.Tests/Tgstation.Server.Host.Service.Tests.csproj index e167d80c15..6f7e285f04 100644 --- a/tests/Tgstation.Server.Host.Service.Tests/Tgstation.Server.Host.Service.Tests.csproj +++ b/tests/Tgstation.Server.Host.Service.Tests/Tgstation.Server.Host.Service.Tests.csproj @@ -13,13 +13,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + diff --git a/tests/Tgstation.Server.Host.Tests.Signals/Tgstation.Server.Host.Tests.Signals.csproj b/tests/Tgstation.Server.Host.Tests.Signals/Tgstation.Server.Host.Tests.Signals.csproj index 5443e844ce..3264033b5e 100644 --- a/tests/Tgstation.Server.Host.Tests.Signals/Tgstation.Server.Host.Tests.Signals.csproj +++ b/tests/Tgstation.Server.Host.Tests.Signals/Tgstation.Server.Host.Tests.Signals.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj b/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj index 84ed7d5882..268d2a524d 100644 --- a/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj +++ b/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj @@ -8,14 +8,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/tests/Tgstation.Server.Host.Watchdog.Tests/Tgstation.Server.Host.Watchdog.Tests.csproj b/tests/Tgstation.Server.Host.Watchdog.Tests/Tgstation.Server.Host.Watchdog.Tests.csproj index 6598062bed..e3e7216124 100644 --- a/tests/Tgstation.Server.Host.Watchdog.Tests/Tgstation.Server.Host.Watchdog.Tests.csproj +++ b/tests/Tgstation.Server.Host.Watchdog.Tests/Tgstation.Server.Host.Watchdog.Tests.csproj @@ -14,14 +14,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs index 09e7592142..592d6da6a6 100644 --- a/tests/Tgstation.Server.Tests/IntegrationTest.cs +++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs @@ -152,7 +152,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(1, serverInformation.SwarmServers.Count); var controller = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "controller"); Assert.IsNotNull(controller); - Assert.AreEqual(controller.Address, "http://localhost:5011"); + Assert.AreEqual(controller.Address, new Uri("http://localhost:5011")); Assert.IsTrue(controller.Controller); } @@ -270,17 +270,17 @@ namespace Tgstation.Server.Tests var node1 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node1"); Assert.IsNotNull(node1); - Assert.AreEqual(node1.Address, "http://localhost:5012"); + Assert.AreEqual(node1.Address, new Uri("http://localhost:5012")); Assert.IsFalse(node1.Controller); var node2 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node2"); Assert.IsNotNull(node2); - Assert.AreEqual(node2.Address, "http://localhost:5013"); + Assert.AreEqual(node2.Address, new Uri("http://localhost:5013")); Assert.IsFalse(node2.Controller); var controller = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "controller"); Assert.IsNotNull(controller); - Assert.AreEqual(controller.Address, "http://localhost:5011"); + Assert.AreEqual(controller.Address, new Uri("http://localhost:5011")); Assert.IsTrue(controller.Controller); } @@ -483,17 +483,17 @@ namespace Tgstation.Server.Tests var node1 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node1"); Assert.IsNotNull(node1); - Assert.AreEqual(node1.Address, "http://localhost:5012"); + Assert.AreEqual(node1.Address, new Uri("http://localhost:5012")); Assert.IsFalse(node1.Controller); var node2 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node2"); Assert.IsNotNull(node2); - Assert.AreEqual(node2.Address, "http://localhost:5013"); + Assert.AreEqual(node2.Address, new Uri("http://localhost:5013")); Assert.IsFalse(node2.Controller); var controller = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "controller"); Assert.IsNotNull(controller); - Assert.AreEqual(controller.Address, "http://localhost:5011"); + Assert.AreEqual(controller.Address, new Uri("http://localhost:5011")); Assert.IsTrue(controller.Controller); } diff --git a/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj b/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj index 4c31c1b3c0..6e95c2cd3c 100644 --- a/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj +++ b/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -8,14 +8,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/tools/ReleaseNotes/Program.cs b/tools/ReleaseNotes/Program.cs index 89ed7a56ae..12e9dbe647 100644 --- a/tools/ReleaseNotes/Program.cs +++ b/tools/ReleaseNotes/Program.cs @@ -75,7 +75,6 @@ namespace ReleaseNotes Task milestoneTask = null; var milestoneTaskLock = new object(); var releaseDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase); - var authorizedUsers = new Dictionary>(); bool postControlPanelMessage = false; @@ -111,44 +110,13 @@ namespace ReleaseNotes // if (!fullPR.Merged) //return; - async Task BuildNotesFromComment(string comment, User user) + void BuildNotesFromComment(string comment, User user) { if (comment == null) return; - async Task CommitNotes(string component, List notes) + void CommitNotes(string component, List notes) { - Task authTask; - TaskCompletionSource ourTcs = null; - lock (authorizedUsers) - { - if (!authorizedUsers.TryGetValue(user.Id, out authTask)) - { - ourTcs = new TaskCompletionSource(); - authTask = ourTcs.Task; - authorizedUsers.Add(user.Id, authTask); - } - } - - if (ourTcs != null) - try - { - //check if the user has access - var perm = String.IsNullOrWhiteSpace(githubToken) - ? PermissionLevel.Write - : (await client.Repository.Collaborator.ReviewPermission(RepoOwner, RepoName, user.Login).ConfigureAwait(false)).Permission; - ourTcs.SetResult(perm == PermissionLevel.Write || perm == PermissionLevel.Admin); - } - catch - { - ourTcs.SetResult(false); - throw; - } - - var authorized = await authTask.ConfigureAwait(false); - if (!authorized) - return; - lock (releaseDictionary) { foreach (var I in notes) @@ -180,7 +148,7 @@ namespace ReleaseNotes } if (trimmedLine.StartsWith("/:cl:", StringComparison.Ordinal)) { - await CommitNotes(targetComponent, notes); + CommitNotes(targetComponent, notes); targetComponent = null; notes.Clear(); continue; @@ -193,7 +161,9 @@ namespace ReleaseNotes } var comments = await client.Issue.Comment.GetAllForIssue(RepoOwner, RepoName, fullPR.Number).ConfigureAwait(false); - await Task.WhenAll(BuildNotesFromComment(fullPR.Body, fullPR.User), Task.WhenAll(comments.Select(x => BuildNotesFromComment(x.Body, x.User)))).ConfigureAwait(false); + BuildNotesFromComment(fullPR.Body, fullPR.User); + foreach(var x in comments) + BuildNotesFromComment(x.Body, x.User); } var tasks = new List(); diff --git a/tools/ReleaseNotes/ReleaseNotes.csproj b/tools/ReleaseNotes/ReleaseNotes.csproj index c366f54023..ce9d33e372 100644 --- a/tools/ReleaseNotes/ReleaseNotes.csproj +++ b/tools/ReleaseNotes/ReleaseNotes.csproj @@ -8,7 +8,7 @@ - + From fc71f8a5e1ee3b678872d43ff1d37afde29eaf64 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 15:48:08 -0400 Subject: [PATCH 4/7] Fix SQLite setup wizard issue again --- src/Tgstation.Server.Host/Setup/SetupWizard.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs index 04a49fda7a..53d31df891 100644 --- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs @@ -276,9 +276,12 @@ namespace Tgstation.Server.Host.Setup } if (isSqliteDB && !dbExists) - await Task.WhenAll( - console.WriteAsync("Deleting test database file...", true, cancellationToken), - ioManager.DeleteFile(databaseName, cancellationToken)); + { + await console.WriteAsync("Deleting test database file...", true, cancellationToken); + if (platformIdentifier.IsWindows) + SqliteConnection.ClearAllPools(); + await ioManager.DeleteFile(databaseName, cancellationToken); + } } /// From f04d1973e7210594011cfedc70f3c06fc91f40a5 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 15:48:44 -0400 Subject: [PATCH 5/7] Fix Sevice logging --- src/Tgstation.Server.Host.Service/Program.cs | 72 +++++++------------ .../ServerService.cs | 66 +++++++---------- .../TestServerService.cs | 13 ++-- 3 files changed, 58 insertions(+), 93 deletions(-) diff --git a/src/Tgstation.Server.Host.Service/Program.cs b/src/Tgstation.Server.Host.Service/Program.cs index 47eb8647dd..95afc4ca21 100644 --- a/src/Tgstation.Server.Host.Service/Program.cs +++ b/src/Tgstation.Server.Host.Service/Program.cs @@ -160,61 +160,37 @@ namespace Tgstation.Server.Host.Service } } - ServerService service = null; - ILoggerFactory loggerFactory; - try + if (Install) { - loggerFactory = LoggerFactory.Create(builder => - { - if (Configure) - { - builder.AddConsole(); - } + if (Uninstall) + return; // oh no, it's retarded... - service = new ServerService(builder, Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information); - }); - } - catch - { - service?.Dispose(); - throw; - } - - using (loggerFactory) - using (service) - { - if (Install) - { - if (Uninstall) - return; // oh no, it's retarded... - - RunServiceInstall(); - - if (Configure) - { - Console.WriteLine("For this first run we'll launch the console runner so you may use the setup wizard."); - Console.WriteLine("If it starts successfully, feel free to close it and then start the service from the Windows control panel."); - } - } - else if (Uninstall) - using (var installer = new ServiceInstaller()) - { - installer.Context = new InstallContext("tgs-uninstall.log", null); - installer.ServiceName = ServerService.Name; - installer.Uninstall(null); - } - else if (!Configure) - { - service.SetupWatchdog(WatchdogFactory.CreateWatchdog(loggerFactory)); - ServiceBase.Run(service); - } + RunServiceInstall(); if (Configure) { - // DCT: None available - await WatchdogFactory.CreateWatchdog(loggerFactory).RunAsync(true, Array.Empty(), default); + Console.WriteLine("For this first run we'll launch the console runner so you may use the setup wizard."); + Console.WriteLine("If it starts successfully, feel free to close it and then start the service from the Windows control panel."); } } + else if (Uninstall) + using (var installer = new ServiceInstaller()) + { + installer.Context = new InstallContext("tgs-uninstall.log", null); + installer.ServiceName = ServerService.Name; + installer.Uninstall(null); + } + else if (!Configure) + { + using (var service = new ServerService(WatchdogFactory, Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information)) + ServiceBase.Run(service); + } + + if (Configure) + { + using (var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole())) + await WatchdogFactory.CreateWatchdog(loggerFactory).RunAsync(true, Array.Empty(), default); // DCT: None available + } } } } diff --git a/src/Tgstation.Server.Host.Service/ServerService.cs b/src/Tgstation.Server.Host.Service/ServerService.cs index a2696d02df..d1adffdaf1 100644 --- a/src/Tgstation.Server.Host.Service/ServerService.cs +++ b/src/Tgstation.Server.Host.Service/ServerService.cs @@ -25,10 +25,15 @@ namespace Tgstation.Server.Host.Service /// /// The for the . /// - IWatchdog watchdog; + readonly IWatchdogFactory watchdogFactory; /// - /// The recieved from of . + /// The minimum for the . + /// + readonly LogLevel minimumLogLevel; + + /// + /// The that represents the running service. /// Task watchdogTask; @@ -40,41 +45,15 @@ namespace Tgstation.Server.Host.Service /// /// Initializes a new instance of the class. /// - /// The to configure. - /// The minimum to record in the event log. - public ServerService(ILoggingBuilder loggingBuilder, LogLevel minumumLogLevel) + /// The value of . + /// The minimum to record in the event log. + public ServerService(IWatchdogFactory watchdogFactory, LogLevel minimumLogLevel) { - if (loggingBuilder == null) - throw new ArgumentNullException(nameof(loggingBuilder)); - - loggingBuilder.AddEventLog(new EventLogSettings - { - LogName = EventLog.Log, - MachineName = EventLog.MachineName, - SourceName = EventLog.Source, - Filter = (message, logLevel) => logLevel >= minumumLogLevel, - }); - + this.watchdogFactory = watchdogFactory ?? throw new ArgumentNullException(nameof(watchdogFactory)); + this.minimumLogLevel = minimumLogLevel; ServiceName = Name; } - /// - /// Setup the for the service. - /// - /// The value of . - public void SetupWatchdog(IWatchdog watchdog) - { - if (watchdog == null) -#pragma warning disable IDE0016 // Use 'throw' expression - throw new ArgumentNullException(nameof(watchdog)); -#pragma warning restore IDE0016 // Use 'throw' expression - - if (this.watchdog != null) - throw new InvalidOperationException("SetupWatchdog called twice!"); - - this.watchdog = watchdog; - } - /// protected override void Dispose(bool disposing) { @@ -85,12 +64,20 @@ namespace Tgstation.Server.Host.Service /// protected override void OnStart(string[] args) { - if (watchdog == null) - throw new InvalidOperationException("Cannot start without watchdog!"); + var loggerFactory = LoggerFactory.Create(builder => builder.AddEventLog(new EventLogSettings + { + LogName = EventLog.Log, + MachineName = EventLog.MachineName, + SourceName = EventLog.Source, + Filter = (message, logLevel) => logLevel >= minimumLogLevel, + })); + + var watchdog = watchdogFactory.CreateWatchdog(loggerFactory); cancellationTokenSource?.Dispose(); cancellationTokenSource = new CancellationTokenSource(); - watchdogTask = RunWatchdog(args, cancellationTokenSource.Token); + + watchdogTask = RunWatchdog(watchdog, args, cancellationTokenSource.Token); } /// @@ -101,12 +88,13 @@ namespace Tgstation.Server.Host.Service } /// - /// Executes the , stopping the service if it exits. + /// Executes the , stopping the service if it exits. /// - /// The arguments for the . + /// The to run. + /// The arguments for the . /// The for the operation. /// A representing the running operation. - async Task RunWatchdog(string[] args, CancellationToken cancellationToken) + async Task RunWatchdog(IWatchdog watchdog, string[] args, CancellationToken cancellationToken) { await watchdog.RunAsync(false, args, cancellationTokenSource.Token); diff --git a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs index a01c4b5181..03846f15a6 100644 --- a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs +++ b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs @@ -20,8 +20,8 @@ namespace Tgstation.Server.Host.Service.Tests public void TestConstructionAndDisposal() { Assert.ThrowsException(() => new ServerService(null, default)); - var mockLoggingBuilder = Mock.Of(); - new ServerService(mockLoggingBuilder, default).Dispose(); + var mockWatchdogFactory = new Mock(); + new ServerService(mockWatchdogFactory.Object, default).Dispose(); } [TestMethod] @@ -35,16 +35,17 @@ namespace Tgstation.Server.Host.Service.Tests var args = Array.Empty(); CancellationToken cancellationToken; mockWatchdog.Setup(x => x.RunAsync(false, args, It.IsAny())).Callback((bool x, string[] _, CancellationToken token) => cancellationToken = token).Returns(Task.CompletedTask).Verifiable(); - var mockLoggerFactory = Mock.Of(); + var mockWatchdogFactory = new Mock(); + mockWatchdogFactory.Setup(x => x.CreateWatchdog(It.IsNotNull())).Returns(mockWatchdog.Object).Verifiable(); - using (var service = new ServerService(mockLoggerFactory, default)) + using (var service = new ServerService(mockWatchdogFactory.Object, default)) { - Assert.ThrowsException(() => onStart.Invoke(service, new object[] { args })); - service.SetupWatchdog(mockWatchdog.Object); onStart.Invoke(service, new object[] { args }); onStop.Invoke(service, Array.Empty()); mockWatchdog.VerifyAll(); } + + mockWatchdogFactory.VerifyAll(); } } } From 8baed3e1085f41e4d14a66489d21acc7a1d1040e Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 15:49:02 -0400 Subject: [PATCH 6/7] Remove another 4 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 368f9ac979..7df09e1651 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ For the docker version run `docker stop ` ## Integrating -tgstation-server 4 provides the DMAPI which can be be integrated into any BYOND codebase for heavily enhanced functionality. The integration process is a fairly simple set of code changes. +tgstation-server provides the DMAPI which can be be integrated into any BYOND codebase for heavily enhanced functionality. The integration process is a fairly simple set of code changes. 1. Copy the [latest release of the DMAPI](https://github.com/tgstation/tgstation-server/releases) anywhere in your code base. `tgs.dm` can be seperated from the `tgs` folder, but do not modify or move the contents of the `tgs` folder 2. Modify your `.dme`(s) to include the `tgs.dm` and `tgs/includes.dm` files (ORDER OF APPEARANCE IS MANDATORY) From d32eef711006297a4706be8bf48c91b1d6202cbb Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 25 Mar 2023 17:15:17 -0400 Subject: [PATCH 7/7] Fix release build. --- .../ServerService.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Tgstation.Server.Host.Service/ServerService.cs b/src/Tgstation.Server.Host.Service/ServerService.cs index d1adffdaf1..775946d42c 100644 --- a/src/Tgstation.Server.Host.Service/ServerService.cs +++ b/src/Tgstation.Server.Host.Service/ServerService.cs @@ -32,6 +32,11 @@ namespace Tgstation.Server.Host.Service /// readonly LogLevel minimumLogLevel; + /// + /// The used by the service. + /// + ILoggerFactory loggerFactory; + /// /// The that represents the running service. /// @@ -57,6 +62,7 @@ namespace Tgstation.Server.Host.Service /// protected override void Dispose(bool disposing) { + loggerFactory?.Dispose(); cancellationTokenSource?.Dispose(); base.Dispose(disposing); } @@ -64,13 +70,16 @@ namespace Tgstation.Server.Host.Service /// protected override void OnStart(string[] args) { - var loggerFactory = LoggerFactory.Create(builder => builder.AddEventLog(new EventLogSettings + if (loggerFactory == null) { - LogName = EventLog.Log, - MachineName = EventLog.MachineName, - SourceName = EventLog.Source, - Filter = (message, logLevel) => logLevel >= minimumLogLevel, - })); + loggerFactory = LoggerFactory.Create(builder => builder.AddEventLog(new EventLogSettings + { + LogName = EventLog.Log, + MachineName = EventLog.MachineName, + SourceName = EventLog.Source, + Filter = (message, logLevel) => logLevel >= minimumLogLevel, + })); + } var watchdog = watchdogFactory.CreateWatchdog(loggerFactory);