diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 615c574..e20041a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,16 +21,12 @@ jobs: 7z a publish/CentCom.API-linux-x64.7z -r ./publish/linux-x64/CentCom.API/* dotnet publish CentCom.Server -o publish/linux-x64/CentCom.Server -r "linux-x64" --self-contained false -c Release --nologo 7z a publish/CentCom.Server-linux-x64.7z -r ./publish/linux-x64/CentCom.Server/* - dotnet publish CentCom.Bot -o publish/linux-x64/CentCom.Bot -r "linux-x64" --self-contained false -c Release --nologo - 7z a publish/CentCom.Bot-linux-x64.7z -r ./publish/linux-x64/CentCom.Bot/* dotnet publish CentCom.Exporter -o publish/linux-x64/CentCom.Exporter -r "linux-x64" --self-contained false -c Release --nologo 7z a publish/CentCom.Exporter-linux-x64.7z -r ./publish/linux-x64/CentCom.Exporter/* dotnet publish CentCom.API -o publish/win-x64/CentCom.API/ -r "win-x64" --self-contained false -c Release --nologo 7z a publish/CentCom.API-win-x64.7z -r ./publish/win-x64/CentCom.API/* dotnet publish CentCom.Server -o publish/win-x64/CentCom.Server -r "win-x64" --self-contained false -c Release --nologo 7z a publish/CentCom.Server-win-x64.7z -r ./publish/win-x64/CentCom.Server/* - dotnet publish CentCom.Bot -o publish/win-x64/CentCom.Bot -r "win-x64" --self-contained false -c Release --nologo - 7z a publish/CentCom.Bot-win-x64.7z -r ./publish/win-x64/CentCom.Bot/* dotnet publish CentCom.Exporter -o publish/win-x64/CentCom.Exporter -r "win-x64" --self-contained false -c Release --nologo 7z a publish/CentCom.Exporter-win-x64.7z -r ./publish/win-x64/CentCom.Exporter/* - name: Upload release artifacts @@ -47,7 +43,7 @@ jobs: tag }); const releaseRuntimes = ['linux-x64', 'win-x64']; - const projects = ['CentCom.API', 'CentCom.Server', 'CentCom.Exporter', 'CentCom.Bot']; + const projects = ['CentCom.API', 'CentCom.Server', 'CentCom.Exporter']; for (rt of releaseRuntimes) { for (proj of projects) { // Upload the release asset diff --git a/.gitignore b/.gitignore index dfcfd56..d40d4a6 100644 --- a/.gitignore +++ b/.gitignore @@ -348,3 +348,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# Rider files +.idea/**/* \ No newline at end of file diff --git a/.idea/.idea.CentCom/.idea/indexLayout.xml b/.idea/.idea.CentCom/.idea/indexLayout.xml deleted file mode 100644 index 7b08163..0000000 --- a/.idea/.idea.CentCom/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.CentCom/.idea/misc.xml b/.idea/.idea.CentCom/.idea/misc.xml deleted file mode 100644 index 1d8c84d..0000000 --- a/.idea/.idea.CentCom/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/.idea.CentCom/.idea/projectSettingsUpdater.xml b/.idea/.idea.CentCom/.idea/projectSettingsUpdater.xml deleted file mode 100644 index 4bb9f4d..0000000 --- a/.idea/.idea.CentCom/.idea/projectSettingsUpdater.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/.idea.CentCom/.idea/vcs.xml b/.idea/.idea.CentCom/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/.idea.CentCom/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/.idea.CentCom/.idea/workspace.xml b/.idea/.idea.CentCom/.idea/workspace.xml deleted file mode 100644 index 3a2df56..0000000 --- a/.idea/.idea.CentCom/.idea/workspace.xml +++ /dev/null @@ -1,393 +0,0 @@ - - - - CentCom.API/CentCom.API.csproj - CentCom.API/CentCom.API.csproj - CentCom.Bot/CentCom.Bot.csproj - CentCom.Explorer/CentCom.Explorer.csproj - CentCom.Explorer/CentCom.Explorer.csproj - CentCom.Exporter/CentCom.Exporter.csproj - CentCom.Exporter/CentCom.Exporter.csproj - CentCom.Server/CentCom.Server.csproj - CentCom.Test/CentCom.Test.csproj - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - "keyToString": { - "WebServerToolWindowFactoryState": "false", - "node.js.detected.package.eslint": "true", - "node.js.detected.package.tslint": "true", - "node.js.selected.package.eslint": "(autodetect)", - "node.js.selected.package.tslint": "(autodetect)", - "nodejs_package_manager_path": "npm", - "settings.editor.selected.configurable": "preferences.sourceCode.C#", - "vue.rearranger.settings.migration": "true" - } -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1621808892140 - - - 1628898475361 - - - 1636645949025 - - - - - - - \ No newline at end of file diff --git a/CentCom.API/CentCom.API.csproj b/CentCom.API/CentCom.API.csproj index 38c5592..9346d21 100644 --- a/CentCom.API/CentCom.API.csproj +++ b/CentCom.API/CentCom.API.csproj @@ -7,19 +7,19 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/CentCom.Bot/CentCom.Bot.csproj b/CentCom.Bot/CentCom.Bot.csproj deleted file mode 100644 index 5c2b2bb..0000000 --- a/CentCom.Bot/CentCom.Bot.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - Exe - c8af1449-8cdf-4707-a66d-51e896551bfb - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - Always - - - - - - - - diff --git a/CentCom.Bot/Commands/AboutCommands.cs b/CentCom.Bot/Commands/AboutCommands.cs deleted file mode 100644 index 345b199..0000000 --- a/CentCom.Bot/Commands/AboutCommands.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Threading.Tasks; -using CentCom.Common.Data; -using CentCom.Common.Util; -using Microsoft.EntityFrameworkCore; -using Remora.Commands.Attributes; -using Remora.Commands.Groups; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Discord.API.Objects; -using Remora.Discord.Commands.Attributes; -using Remora.Discord.Commands.Feedback.Services; -using Remora.Results; - -namespace CentCom.Bot.Commands; - -public class AboutCommands : CommandGroup -{ - private readonly DatabaseContext _dbContext; - private readonly FeedbackService _feedback; - - public AboutCommands(DatabaseContext dbContext, FeedbackService feedback) - { - _dbContext = dbContext; - _feedback = feedback; - } - - [Command("about")] - [Description("Get basic information about CentCom and its performance")] - [CommandType(ApplicationCommandType.ChatInput)] - public async Task GetAboutAsync() - { - var stats = new List - { - new EmbedField("Total Bans", (await _dbContext.Bans.CountAsync()).ToString(), true), - new EmbedField("Total Sources", (await _dbContext.BanSources.CountAsync()).ToString(), true), - new EmbedField("Bans in Last 24h", (await _dbContext.Bans - .Where(x => x.BannedOn > DateTime.UtcNow.AddDays(-1)) - .CountAsync()).ToString(), true - ) - }; - var embed = new Embed("Oh, woah, what's this?", - Description: - "[CentCom](https://centcom.melonmesa.com/) is a ban data aggregation service for Space Station 13. " + - "This bot, ``CentCom.Bot``, serves as a utility to provide feedback when something is wrong. You can " + - "find the source on GitHub [here](https://github.com/bobbahbrown/centcom).", - Fields: stats, - Colour: _feedback.Theme.Success, - Timestamp: DateTimeOffset.UtcNow, - Footer: new EmbedFooter($"{AssemblyInformation.Current.Version} ({AssemblyInformation.Current.Commit[..7]})")); - var result = await _feedback.SendContextualEmbedAsync(embed, ct: CancellationToken); - return result.IsSuccess ? Result.FromSuccess() : Result.FromError(result); - } - - [Command("invite")] - [Description("Get an invite link for the bot to your server")] - [CommandType(ApplicationCommandType.ChatInput)] - public async Task GetInviteAsync() - { - const string inviteLink = - "https://discord.com/api/oauth2/authorize?client_id=878121825333293127&permissions=51264&scope=bot%20applications.commands"; - return await _feedback.SendContextualEmbedAsync(new Embed( - Description: $"[Click here]({inviteLink}) to invite me to your server!", - Colour: _feedback.Theme.Primary, - Timestamp: DateTimeOffset.UtcNow, - Footer: new EmbedFooter($"{AssemblyInformation.Current.Version} ({AssemblyInformation.Current.Commit[..7]})"))); - } -} \ No newline at end of file diff --git a/CentCom.Bot/Commands/SearchCommands.cs b/CentCom.Bot/Commands/SearchCommands.cs deleted file mode 100644 index 385bc41..0000000 --- a/CentCom.Bot/Commands/SearchCommands.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Threading.Tasks; -using CentCom.Common.Data; -using CentCom.Common.Models; -using CentCom.Common.Models.Byond; -using CentCom.Common.Models.DTO; -using CentCom.Common.Util; -using Microsoft.EntityFrameworkCore; -using Remora.Commands.Attributes; -using Remora.Commands.Groups; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Discord.API.Objects; -using Remora.Discord.Commands.Feedback.Services; -using Remora.Results; - -namespace CentCom.Bot.Commands; - -public class SearchCommands : CommandGroup -{ - private readonly DatabaseContext _dbContext; - private readonly FeedbackService _feedback; - - public SearchCommands(DatabaseContext dbContext, FeedbackService feedback) - { - _dbContext = dbContext; - _feedback = feedback; - } - - [Command("search")] - [Description("Search and view a summary for a player on CentCom")] - public async Task LookupCkey(string key) - { - var ckey = new CKey(key); - var bans = (await _dbContext.Bans - .Include(x => x.JobBans) - .Include(x => x.SourceNavigation) - .Where(x => x.CKey == ckey.CanonicalKey) - .ToListAsync()) - .Select(BanData.FromBan); - - // Collect statistics - var fields = new List - { - new EmbedField("Server bans", bans.Count(x => x.Type == BanType.Server).ToString(), true), - new EmbedField("Job bans", bans.Count(x => x.Type == BanType.Job).ToString(), true), - new EmbedField("Active bans", bans.Count(x => x.Active).ToString(), true) - }; - - // Generate embed to relay the information - var embed = new Embed("Search Results", - Colour: _feedback.Theme.Success, - Description: - $"Found the following details when searching for ``{key}``. You may be interested in viewing the " + - $"full details of the bans on [CentCom](https://centcom.melonmesa.com/viewer/view/{key}), or viewing " + - $"their /tg/ activity on [Scrubby](https://scrubby.melonmesa.com/ckey/{key}).", - Fields: fields, - Timestamp: DateTimeOffset.UtcNow, - Footer: new EmbedFooter($"{AssemblyInformation.Current.Version} ({AssemblyInformation.Current.Commit[..7]})")); - - return await _feedback.SendContextualEmbedAsync(embed); - } -} \ No newline at end of file diff --git a/CentCom.Bot/Configuration/DiscordConfiguration.cs b/CentCom.Bot/Configuration/DiscordConfiguration.cs deleted file mode 100644 index 7e69ecc..0000000 --- a/CentCom.Bot/Configuration/DiscordConfiguration.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace CentCom.Bot.Configuration; - -public class DiscordConfiguration -{ - public string Token { get; set; } - - public ulong? FailureChannel { get; set; } - - public ulong? FailureMention { get; set; } -} \ No newline at end of file diff --git a/CentCom.Bot/Jobs/FailedParseJob.cs b/CentCom.Bot/Jobs/FailedParseJob.cs deleted file mode 100644 index f261afb..0000000 --- a/CentCom.Bot/Jobs/FailedParseJob.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CentCom.Bot.Configuration; -using CentCom.Common.Data; -using CentCom.Common.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; -using OneOf; -using Quartz; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Discord.API.Abstractions.Rest; -using Remora.Rest.Core; - -namespace CentCom.Bot.Jobs; - -[DisallowConcurrentExecution] -public class FailedParseJob : IJob -{ - private readonly IDiscordRestChannelAPI _channelAPI; - private readonly IOptions _config; - private readonly DatabaseContext _dbContext; - - public FailedParseJob(DatabaseContext dbContext, IOptions config, - IDiscordRestChannelAPI channelAPI) - { - _dbContext = dbContext; - _channelAPI = channelAPI; - _config = config; - } - - public async Task Execute(IJobExecutionContext context) - { - var failures = await _dbContext.CheckHistory - .Include(x => x.Notification) - .Where(x => !x.Success && x.Notification == null) - .ToListAsync(); - if (failures.Count == 0) - return; - - if (_config.Value == null) - throw new Exception("Missing or invalid Discord configuration, cannot dispatch failure notifications"); - - // Don't bother if we haven't configured a channel to use - if (_config.Value.FailureChannel == null) - return; - - // Get channel, check it exists - var channelRequest = await _channelAPI.GetChannelAsync(new Snowflake(_config.Value.FailureChannel.Value)); - if (!channelRequest.IsSuccess || channelRequest.Entity == null) - throw new Exception("Failed to get Discord channel to dispatch parse failure notifications into."); - - var notified = new List(); - var channel = channelRequest.Entity; - foreach (var failure in failures) - { - // Attach text content of response where available - FileData fileData = null; - var messageSuffix = "The content of the response was missing or empty."; - if (failure.ResponseContent != null) - { - var dataStream = new MemoryStream(); - var writer = new StreamWriter(dataStream); - await writer.WriteAsync(failure.ResponseContent); - dataStream.Seek(0, SeekOrigin.Begin); - fileData = new FileData("response_content.txt", dataStream); - messageSuffix = "The content of the response is attached to this message."; - } - - var message = new StringBuilder(); - if (_config.Value.FailureMention.HasValue) - message.Append($"<@{_config.Value.FailureMention}> "); - message.Append( - $"Failed to parse bans for {failure.Parser} at , exception is as follows... ```"); - - // Ensure that our length fits - var currLength = message.Length + failure.Exception.Length + messageSuffix.Length + 3; - message.Append(currLength > 2000 - ? $"{failure.Exception[..^(currLength - 2000 + 4)]}...```" - : $"{failure.Exception}```"); - - // Add suffix - message.Append(messageSuffix); - - // Try to send, only mark completed if successful - var attachments = new List> { fileData }; - var result = await _channelAPI.CreateMessageAsync(channel.ID, message.ToString(), - attachments: attachments); - if (result.IsSuccess) - notified.Add(new NotifiedFailure - { - CheckHistory = failure, - Timestamp = DateTimeOffset.UtcNow - }); - } - - _dbContext.NotifiedFailures.AddRange(notified); - await _dbContext.SaveChangesAsync(); - } -} \ No newline at end of file diff --git a/CentCom.Bot/Program.cs b/CentCom.Bot/Program.cs deleted file mode 100644 index 4271d0c..0000000 --- a/CentCom.Bot/Program.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Threading.Tasks; -using CentCom.Bot.Commands; -using CentCom.Bot.Configuration; -using CentCom.Bot.Jobs; -using CentCom.Bot.Responders; -using CentCom.Common.Configuration; -using CentCom.Common.Data; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Quartz; -using Remora.Commands.Extensions; -using Remora.Discord.Commands.Extensions; -using Remora.Discord.Gateway.Extensions; -using Remora.Discord.Hosting.Extensions; -using Serilog; - -namespace CentCom.Bot; - -public class Program -{ - public static Task Main(string[] args) - { - // Setup Serilog - Log.Logger = new LoggerConfiguration() - .Enrich.FromLogContext() - .WriteTo.Logger(lc => - { - lc.Filter.ByExcluding( - "Contains(SourceContext, 'Quartz') and (@Level = 'Information')"); - lc.WriteTo.Console( - outputTemplate: - "[{Timestamp:HH:mm:ss} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}"); - }) - .WriteTo.Logger(lc => - { - lc.WriteTo.File(path: "centcom-discord-bot.txt", - outputTemplate: - "[{Timestamp:HH:mm:ss} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}"); - }) - .CreateLogger(); - - return CreateHostBuilder(args).RunConsoleAsync(); - } - - private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .AddDiscordService(services => - { - var configuration = services.GetRequiredService(); - return configuration.GetValue("discord:token") ?? - throw new InvalidOperationException - ( - "Failed to read Discord configuration, bot token not found in appsettings.json." - ); - }) - .ConfigureServices((_, services) => - { - // Add configuration - var config = new ConfigurationBuilder() - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false) - .AddCommandLine(args) - .AddUserSecrets() - .Build(); - services.AddSingleton(config); - - // Add Discord config - services.AddOptions() - .Bind(config.GetSection("discord")) - .Validate(x => x.Token != null); - - // Get DB configuration - var dbConfig = new DbConfig(); - config.Bind("dbConfig", dbConfig); - - // Add appropriate DB context - if (dbConfig == null) - { - throw new Exception( - "Failed to read DB configuration, please ensure you provide one in appsettings.json"); - } - - switch (dbConfig.DbType) - { - case DbType.Postgres: - services.AddDbContext(); - break; - case DbType.MariaDB: - services.AddDbContext(); - break; - case DbType.MySql: - services.AddDbContext(); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - // Add Quartz - services.AddQuartz(q => - { - q.UseMicrosoftDependencyInjectionJobFactory(); - - q.ScheduleJob(trigger => - trigger - .StartNow() - .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever()), - job => job.WithIdentity("failed-parse")); - }); - services.AddQuartzHostedService(); - - // Add Quartz jobs - services.AddTransient(); - - // Add Discord commands - services - .AddDiscordCommands(true) - .AddCommandTree() - .WithCommandGroup() - .WithCommandGroup() - .Finish() - .AddResponder(); - }) - .UseSerilog(); -} \ No newline at end of file diff --git a/CentCom.Bot/Responders/ServerJoinResponder.cs b/CentCom.Bot/Responders/ServerJoinResponder.cs deleted file mode 100644 index fe09543..0000000 --- a/CentCom.Bot/Responders/ServerJoinResponder.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Remora.Discord.API.Abstractions.Gateway.Events; -using Remora.Discord.Commands.Services; -using Remora.Discord.Gateway.Responders; -using Remora.Results; - -namespace CentCom.Bot.Responders; - -public class ServerJoinResponder : IResponder -{ - private readonly ILogger _logger; - private readonly SlashService _slash; - - public ServerJoinResponder(ILogger logger, SlashService slash) - { - _slash = slash; - _logger = logger; - } - - public async Task RespondAsync(IGuildCreate gatewayEvent, - CancellationToken ct = new CancellationToken()) - { - var slashSupport = _slash.SupportsSlashCommands(); - if (!slashSupport.IsSuccess) - { - _logger.LogWarning("The registered commands of the bot don't support slash commands: {Reason}", - slashSupport.Error?.Message); - return Result.FromError(slashSupport.Error); - } - - var update = await _slash.UpdateSlashCommandsAsync(gatewayEvent.ID, ct: ct); - if (!update.IsSuccess) - { - _logger.LogWarning("Failed to update slash commands: {Reason}", update.Error?.Message); - return Result.FromError(update.Error); - } - - return Result.FromSuccess(); - } -} \ No newline at end of file diff --git a/CentCom.Bot/appsettings.json b/CentCom.Bot/appsettings.json deleted file mode 100644 index 0cc51b9..0000000 --- a/CentCom.Bot/appsettings.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "dbConfig": { - "connectionString": "connection_string_goes_here", - "dbType": "db_type_goes_here" - }, - "discord": { - "token": null, - "failureChannel": 0, - "failureMention": 0 - } -} \ No newline at end of file diff --git a/CentCom.Common/Abstract/IRestBan.cs b/CentCom.Common/Abstract/IRestBan.cs index 752b07f..cb02247 100644 --- a/CentCom.Common/Abstract/IRestBan.cs +++ b/CentCom.Common/Abstract/IRestBan.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using CentCom.Common.Models; -using Remora.Rest.Core; namespace CentCom.Common.Abstract; @@ -58,5 +58,6 @@ public interface IRestBan /// /// The optional Round ID of the ban, if present /// - public Optional RoundId { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? RoundId { get; } } \ No newline at end of file diff --git a/CentCom.Common/CentCom.Common.csproj b/CentCom.Common/CentCom.Common.csproj index 24f4a72..9307a2d 100644 --- a/CentCom.Common/CentCom.Common.csproj +++ b/CentCom.Common/CentCom.Common.csproj @@ -1,19 +1,19 @@  - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/CentCom.Common/Data/DatabaseContext.cs b/CentCom.Common/Data/DatabaseContext.cs index fa2f563..c1a0313 100644 --- a/CentCom.Common/Data/DatabaseContext.cs +++ b/CentCom.Common/Data/DatabaseContext.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading; using System.Threading.Tasks; using CentCom.Common.Models; diff --git a/CentCom.Common/Models/Rest/RestBan.cs b/CentCom.Common/Models/Rest/RestBan.cs index f87a01b..ca8034c 100644 --- a/CentCom.Common/Models/Rest/RestBan.cs +++ b/CentCom.Common/Models/Rest/RestBan.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using CentCom.Common.Abstract; -using Remora.Rest.Core; namespace CentCom.Common.Models.Rest; @@ -16,5 +15,5 @@ public record RestBan DateTimeOffset? Expires, ICKey UnbannedBy, IReadOnlyList JobBans, - Optional RoundId + int? RoundId ) : IRestBan; \ No newline at end of file diff --git a/CentCom.Exporter/CentCom.Exporter.csproj b/CentCom.Exporter/CentCom.Exporter.csproj index 22e7161..4aa648d 100644 --- a/CentCom.Exporter/CentCom.Exporter.csproj +++ b/CentCom.Exporter/CentCom.Exporter.csproj @@ -5,9 +5,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CentCom.Exporter/Data/Ban/ParadiseExportedBan.cs b/CentCom.Exporter/Data/Ban/ParadiseExportedBan.cs index 6575d7c..3f56e10 100644 --- a/CentCom.Exporter/Data/Ban/ParadiseExportedBan.cs +++ b/CentCom.Exporter/Data/Ban/ParadiseExportedBan.cs @@ -1,6 +1,4 @@ -using System; -using CentCom.Common.Models; -using CentCom.Common.Models.Byond; +using CentCom.Common.Models; using CentCom.Common.Models.Rest; namespace CentCom.Exporter.Data.Ban; diff --git a/CentCom.Exporter/Data/Clustering/IBanClusterer.cs b/CentCom.Exporter/Data/Clustering/IBanClusterer.cs index 1d71785..64227e5 100644 --- a/CentCom.Exporter/Data/Clustering/IBanClusterer.cs +++ b/CentCom.Exporter/Data/Clustering/IBanClusterer.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; -using System.Linq; using CentCom.Common.Abstract; -using CentCom.Common.Models; -using CentCom.Common.Models.Rest; namespace CentCom.Exporter.Data.Clustering; diff --git a/CentCom.Server/CentCom.Server.csproj b/CentCom.Server/CentCom.Server.csproj index 5e6b5cd..08e147f 100644 --- a/CentCom.Server/CentCom.Server.csproj +++ b/CentCom.Server/CentCom.Server.csproj @@ -10,34 +10,33 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - + + + + + + + + + + diff --git a/CentCom.Server/Services/FulpBanService.cs b/CentCom.Server/Services/FulpBanService.cs index 77db63e..133a52f 100644 --- a/CentCom.Server/Services/FulpBanService.cs +++ b/CentCom.Server/Services/FulpBanService.cs @@ -16,19 +16,25 @@ namespace CentCom.Server.Services; public class FulpBanService : RestBanService { + private readonly bool _allowExpiredSsl; private const int RecordsPerPage = 50; private static readonly BanSource BanSource = new BanSource { Name = "fulp" }; public FulpBanService(ILogger logger, IConfiguration config) : base(logger) { - if (config.GetSection("sourceConfig").GetValue("allowFulpExpiredSSL")) - { - Client.Options.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyError) => true; - } + _allowExpiredSsl = config.GetSection("sourceConfig").GetValue("allowFulpExpiredSSL"); } protected override string BaseUrl => "https://api.fulp.gg/"; + protected override RestClientOptions GenerateClientOptions() + { + var baseOptions = base.GenerateClientOptions(); + if (_allowExpiredSsl) + baseOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyError) => true; + return baseOptions; + } + public async Task> GetBansAsync(int page = 1) { var request = new RestRequest($"bans/{RecordsPerPage}/{page}"); diff --git a/CentCom.Server/Services/RestBanService.cs b/CentCom.Server/Services/RestBanService.cs index 1a8570e..47ecad2 100644 --- a/CentCom.Server/Services/RestBanService.cs +++ b/CentCom.Server/Services/RestBanService.cs @@ -30,25 +30,26 @@ protected void FailedRequest(RestResponse response) messageBuilder.Append($"\n\tResponse URL: \"{response.ResponseUri}\""); messageBuilder.Append($"\n\tRequest URL: \"{url}\""); var message = messageBuilder.ToString(); - + // Log error as appropriate _logger.LogError(message); throw new BanSourceUnavailableException(message, response.Content); } - protected void InitializeClient() + protected void InitializeClient(ConfigureSerialization configureSerialization = null) { if (BaseUrl == null) return; - - var options = new RestClientOptions(BaseUrl) + + Client = new RestClient(GenerateClientOptions(), configureSerialization: configureSerialization); + } + + protected virtual RestClientOptions GenerateClientOptions() => + new(BaseUrl) { // Setup user agent UserAgent = $"Mozilla/5.0 (compatible; CentComBot/{Assembly.GetExecutingAssembly().GetName().Version}; +https://centcom.melonmesa.com/scraper)" }; - - Client = new RestClient(options); - } } \ No newline at end of file diff --git a/CentCom.Server/Services/StandardProviderService.cs b/CentCom.Server/Services/StandardProviderService.cs index 5349e23..d57dfde 100644 --- a/CentCom.Server/Services/StandardProviderService.cs +++ b/CentCom.Server/Services/StandardProviderService.cs @@ -88,16 +88,15 @@ public void Configure(StandardProviderConfiguration config) _configured = true; _baseUrl = config.Url; Source = new BanSource { Name = config.Id, Display = config.Display, RoleplayLevel = config.RoleplayLevel }; - - // Re-initialize client with new url - InitializeClient(); - + // Setup JSON for client var options = new JsonSerializerOptions(); options.AddCentComOptions(); options.AddDataObjectConverter(); options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.Converters.Insert(0, new JsonStringEnumConverter()); - Client.UseSystemTextJson(options); + + // Re-initialize client with new url + InitializeClient(o => o.UseSystemTextJson(options)); } } \ No newline at end of file diff --git a/CentCom.Server/Services/TgBanService.cs b/CentCom.Server/Services/TgBanService.cs index e175d02..62fcb8d 100644 --- a/CentCom.Server/Services/TgBanService.cs +++ b/CentCom.Server/Services/TgBanService.cs @@ -20,11 +20,12 @@ public class TgBanService : RestBanService public TgBanService(ILogger logger) : base(logger) { - Client.UseSystemTextJson(new JsonSerializerOptions + // Re-initialize to control JSON serialization behaviour + InitializeClient(o =>o.UseSystemTextJson(new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter() } - }); + })); } protected override string BaseUrl => "https://tgstation13.org/"; diff --git a/CentCom.Test/CentCom.Test.csproj b/CentCom.Test/CentCom.Test.csproj index 2a8d3ef..92c20db 100644 --- a/CentCom.Test/CentCom.Test.csproj +++ b/CentCom.Test/CentCom.Test.csproj @@ -9,17 +9,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CentCom.Test/RestBanTests.cs b/CentCom.Test/RestBanTests.cs index e5f93f4..557cd53 100644 --- a/CentCom.Test/RestBanTests.cs +++ b/CentCom.Test/RestBanTests.cs @@ -51,9 +51,7 @@ public void CanSerializeBan() Assert.NotNull(deserialized); } - private static JsonSerializerOptions GetOptions() - { - return (new ServiceCollection()).AddCentComSerialization().BuildServiceProvider() - .GetRequiredService>().Value; - } + private static JsonSerializerOptions GetOptions() => + new ServiceCollection().AddCentComSerialization().BuildServiceProvider() + .GetRequiredService>().Value; } \ No newline at end of file diff --git a/CentCom.sln b/CentCom.sln index d60b326..a90b0da 100644 --- a/CentCom.sln +++ b/CentCom.sln @@ -18,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CentCom.Bot", "CentCom.Bot\CentCom.Bot.csproj", "{A99A54D9-F216-45EA-9758-1092C82CEC57}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CentCom.Exporter", "CentCom.Exporter\CentCom.Exporter.csproj", "{F3B6E80D-A12F-4D26-8E7A-1A5A3D6E50AF}" EndProject Global @@ -44,10 +42,6 @@ Global {B4A8FED4-ED2C-471B-9F07-A72B0E80E089}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4A8FED4-ED2C-471B-9F07-A72B0E80E089}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4A8FED4-ED2C-471B-9F07-A72B0E80E089}.Release|Any CPU.Build.0 = Release|Any CPU - {A99A54D9-F216-45EA-9758-1092C82CEC57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A99A54D9-F216-45EA-9758-1092C82CEC57}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A99A54D9-F216-45EA-9758-1092C82CEC57}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A99A54D9-F216-45EA-9758-1092C82CEC57}.Release|Any CPU.Build.0 = Release|Any CPU {F3B6E80D-A12F-4D26-8E7A-1A5A3D6E50AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F3B6E80D-A12F-4D26-8E7A-1A5A3D6E50AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {F3B6E80D-A12F-4D26-8E7A-1A5A3D6E50AF}.Release|Any CPU.ActiveCfg = Release|Any CPU