chore: housekeeping — linter & formatter setup

Add .prettierrc.json, .markdownlint.json, .yamllint.yaml, .gitattributes
Run CSharpier, Prettier and markdownlint across the entire codebase.
No logic changes — formatting, using order and line endings only.
This commit is contained in:
2026-05-10 13:01:00 +02:00
parent cd01fa63a1
commit 699d4ede1d
141 changed files with 8833 additions and 5733 deletions
+173 -61
View File
@@ -1,15 +1,14 @@
using System.Buffers;
using System.Collections;
using System.Data.Common;
using Dalamud.Game.Text.SeStringHandling;
using HellionChat.Code;
using HellionChat.Ui;
using HellionChat.Util;
using Dalamud.Game.Text.SeStringHandling;
using MessagePack;
using MessagePack.Formatters;
using MessagePack.Resolvers;
using Microsoft.Data.Sqlite;
using DalamudUtil = Dalamud.Utility.Util;
using Encoding = System.Text.Encoding;
@@ -36,7 +35,11 @@ internal enum PayloadMessagePackType : byte
public class PayloadMessagePackFormatter : IMessagePackFormatter<Payload?>
{
public void Serialize(ref MessagePackWriter writer, Payload? value, MessagePackSerializerOptions options)
public void Serialize(
ref MessagePackWriter writer,
Payload? value,
MessagePackSerializerOptions options
)
{
if (value == null)
{
@@ -100,14 +103,22 @@ public class PayloadMessagePackFormatter : IMessagePackFormatter<Payload?>
public class SeStringMessagePackFormatter : IMessagePackFormatter<SeString?>
{
public void Serialize(ref MessagePackWriter writer, SeString? value, MessagePackSerializerOptions options)
public void Serialize(
ref MessagePackWriter writer,
SeString? value,
MessagePackSerializerOptions options
)
{
options.Resolver.GetFormatter<List<Payload>>()!.Serialize(ref writer, value?.Payloads ?? [], options);
options
.Resolver.GetFormatter<List<Payload>>()!
.Serialize(ref writer, value?.Payloads ?? [], options);
}
public SeString Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
return new SeString(options.Resolver.GetFormatter<List<Payload>>()!.Deserialize(ref reader, options));
return new SeString(
options.Resolver.GetFormatter<List<Payload>>()!.Deserialize(ref reader, options)
);
}
}
@@ -119,8 +130,13 @@ internal class MessageStore : IDisposable
private SqliteConnection Connection { get; set; }
internal static readonly MessagePackSerializerOptions MsgPackOptions = MessagePackSerializerOptions.Standard
.WithResolver(CompositeResolver.Create([new PayloadMessagePackFormatter(), new SeStringMessagePackFormatter()], [StandardResolver.Instance]));
internal static readonly MessagePackSerializerOptions MsgPackOptions =
MessagePackSerializerOptions.Standard.WithResolver(
CompositeResolver.Create(
[new PayloadMessagePackFormatter(), new SeStringMessagePackFormatter()],
[StandardResolver.Instance]
)
);
internal MessageStore(string dbPath)
{
@@ -193,7 +209,8 @@ internal class MessageStore : IDisposable
private void Migrate0()
{
Plugin.Log.Information("Running migration 0: Creating tables");
Connection.Execute(@"
Connection.Execute(
@"
CREATE TABLE IF NOT EXISTS messages (
Id BLOB PRIMARY KEY NOT NULL, -- Guid
Receiver INTEGER NOT NULL, -- uint64 (first bits are always 0)
@@ -210,7 +227,8 @@ internal class MessageStore : IDisposable
CREATE INDEX IF NOT EXISTS idx_messages_receiver ON messages (Receiver);
CREATE INDEX IF NOT EXISTS idx_messages_date ON messages (Date);
");
"
);
SetMigrationVersion(0);
}
@@ -218,10 +236,12 @@ internal class MessageStore : IDisposable
private void Migrate1()
{
Plugin.Log.Information("Running migration 1: Adding Deleted column");
Connection.Execute(@"
Connection.Execute(
@"
-- Migration 1: Add Deleted column
ALTER TABLE messages ADD COLUMN Deleted BOOLEAN NOT NULL DEFAULT false;
");
"
);
SetMigrationVersion(1);
}
@@ -229,11 +249,13 @@ internal class MessageStore : IDisposable
private void Migrate2()
{
Plugin.Log.Information("Running migration 2: Adding Channel generated column");
Connection.Execute(@"
Connection.Execute(
@"
-- Migration 2: Add Channel generated column
ALTER TABLE messages ADD COLUMN Channel INTEGER GENERATED ALWAYS AS (Code & 0x7f) VIRTUAL;
CREATE INDEX IF NOT EXISTS idx_messages_channel ON messages (Channel);
");
"
);
SetMigrationVersion(2);
}
@@ -263,12 +285,15 @@ internal class MessageStore : IDisposable
// user_version was never bumped, just record the version and exit.
if (ColumnExists("messages", "ChatType") && !ColumnExists("messages", "Code"))
{
Plugin.Log.Information("Migration 3: schema already migrated, only bumping user_version");
Plugin.Log.Information(
"Migration 3: schema already migrated, only bumping user_version"
);
SetMigrationVersion(3);
return;
}
Connection.Execute(@"
Connection.Execute(
@"
-- Migration 3: Fix log kinds to fit the new format
-- Add new ChatType, SourceKind, TargetKind (byte), SortCodeV2
-- Migrate OldChatColumn
@@ -293,7 +318,8 @@ internal class MessageStore : IDisposable
ALTER TABLE messages DROP COLUMN Channel;
ALTER TABLE messages DROP COLUMN Code;
ALTER TABLE messages DROP COLUMN SortCode;
");
"
);
SetMigrationVersion(3);
}
@@ -325,7 +351,8 @@ internal class MessageStore : IDisposable
{
var result = new Dictionary<int, long>();
using var cmd = Connection.CreateCommand();
cmd.CommandText = "SELECT ChatType, COUNT(*) FROM messages WHERE deleted = false GROUP BY ChatType;";
cmd.CommandText =
"SELECT ChatType, COUNT(*) FROM messages WHERE deleted = false GROUP BY ChatType;";
cmd.CommandTimeout = 120;
using var reader = cmd.ExecuteReader();
while (reader.Read())
@@ -343,13 +370,22 @@ internal class MessageStore : IDisposable
/// computed from "now" at call time. Runs VACUUM only if anything was
/// removed. Returns the number of rows deleted.
/// </summary>
internal long DeleteByRetentionPolicy(IReadOnlyDictionary<int, int> chatTypeDaysMap, int defaultDays)
internal long DeleteByRetentionPolicy(
IReadOnlyDictionary<int, int> chatTypeDaysMap,
int defaultDays
)
{
if (defaultDays < 0)
throw new ArgumentOutOfRangeException(nameof(defaultDays), "Negative retention is not allowed.");
throw new ArgumentOutOfRangeException(
nameof(defaultDays),
"Negative retention is not allowed."
);
foreach (var (_, days) in chatTypeDaysMap)
if (days < 0)
throw new ArgumentOutOfRangeException(nameof(chatTypeDaysMap), "Negative retention is not allowed.");
throw new ArgumentOutOfRangeException(
nameof(chatTypeDaysMap),
"Negative retention is not allowed."
);
var nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
@@ -381,10 +417,13 @@ internal class MessageStore : IDisposable
var defaultCutoff = nowMs - defaultDays * 86400000L;
cmd.Parameters.AddWithValue("$defaultCutoff", defaultCutoff);
var explicitPlaceholders = chatTypeDaysMap.Count > 0
? BindIntList(cmd, "explicit", chatTypeDaysMap.Keys)
: "-1"; // empty list would produce invalid SQL
clauses.Add($"(ChatType NOT IN ({explicitPlaceholders}) AND Date < $defaultCutoff)");
var explicitPlaceholders =
chatTypeDaysMap.Count > 0
? BindIntList(cmd, "explicit", chatTypeDaysMap.Keys)
: "-1"; // empty list would produce invalid SQL
clauses.Add(
$"(ChatType NOT IN ({explicitPlaceholders}) AND Date < $defaultCutoff)"
);
}
if (clauses.Count == 0)
@@ -411,7 +450,9 @@ internal class MessageStore : IDisposable
{
// Defensive: refuse a "delete everything" disguised as a filter.
// Use ClearMessages() if a full wipe is actually intended.
throw new InvalidOperationException("CleanupRetainOnly requires at least one allowed ChatType. Use ClearMessages for a full wipe.");
throw new InvalidOperationException(
"CleanupRetainOnly requires at least one allowed ChatType. Use ClearMessages for a full wipe."
);
}
long deleted;
@@ -428,15 +469,19 @@ internal class MessageStore : IDisposable
internal void PerformMaintenance()
{
Connection.Execute(@"
Connection.Execute(
@"
VACUUM;
REINDEX messages;
ANALYZE;
");
"
);
}
private string LogPath => DbPath + "-wal";
internal long DatabaseSize() => !File.Exists(DbPath) ? 0 : new FileInfo(DbPath).Length;
internal long DatabaseLogSize() => !File.Exists(LogPath) ? 0 : new FileInfo(LogPath).Length;
internal int MessageCount()
@@ -461,7 +506,8 @@ internal class MessageStore : IDisposable
}
using var cmd = Connection.CreateCommand();
cmd.CommandText = @"
cmd.CommandText =
@"
INSERT INTO messages (
Id,
Receiver,
@@ -513,10 +559,22 @@ internal class MessageStore : IDisposable
cmd.Parameters.AddWithValue("$ChatType", message.Code.Type);
cmd.Parameters.AddWithValue("$SourceKind", message.Code.Source);
cmd.Parameters.AddWithValue("$TargetKind", message.Code.Target);
cmd.Parameters.AddWithValue("$Sender", MessagePackSerializer.Serialize(message.Sender, MsgPackOptions));
cmd.Parameters.AddWithValue("$Content", MessagePackSerializer.Serialize(message.Content, MsgPackOptions));
cmd.Parameters.AddWithValue("$SenderSource", MessagePackSerializer.Serialize(message.SenderSource, MsgPackOptions));
cmd.Parameters.AddWithValue("$ContentSource", MessagePackSerializer.Serialize(message.ContentSource, MsgPackOptions));
cmd.Parameters.AddWithValue(
"$Sender",
MessagePackSerializer.Serialize(message.Sender, MsgPackOptions)
);
cmd.Parameters.AddWithValue(
"$Content",
MessagePackSerializer.Serialize(message.Content, MsgPackOptions)
);
cmd.Parameters.AddWithValue(
"$SenderSource",
MessagePackSerializer.Serialize(message.SenderSource, MsgPackOptions)
);
cmd.Parameters.AddWithValue(
"$ContentSource",
MessagePackSerializer.Serialize(message.ContentSource, MsgPackOptions)
);
cmd.Parameters.AddWithValue("$ExtraChatChannel", message.ExtraChatChannel);
cmd.ExecuteNonQuery();
@@ -532,7 +590,8 @@ internal class MessageStore : IDisposable
internal MessageEnumerator StreamForExport(
IReadOnlyCollection<int>? chatTypes,
DateTimeOffset? from,
DateTimeOffset? to)
DateTimeOffset? to
)
{
var cmd = Connection.CreateCommand();
@@ -544,7 +603,8 @@ internal class MessageStore : IDisposable
if (to is not null)
clauses.Add("Date <= $To");
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT
Id,
Receiver,
@@ -559,7 +619,9 @@ internal class MessageStore : IDisposable
ContentSource,
ExtraChatChannel
FROM messages
WHERE " + string.Join(" AND ", clauses) + @"
WHERE "
+ string.Join(" AND ", clauses)
+ @"
ORDER BY Date ASC;";
cmd.CommandTimeout = 600;
@@ -577,7 +639,11 @@ internal class MessageStore : IDisposable
/// <param name="receiver">The receiver content ID to filter by. If null, no filtering is performed.</param>
/// <param name="since">Only show messages since this date. If null, no filtering is performed.</param>
/// <param name="count">The amount to return. Defaults to 10,000.</param>
internal MessageEnumerator GetMostRecentMessages(ulong? receiver = null, DateTimeOffset? since = null, int count = MessageQueryLimit)
internal MessageEnumerator GetMostRecentMessages(
ulong? receiver = null,
DateTimeOffset? since = null,
int count = MessageQueryLimit
)
{
List<string> whereClauses = ["deleted = false"];
if (receiver != null)
@@ -590,7 +656,8 @@ internal class MessageStore : IDisposable
var cmd = Connection.CreateCommand();
// Select last N messages by date DESC, but reverse the order to get
// them in ascending order.
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT *
FROM (
SELECT
@@ -607,7 +674,9 @@ internal class MessageStore : IDisposable
ContentSource,
ExtraChatChannel
FROM messages
" + whereClause + @"
"
+ whereClause
+ @"
ORDER BY Date DESC
LIMIT $Count
)
@@ -645,7 +714,8 @@ internal class MessageStore : IDisposable
string senderName,
uint senderWorld,
int limit,
int sqlScanLimit = 500)
int sqlScanLimit = 500
)
{
if (limit <= 0)
{
@@ -653,7 +723,8 @@ internal class MessageStore : IDisposable
}
using var cmd = Connection.CreateCommand();
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT
Id,
Receiver,
@@ -714,7 +785,12 @@ internal class MessageStore : IDisposable
cmd.ExecuteNonQuery();
}
internal long CountDateRange(DateTime after, DateTime before, IEnumerable<byte> channels, ulong? receiver = null)
internal long CountDateRange(
DateTime after,
DateTime before,
IEnumerable<byte> channels,
ulong? receiver = null
)
{
using var cmd = Connection.CreateCommand();
@@ -729,7 +805,8 @@ internal class MessageStore : IDisposable
// Select last N messages by date DESC, but reverse the order to get
// them in ascending order.
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT COUNT(*)
FROM messages
" + whereClause;
@@ -737,14 +814,19 @@ internal class MessageStore : IDisposable
if (receiver != null)
cmd.Parameters.AddWithValue("$Receiver", receiver);
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset) after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset) before).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
cmd.CommandTimeout = 120; // this could take a while on slow computers
return (long) cmd.ExecuteScalar()!;
return (long)cmd.ExecuteScalar()!;
}
internal MessageEnumerator GetDateRange(DateTime after, DateTime before, IEnumerable<byte> channels, ulong? receiver = null)
internal MessageEnumerator GetDateRange(
DateTime after,
DateTime before,
IEnumerable<byte> channels,
ulong? receiver = null
)
{
var cmd = Connection.CreateCommand();
@@ -759,7 +841,8 @@ internal class MessageStore : IDisposable
// Select last N messages by date DESC, but reverse the order to get
// them in ascending order.
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT
Id,
Receiver,
@@ -780,13 +863,19 @@ internal class MessageStore : IDisposable
if (receiver != null)
cmd.Parameters.AddWithValue("$Receiver", receiver);
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset) after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset) before).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
return new MessageEnumerator(cmd.ExecuteReader());
}
internal MessageEnumerator GetPagedDateRange(DateTime after, DateTime before, IEnumerable<byte> channels, ulong? receiver = null, int page = 0)
internal MessageEnumerator GetPagedDateRange(
DateTime after,
DateTime before,
IEnumerable<byte> channels,
ulong? receiver = null,
int page = 0
)
{
var cmd = Connection.CreateCommand();
@@ -801,7 +890,8 @@ internal class MessageStore : IDisposable
// Select last N messages by date DESC, but reverse the order to get
// them in ascending order.
cmd.CommandText = @"
cmd.CommandText =
@"
SELECT
Id,
Receiver,
@@ -816,7 +906,9 @@ internal class MessageStore : IDisposable
ContentSource,
ExtraChatChannel
FROM messages
" + whereClause + @"
"
+ whereClause
+ @"
ORDER BY Date
LIMIT $Offset, $OffsetCount;
";
@@ -825,8 +917,8 @@ internal class MessageStore : IDisposable
if (receiver != null)
cmd.Parameters.AddWithValue("$Receiver", receiver);
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset) after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset) before).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
cmd.Parameters.AddWithValue("$Offset", DbViewer.RowPerPage * page);
cmd.Parameters.AddWithValue("$OffsetCount", DbViewer.RowPerPage);
@@ -852,7 +944,10 @@ internal class MessageStore : IDisposable
}
}
internal class MessageEnumerator(DbDataReader reader) : IEnumerable<Message>, IDisposable, IAsyncDisposable
internal class MessageEnumerator(DbDataReader reader)
: IEnumerable<Message>,
IDisposable,
IAsyncDisposable
{
private const int MaxErrorLogs = 10;
@@ -876,11 +971,27 @@ internal class MessageEnumerator(DbDataReader reader) : IEnumerable<Message>, ID
(ulong)reader.GetInt64(1),
(ulong)reader.GetInt64(2),
DateTimeOffset.FromUnixTimeMilliseconds(reader.GetInt64(3)),
new ChatCode((byte)reader.GetInt32(4), (byte)reader.GetInt32(5), (byte)reader.GetInt32(6)),
MessagePackSerializer.Deserialize<List<Chunk>>(reader.GetFieldValue<byte[]>(7), MessageStore.MsgPackOptions),
MessagePackSerializer.Deserialize<List<Chunk>>(reader.GetFieldValue<byte[]>(8), MessageStore.MsgPackOptions),
MessagePackSerializer.Deserialize<SeString>(reader.GetFieldValue<byte[]>(9), MessageStore.MsgPackOptions),
MessagePackSerializer.Deserialize<SeString>(reader.GetFieldValue<byte[]>(10), MessageStore.MsgPackOptions),
new ChatCode(
(byte)reader.GetInt32(4),
(byte)reader.GetInt32(5),
(byte)reader.GetInt32(6)
),
MessagePackSerializer.Deserialize<List<Chunk>>(
reader.GetFieldValue<byte[]>(7),
MessageStore.MsgPackOptions
),
MessagePackSerializer.Deserialize<List<Chunk>>(
reader.GetFieldValue<byte[]>(8),
MessageStore.MsgPackOptions
),
MessagePackSerializer.Deserialize<SeString>(
reader.GetFieldValue<byte[]>(9),
MessageStore.MsgPackOptions
),
MessagePackSerializer.Deserialize<SeString>(
reader.GetFieldValue<byte[]>(10),
MessageStore.MsgPackOptions
),
reader.GetGuid(11)
);
}
@@ -915,6 +1026,7 @@ internal class MessageEnumerator(DbDataReader reader) : IEnumerable<Message>, ID
{
reader.Dispose();
}
public async ValueTask DisposeAsync()
{
await reader.DisposeAsync();