Address Rider inspections

This commit is contained in:
chylex 2022-02-21 00:05:25 +01:00
parent 849ef18adb
commit 4dc781b35c
No known key found for this signature in database
GPG Key ID: 4DE42C8F19A80548
64 changed files with 126 additions and 128 deletions

View File

@ -4,7 +4,7 @@ using Avalonia.Markup.Xaml;
using DHT.Desktop.Main;
namespace DHT.Desktop {
public class App : Application {
sealed class App : Application {
public override void Initialize() {
AvaloniaXamlLoader.Load(this);
}

View File

@ -2,7 +2,7 @@ using System;
using DHT.Utils.Logging;
namespace DHT.Desktop {
public class Arguments {
sealed class Arguments {
private static readonly Log Log = Log.ForType<Arguments>();
public static Arguments Empty => new(Array.Empty<string>());

View File

@ -10,7 +10,7 @@ using DHT.Server.Database.Sqlite;
using DHT.Utils.Logging;
namespace DHT.Desktop.Common {
public static class DatabaseGui {
static class DatabaseGui {
private static readonly Log Log = Log.ForType(typeof(DatabaseGui));
private const string DatabaseFileInitialName = "archive.dht";

View File

@ -3,7 +3,7 @@ using System.Globalization;
using Avalonia.Data.Converters;
namespace DHT.Desktop.Common {
public class NumberValueConverter : IValueConverter {
sealed class NumberValueConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return string.Format(Program.Culture, "{0:n0}", value);
}

View File

@ -1,5 +1,5 @@
namespace DHT.Desktop.Common {
public static class TextFormat {
static class TextFormat {
public static string Format(this int number) {
return number.ToString("N0", Program.Culture);
}

View File

@ -5,7 +5,7 @@ using Avalonia.Markup.Xaml;
using DHT.Desktop.Dialogs.Message;
namespace DHT.Desktop.Dialogs.CheckBox {
public class CheckBoxDialog : Window {
sealed class CheckBoxDialog : Window {
public CheckBoxDialog() {
InitializeComponent();
#if DEBUG

View File

@ -5,7 +5,7 @@ using System.Linq;
using DHT.Utils.Models;
namespace DHT.Desktop.Dialogs.CheckBox {
public class CheckBoxDialogModel : BaseModel {
class CheckBoxDialogModel : BaseModel {
public string Title { get; init; } = "";
private IReadOnlyList<CheckBoxItem> items = Array.Empty<CheckBoxItem>();
@ -28,8 +28,8 @@ namespace DHT.Desktop.Dialogs.CheckBox {
private bool pauseCheckEvents = false;
public bool AreAllSelected => Items.All(item => item.Checked);
public bool AreNoneSelected => Items.All(item => !item.Checked);
public bool AreAllSelected => Items.All(static item => item.Checked);
public bool AreNoneSelected => Items.All(static item => !item.Checked);
public void SelectAll() => SetAllChecked(true);
public void SelectNone() => SetAllChecked(false);
@ -57,10 +57,10 @@ namespace DHT.Desktop.Dialogs.CheckBox {
}
}
public class CheckBoxDialogModel<T> : CheckBoxDialogModel {
sealed class CheckBoxDialogModel<T> : CheckBoxDialogModel {
public new IReadOnlyList<CheckBoxItem<T>> Items { get; }
public IEnumerable<CheckBoxItem<T>> SelectedItems => Items.Where(item => item.Checked);
public IEnumerable<CheckBoxItem<T>> SelectedItems => Items.Where(static item => item.Checked);
public CheckBoxDialogModel(IEnumerable<CheckBoxItem<T>> items) {
this.Items = new List<CheckBoxItem<T>>(items);

View File

@ -1,7 +1,7 @@
using DHT.Utils.Models;
namespace DHT.Desktop.Dialogs.CheckBox {
public class CheckBoxItem : BaseModel {
class CheckBoxItem : BaseModel {
public string Title { get; init; } = "";
public object? Item { get; init; } = null;
@ -13,7 +13,7 @@ namespace DHT.Desktop.Dialogs.CheckBox {
}
}
public class CheckBoxItem<T> : CheckBoxItem {
sealed class CheckBoxItem<T> : CheckBoxItem {
public new T Item { get; }
public CheckBoxItem(T item) {

View File

@ -3,7 +3,7 @@ using Avalonia.Controls;
using Avalonia.Threading;
namespace DHT.Desktop.Dialogs.Message {
public static class Dialog {
static class Dialog {
public static async Task ShowOk(Window owner, string title, string message) {
if (!Dispatcher.UIThread.CheckAccess()) {
await Dispatcher.UIThread.InvokeAsync(() => ShowOk(owner, title, message));

View File

@ -1,7 +1,7 @@
using System;
namespace DHT.Desktop.Dialogs.Message {
public static class DialogResult {
static class DialogResult {
public enum All {
Ok,
Yes,

View File

@ -4,7 +4,7 @@ using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Dialogs.Message {
public class MessageDialog : Window {
sealed class MessageDialog : Window {
public MessageDialog() {
InitializeComponent();
#if DEBUG

View File

@ -1,5 +1,5 @@
namespace DHT.Desktop.Dialogs.Message {
public class MessageDialogModel {
sealed class MessageDialogModel {
public string Title { get; init; } = "";
public string Message { get; init; } = "";

View File

@ -1,7 +1,7 @@
using System.Threading.Tasks;
namespace DHT.Desktop.Dialogs.Progress {
public interface IProgressCallback {
interface IProgressCallback {
Task Update(string message, int finishedItems, int totalItems);
}
}

View File

@ -6,7 +6,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Dialogs.Progress {
public class ProgressDialog : Window {
sealed class ProgressDialog : Window {
private bool isFinished = false;
public ProgressDialog() {

View File

@ -5,7 +5,7 @@ using DHT.Desktop.Common;
using DHT.Utils.Models;
namespace DHT.Desktop.Dialogs.Progress {
public class ProgressDialogModel : BaseModel {
sealed class ProgressDialogModel : BaseModel {
public string Title { get; init; } = "";
private string message = "";
@ -46,7 +46,7 @@ namespace DHT.Desktop.Dialogs.Progress {
public delegate Task TaskRunner(IProgressCallback callback);
private class Callback : IProgressCallback {
private sealed class Callback : IProgressCallback {
private readonly ProgressDialogModel model;
public Callback(ProgressDialogModel model) {

View File

@ -3,7 +3,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main {
public class AboutWindow : Window {
sealed class AboutWindow : Window {
public AboutWindow() {
InitializeComponent();
#if DEBUG

View File

@ -1,7 +1,7 @@
using System.Diagnostics;
namespace DHT.Desktop.Main {
public class AboutWindowModel {
sealed class AboutWindowModel {
public void ShowOfficialWebsite() {
OpenUrl("https://dht.chylex.com");
}

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main.Controls {
public class FilterPanel : UserControl {
sealed class FilterPanel : UserControl {
private CalendarDatePicker StartDatePicker => this.FindControl<CalendarDatePicker>("StartDatePicker");
private CalendarDatePicker EndDatePicker => this.FindControl<CalendarDatePicker>("EndDatePicker");

View File

@ -14,7 +14,7 @@ using DHT.Server.Database;
using DHT.Utils.Models;
namespace DHT.Desktop.Main.Controls {
public class FilterPanelModel : BaseModel {
sealed class FilterPanelModel : BaseModel {
private static readonly HashSet<string> FilterProperties = new () {
nameof(FilterByDate),
nameof(StartDate),
@ -58,7 +58,7 @@ namespace DHT.Desktop.Main.Controls {
}
public HashSet<ulong> IncludedChannels {
get => includedChannels ?? db.GetAllChannels().Select(channel => channel.Id).ToHashSet();
get => includedChannels ?? db.GetAllChannels().Select(static channel => channel.Id).ToHashSet();
set => Change(ref includedChannels, value);
}
@ -68,7 +68,7 @@ namespace DHT.Desktop.Main.Controls {
}
public HashSet<ulong> IncludedUsers {
get => includedUsers ?? db.GetAllUsers().Select(user => user.Id).ToHashSet();
get => includedUsers ?? db.GetAllUsers().Select(static user => user.Id).ToHashSet();
set => Change(ref includedUsers, value);
}
@ -126,7 +126,7 @@ namespace DHT.Desktop.Main.Controls {
}
public async void OpenChannelFilterDialog() {
var servers = db.GetAllServers().ToDictionary(server => server.Id);
var servers = db.GetAllServers().ToDictionary(static server => server.Id);
var items = new List<CheckBoxItem<ulong>>();
var included = IncludedChannels;
@ -222,7 +222,7 @@ namespace DHT.Desktop.Main.Controls {
}
private static async Task<HashSet<ulong>?> OpenIdFilterDialog(Window window, string title, List<CheckBoxItem<ulong>> items) {
items.Sort((item1, item2) => item1.Title.CompareTo(item2.Title));
items.Sort(static (item1, item2) => item1.Title.CompareTo(item2.Title));
var model = new CheckBoxDialogModel<ulong>(items) {
Title = title
@ -231,7 +231,7 @@ namespace DHT.Desktop.Main.Controls {
var dialog = new CheckBoxDialog { DataContext = model };
var result = await dialog.ShowDialog<DialogResult.OkCancel>(window);
return result == DialogResult.OkCancel.Ok ? model.SelectedItems.Select(item => item.Item).ToHashSet() : null;
return result == DialogResult.OkCancel.Ok ? model.SelectedItems.Select(static item => item.Item).ToHashSet() : null;
}
}
}

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main.Controls {
public class StatusBar : UserControl {
sealed class StatusBar : UserControl {
public StatusBar() {
InitializeComponent();
}

View File

@ -3,7 +3,7 @@ using DHT.Server.Database;
using DHT.Utils.Models;
namespace DHT.Desktop.Main.Controls {
public class StatusBarModel : BaseModel {
sealed class StatusBarModel : BaseModel {
public DatabaseStatistics DatabaseStatistics { get; }
private Status status = Status.Stopped;

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main {
public class MainContentScreen : UserControl {
sealed class MainContentScreen : UserControl {
public MainContentScreen() {
InitializeComponent();
}

View File

@ -6,7 +6,7 @@ using DHT.Server.Database;
using DHT.Server.Service;
namespace DHT.Desktop.Main {
public class MainContentScreenModel : IDisposable {
sealed class MainContentScreenModel : IDisposable {
public DatabasePage DatabasePage { get; }
private DatabasePageModel DatabasePageModel { get; }
@ -19,8 +19,12 @@ namespace DHT.Desktop.Main {
public StatusBarModel StatusBarModel { get; }
public event EventHandler? DatabaseClosed {
add { DatabasePageModel.DatabaseClosed += value; }
remove { DatabasePageModel.DatabaseClosed -= value; }
add {
DatabasePageModel.DatabaseClosed += value;
}
remove {
DatabasePageModel.DatabaseClosed -= value;
}
}
[Obsolete("Designer")]
@ -51,7 +55,6 @@ namespace DHT.Desktop.Main {
public void Dispose() {
TrackingPageModel.Dispose();
GC.SuppressFinalize(this);
}
}
}

View File

@ -4,7 +4,7 @@ using Avalonia.Markup.Xaml;
using JetBrains.Annotations;
namespace DHT.Desktop.Main {
public class MainWindow : Window {
sealed class MainWindow : Window {
[UsedImplicitly]
public MainWindow() {
InitializeComponent(Arguments.Empty);

View File

@ -10,7 +10,7 @@ using DHT.Server.Database;
using DHT.Utils.Models;
namespace DHT.Desktop.Main {
public class MainWindowModel : BaseModel {
sealed class MainWindowModel : BaseModel {
private const string DefaultTitle = "Discord History Tracker";
public string Title { get; private set; } = DefaultTitle;

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main.Pages {
public class DatabasePage : UserControl {
sealed class DatabasePage : UserControl {
public DatabasePage() {
InitializeComponent();
}

View File

@ -13,7 +13,7 @@ using DHT.Utils.Logging;
using DHT.Utils.Models;
namespace DHT.Desktop.Main.Pages {
public class DatabasePageModel : BaseModel {
sealed class DatabasePageModel : BaseModel {
private static readonly Log Log = Log.ForType<DatabasePageModel>();
public IDatabaseFile Db { get; }

View File

@ -5,7 +5,7 @@ using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main.Pages {
public class TrackingPage : UserControl {
sealed class TrackingPage : UserControl {
private bool isCopyingScript;
public TrackingPage() {

View File

@ -12,7 +12,7 @@ using DHT.Utils.Models;
using static DHT.Desktop.Program;
namespace DHT.Desktop.Main.Pages {
public class TrackingPageModel : BaseModel, IDisposable {
sealed class TrackingPageModel : BaseModel, IDisposable {
private static readonly Log Log = Log.ForType<TrackingPageModel>();
internal static string ServerPort { get; set; } = ServerUtils.FindAvailablePort(50000, 60000).ToString();
@ -76,7 +76,6 @@ namespace DHT.Desktop.Main.Pages {
ServerLauncher.ServerManagementExceptionCaught -= ServerLauncherOnServerManagementExceptionCaught;
ServerLauncher.ServerStatusChanged -= ServerLauncherOnServerStatusChanged;
ServerLauncher.Stop();
GC.SuppressFinalize(this);
}
private async Task<bool> StartServer() {

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main.Pages {
public class ViewerPage : UserControl {
sealed class ViewerPage : UserControl {
public ViewerPage() {
InitializeComponent();
}

View File

@ -16,7 +16,7 @@ using DHT.Utils.Models;
using static DHT.Desktop.Program;
namespace DHT.Desktop.Main.Pages {
public class ViewerPageModel : BaseModel {
sealed class ViewerPageModel : BaseModel {
public string ExportedMessageText { get; private set; } = "";
public bool DatabaseToolFilterModeKeep { get; set; } = true;

View File

@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DHT.Desktop.Main {
public class WelcomeScreen : UserControl {
sealed class WelcomeScreen : UserControl {
public WelcomeScreen() {
InitializeComponent();
}

View File

@ -8,7 +8,7 @@ using DHT.Server.Database;
using DHT.Utils.Models;
namespace DHT.Desktop.Main {
public class WelcomeScreenModel : BaseModel {
sealed class WelcomeScreenModel : BaseModel {
public string Version => Program.Version;
public IDatabaseFile? Db { get; private set; }

View File

@ -4,7 +4,7 @@ using Avalonia;
using DHT.Utils.Resources;
namespace DHT.Desktop {
internal static class Program {
static class Program {
public static string Version { get; }
public static CultureInfo Culture { get; }
public static ResourceLoader Resources { get; }

View File

@ -1,9 +1,9 @@
namespace DHT.Server.Data {
public readonly struct Attachment {
public ulong Id { get; init; }
public string Name { get; init; }
public string? Type { get; init; }
public string Url { get; init; }
public ulong Size { get; init; }
public ulong Id { get; internal init; }
public string Name { get; internal init; }
public string? Type { get; internal init; }
public string Url { get; internal init; }
public ulong Size { get; internal init; }
}
}

View File

@ -1,11 +1,11 @@
namespace DHT.Server.Data {
public readonly struct Channel {
public ulong Id { get; init; }
public ulong Server { get; init; }
public string Name { get; init; }
public ulong? ParentId { get; init; }
public int? Position { get; init; }
public string? Topic { get; init; }
public bool? Nsfw { get; init; }
public ulong Id { get; internal init; }
public ulong Server { get; internal init; }
public string Name { get; internal init; }
public ulong? ParentId { get; internal init; }
public int? Position { get; internal init; }
public string? Topic { get; internal init; }
public bool? Nsfw { get; internal init; }
}
}

View File

@ -1,5 +1,5 @@
namespace DHT.Server.Data {
public readonly struct Embed {
public string Json { get; init; }
public string Json { get; internal init; }
}
}

View File

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
namespace DHT.Server.Data.Filters {
public class MessageFilter {
public sealed class MessageFilter {
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }

View File

@ -2,15 +2,15 @@ using System.Collections.Immutable;
namespace DHT.Server.Data {
public readonly struct Message {
public ulong Id { get; init; }
public ulong Sender { get; init; }
public ulong Channel { get; init; }
public string Text { get; init; }
public long Timestamp { get; init; }
public long? EditTimestamp { get; init; }
public ulong? RepliedToId { get; init; }
public ImmutableArray<Attachment> Attachments { get; init; }
public ImmutableArray<Embed> Embeds { get; init; }
public ImmutableArray<Reaction> Reactions { get; init; }
public ulong Id { get; internal init; }
public ulong Sender { get; internal init; }
public ulong Channel { get; internal init; }
public string Text { get; internal init; }
public long Timestamp { get; internal init; }
public long? EditTimestamp { get; internal init; }
public ulong? RepliedToId { get; internal init; }
public ImmutableArray<Attachment> Attachments { get; internal init; }
public ImmutableArray<Embed> Embeds { get; internal init; }
public ImmutableArray<Reaction> Reactions { get; internal init; }
}
}

View File

@ -1,8 +1,8 @@
namespace DHT.Server.Data {
public readonly struct Reaction {
public ulong? EmojiId { get; init; }
public string? EmojiName { get; init; }
public EmojiFlags EmojiFlags { get; init; }
public int Count { get; init; }
public ulong? EmojiId { get; internal init; }
public string? EmojiName { get; internal init; }
public EmojiFlags EmojiFlags { get; internal init; }
public int Count { get; internal init; }
}
}

View File

@ -1,7 +1,7 @@
namespace DHT.Server.Data {
public readonly struct Server {
public ulong Id { get; init; }
public string Name { get; init; }
public ServerType? Type { get; init; }
public ulong Id { get; internal init; }
public string Name { get; internal init; }
public ServerType? Type { get; internal init; }
}
}

View File

@ -24,7 +24,7 @@ namespace DHT.Server.Data {
};
}
public static string ToJsonViewerString(ServerType? type) {
internal static string ToJsonViewerString(ServerType? type) {
return type switch {
ServerType.Server => "server",
ServerType.Group => "group",

View File

@ -1,8 +1,8 @@
namespace DHT.Server.Data {
public readonly struct User {
public ulong Id { get; init; }
public string Name { get; init; }
public string? AvatarUrl { get; init; }
public string? Discriminator { get; init; }
public ulong Id { get; internal init; }
public string Name { get; internal init; }
public string? AvatarUrl { get; internal init; }
public string? Discriminator { get; internal init; }
}
}

View File

@ -2,7 +2,7 @@ using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace DHT.Server.Database {
public class DatabaseStatistics : INotifyPropertyChanged {
public sealed class DatabaseStatistics : INotifyPropertyChanged {
private long totalServers;
private long totalChannels;
private long totalUsers;

View File

@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using DHT.Server.Data;
using DHT.Server.Data.Filters;
namespace DHT.Server.Database {
public class DummyDatabaseFile : IDatabaseFile {
public sealed class DummyDatabaseFile : IDatabaseFile {
public static DummyDatabaseFile Instance { get; } = new();
public string Path => "";
@ -42,8 +41,6 @@ namespace DHT.Server.Database {
public void RemoveMessages(MessageFilter filter, MessageFilterRemovalMode mode) {}
public void Dispose() {
GC.SuppressFinalize(this);
}
public void Dispose() {}
}
}

View File

@ -2,11 +2,11 @@ using System;
using DHT.Server.Database.Sqlite;
namespace DHT.Server.Database.Exceptions {
public class DatabaseTooNewException : Exception {
public sealed class DatabaseTooNewException : Exception {
public int DatabaseVersion { get; }
public int CurrentVersion => Schema.Version;
public DatabaseTooNewException(int databaseVersion) : base("Database is too new: " + databaseVersion + " > " + Schema.Version) {
internal DatabaseTooNewException(int databaseVersion) : base("Database is too new: " + databaseVersion + " > " + Schema.Version) {
this.DatabaseVersion = databaseVersion;
}
}

View File

@ -1,10 +1,10 @@
using System;
namespace DHT.Server.Database.Exceptions {
public class InvalidDatabaseVersionException : Exception {
public sealed class InvalidDatabaseVersionException : Exception {
public string Version { get; }
public InvalidDatabaseVersionException(string version) : base("Invalid database version: " + version) {
internal InvalidDatabaseVersionException(string version) : base("Invalid database version: " + version) {
this.Version = version;
}
}

View File

@ -124,7 +124,7 @@ namespace DHT.Server.Database.Export {
private static dynamic GenerateMessageList(List<Message> includedMessages, Dictionary<ulong, int> userIndices) {
var data = new Dictionary<string, Dictionary<string, dynamic>>();
foreach (var grouping in includedMessages.GroupBy(message => message.Channel)) {
foreach (var grouping in includedMessages.GroupBy(static message => message.Channel)) {
var channel = grouping.Key.ToString();
var channelData = new Dictionary<string, dynamic>();
@ -146,17 +146,17 @@ namespace DHT.Server.Database.Export {
}
if (!message.Attachments.IsEmpty) {
obj.a = message.Attachments.Select(attachment => new {
obj.a = message.Attachments.Select(static attachment => new {
url = attachment.Url
}).ToArray();
}
if (!message.Embeds.IsEmpty) {
obj.e = message.Embeds.Select(embed => embed.Json).ToArray();
obj.e = message.Embeds.Select(static embed => embed.Json).ToArray();
}
if (!message.Reactions.IsEmpty) {
obj.re = message.Reactions.Select(reaction => {
obj.re = message.Reactions.Select(static reaction => {
dynamic r = new ExpandoObject();
if (reaction.EmojiId != null) {

View File

@ -3,7 +3,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
namespace DHT.Server.Database.Export {
public class ViewerJsonSnowflakeSerializer : JsonConverter<ulong> {
sealed class ViewerJsonSnowflakeSerializer : JsonConverter<ulong> {
public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
return ulong.Parse(reader.GetString()!);
}

View File

@ -4,7 +4,7 @@ using DHT.Server.Database.Exceptions;
using Microsoft.Data.Sqlite;
namespace DHT.Server.Database.Sqlite {
internal class Schema {
sealed class Schema {
internal const int Version = 2;
private readonly SqliteConnection conn;

View File

@ -9,7 +9,7 @@ using DHT.Utils.Collections;
using Microsoft.Data.Sqlite;
namespace DHT.Server.Database.Sqlite {
public class SqliteDatabaseFile : IDatabaseFile {
public sealed class SqliteDatabaseFile : IDatabaseFile {
public static async Task<SqliteDatabaseFile?> OpenOrCreate(string path, Func<Task<bool>> checkCanUpgradeSchemas) {
string connectionString = new SqliteConnectionStringBuilder {
DataSource = path,
@ -39,7 +39,6 @@ namespace DHT.Server.Database.Sqlite {
public void Dispose() {
conn.Dispose();
GC.SuppressFinalize(this);
}
public void AddServer(Data.Server server) {

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using DHT.Server.Data.Filters;
namespace DHT.Server.Database.Sqlite {
public static class SqliteMessageFilter {
static class SqliteMessageFilter {
public static string GenerateWhereClause(this MessageFilter? filter, bool invert = false) {
if (filter == null) {
return "";

View File

@ -3,7 +3,7 @@ using System.Linq;
using Microsoft.Data.Sqlite;
namespace DHT.Server.Database.Sqlite {
public static class SqliteUtils {
static class SqliteUtils {
public static SqliteCommand Command(this SqliteConnection conn, string sql) {
var cmd = conn.CreateCommand();
cmd.CommandText = sql;
@ -12,7 +12,7 @@ namespace DHT.Server.Database.Sqlite {
public static SqliteCommand Insert(this SqliteConnection conn, string tableName, string[] columns) {
string columnNames = string.Join(',', columns);
string columnParams = string.Join(',', columns.Select(c => ':' + c));
string columnParams = string.Join(',', columns.Select(static c => ':' + c));
return conn.Command("INSERT INTO " + tableName + " (" + columnNames + ")" +
"VALUES (" + columnParams + ")");
@ -20,8 +20,8 @@ namespace DHT.Server.Database.Sqlite {
public static SqliteCommand Upsert(this SqliteConnection conn, string tableName, string[] columns) {
string columnNames = string.Join(',', columns);
string columnParams = string.Join(',', columns.Select(c => ':' + c));
string columnUpdates = string.Join(',', columns.Skip(1).Select(c => c + " = excluded." + c));
string columnParams = string.Join(',', columns.Select(static c => ':' + c));
string columnUpdates = string.Join(',', columns.Skip(1).Select(static c => c + " = excluded." + c));
return conn.Command("INSERT INTO " + tableName + " (" + columnNames + ")" +
"VALUES (" + columnParams + ")" +

View File

@ -4,12 +4,13 @@ using System.Text.Json;
using System.Threading.Tasks;
using DHT.Server.Database;
using DHT.Server.Service;
using DHT.Utils.Http;
using DHT.Utils.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
namespace DHT.Server.Endpoints {
public abstract class BaseEndpoint {
abstract class BaseEndpoint {
private static readonly Log Log = Log.ForType<BaseEndpoint>();
protected IDatabaseFile Db { get; }

View File

@ -3,12 +3,12 @@ using System.Text.Json;
using System.Threading.Tasks;
using DHT.Server.Data;
using DHT.Server.Database;
using DHT.Server.Json;
using DHT.Server.Service;
using DHT.Utils.Http;
using Microsoft.AspNetCore.Http;
namespace DHT.Server.Endpoints {
public class TrackChannelEndpoint : BaseEndpoint {
sealed class TrackChannelEndpoint : BaseEndpoint {
public TrackChannelEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
protected override async Task<(HttpStatusCode, object?)> Respond(HttpContext ctx) {

View File

@ -7,12 +7,12 @@ using System.Threading.Tasks;
using DHT.Server.Data;
using DHT.Server.Data.Filters;
using DHT.Server.Database;
using DHT.Server.Json;
using DHT.Server.Service;
using DHT.Utils.Http;
using Microsoft.AspNetCore.Http;
namespace DHT.Server.Endpoints {
public class TrackMessagesEndpoint : BaseEndpoint {
sealed class TrackMessagesEndpoint : BaseEndpoint {
public TrackMessagesEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
protected override async Task<(HttpStatusCode, object?)> Respond(HttpContext ctx) {

View File

@ -3,12 +3,12 @@ using System.Text.Json;
using System.Threading.Tasks;
using DHT.Server.Data;
using DHT.Server.Database;
using DHT.Server.Json;
using DHT.Server.Service;
using DHT.Utils.Http;
using Microsoft.AspNetCore.Http;
namespace DHT.Server.Endpoints {
public class TrackUsersEndpoint : BaseEndpoint {
sealed class TrackUsersEndpoint : BaseEndpoint {
public TrackUsersEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
protected override async Task<(HttpStatusCode, object?)> Respond(HttpContext ctx) {

View File

@ -72,7 +72,7 @@ namespace DHT.Server.Service {
void SetKestrelOptions(KestrelServerOptions options) {
options.Limits.MaxRequestBodySize = null;
options.Limits.MinResponseDataRate = null;
options.ListenLocalhost(port, listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
}
Server = WebHost.CreateDefaultBuilder()

View File

@ -1,5 +1,5 @@
namespace DHT.Server.Service {
public struct ServerParameters {
readonly struct ServerParameters {
public string Token { get; init; }
}
}

View File

@ -8,14 +8,14 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace DHT.Server.Service {
public class Startup {
sealed class Startup {
public void ConfigureServices(IServiceCollection services) {
services.Configure<JsonOptions>(options => {
services.Configure<JsonOptions>(static options => {
options.SerializerOptions.NumberHandling = JsonNumberHandling.Strict;
});
services.AddCors(cors => {
cors.AddDefaultPolicy(builder => {
services.AddCors(static cors => {
cors.AddDefaultPolicy(static builder => {
builder.WithOrigins("https://discord.com", "https://discordapp.com").AllowCredentials().AllowAnyMethod().AllowAnyHeader();
});
});

View File

@ -10,8 +10,8 @@ namespace DHT.Server.Service {
public static int FindAvailablePort(int min, int max) {
var properties = IPGlobalProperties.GetIPGlobalProperties();
var occupied = new HashSet<int>();
occupied.UnionWith(properties.GetActiveTcpListeners().Select(tcp => tcp.Port));
occupied.UnionWith(properties.GetActiveTcpConnections().Select(tcp => tcp.LocalEndPoint.Port));
occupied.UnionWith(properties.GetActiveTcpListeners().Select(static tcp => tcp.Port));
occupied.UnionWith(properties.GetActiveTcpConnections().Select(static tcp => tcp.LocalEndPoint.Port));
for (int port = min; port < max; port++) {
if (!occupied.Contains(port)) {

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
namespace DHT.Utils.Collections {
public class MultiDictionary<TKey, TValue> where TKey : notnull {
public sealed class MultiDictionary<TKey, TValue> where TKey : notnull {
private readonly Dictionary<TKey, List<TValue>> dict = new();
public void Add(TKey key, TValue value) {

View File

@ -1,8 +1,8 @@
using System;
using System.Net;
namespace DHT.Server.Service {
public class HttpException : Exception {
namespace DHT.Utils.Http {
public sealed class HttpException : Exception {
public HttpStatusCode StatusCode { get; }
public HttpException(HttpStatusCode statusCode, string message) : base(message) {

View File

@ -1,8 +1,7 @@
using System.Net;
using System.Text.Json;
using DHT.Server.Service;
namespace DHT.Server.Json {
namespace DHT.Utils.Http {
public static class JsonExtensions {
public static bool HasKey(this JsonElement json, string key) {
return json.TryGetProperty(key, out _);