Switch to dalamud window system

This commit is contained in:
Infi
2024-04-06 23:09:20 +02:00
parent 882099affe
commit 20edc10961
10 changed files with 539 additions and 610 deletions
+46 -132
View File
@@ -1,13 +1,10 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Numerics;
using ChatTwo.Code;
using ChatTwo.Resources;
using ChatTwo.Util;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin.Services;
using ImGuiNET;
using LiteDB;
using Lumina.Excel.GeneratedSheets;
@@ -21,7 +18,7 @@ internal class Store : IDisposable {
private ConcurrentQueue<(uint, Message)> Pending { get; } = new();
private Stopwatch CheckpointTimer { get; } = new();
internal ILiteDatabase Database { get; private set; }
private ILiteCollection<Message> Messages => this.Database.GetCollection<Message>("messages");
private ILiteCollection<Message> Messages => Database.GetCollection<Message>("messages");
private Dictionary<ChatType, NameFormatting> Formats { get; } = new();
private ulong LastContentId { get; set; }
@@ -29,13 +26,13 @@ internal class Store : IDisposable {
private ulong CurrentContentId {
get {
var contentId = Plugin.ClientState.LocalContentId;
return contentId == 0 ? this.LastContentId : contentId;
return contentId == 0 ? LastContentId : contentId;
}
}
internal Store(Plugin plugin) {
this.Plugin = plugin;
this.CheckpointTimer.Start();
Plugin = plugin;
CheckpointTimer.Start();
BsonMapper.Global = new BsonMapper {
IncludeNonPublic = true,
@@ -43,7 +40,7 @@ internal class Store : IDisposable {
// EnumAsInteger = true,
};
if (this.Plugin.Config.DatabaseMigration == 0) {
if (Plugin.Config.DatabaseMigration == 0) {
BsonMapper.Global.Entity<Message>()
.Id(msg => msg.Id)
.Ctor(doc => new Message(
@@ -136,26 +133,24 @@ internal class Store : IDisposable {
dateTime => dateTime.Subtract(DateTime.UnixEpoch).TotalMilliseconds,
bson => DateTime.UnixEpoch.AddMilliseconds(bson.AsInt64)
);
this.Database = this.Connect();
this.Messages.EnsureIndex(msg => msg.Date);
this.Messages.EnsureIndex(msg => msg.SortCode);
this.Messages.EnsureIndex(msg => msg.ExtraChatChannel);
Database = Connect();
Messages.EnsureIndex(msg => msg.Date);
Messages.EnsureIndex(msg => msg.SortCode);
Messages.EnsureIndex(msg => msg.ExtraChatChannel);
this.MigrateWrapper();
Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage;
Plugin.Framework.Update += this.GetMessageInfo;
Plugin.Framework.Update += this.UpdateReceiver;
Plugin.ClientState.Logout += this.Logout;
Plugin.ChatGui.ChatMessageUnhandled += ChatMessage;
Plugin.Framework.Update += GetMessageInfo;
Plugin.Framework.Update += UpdateReceiver;
Plugin.ClientState.Logout += Logout;
}
public void Dispose() {
Plugin.ClientState.Logout -= this.Logout;
Plugin.Framework.Update -= this.UpdateReceiver;
Plugin.Framework.Update -= this.GetMessageInfo;
Plugin.ChatGui.ChatMessageUnhandled -= this.ChatMessage;
Plugin.ClientState.Logout -= Logout;
Plugin.Framework.Update -= UpdateReceiver;
Plugin.Framework.Update -= GetMessageInfo;
Plugin.ChatGui.ChatMessageUnhandled -= ChatMessage;
this.Database.Dispose();
Database.Dispose();
}
private ILiteDatabase Connect() {
@@ -163,7 +158,7 @@ internal class Store : IDisposable {
dir.Create();
var dbPath = Path.Join(dir.FullName, "chat.db");
var connection = this.Plugin.Config.SharedMode ? "shared" : "direct";
var connection = Plugin.Config.SharedMode ? "shared" : "direct";
var connString = $"Filename='{dbPath}';Connection={connection}";
return new LiteDatabase(connString, BsonMapper.Global) {
CheckpointSize = 1_000,
@@ -172,127 +167,46 @@ internal class Store : IDisposable {
}
internal void Reconnect() {
this.Database.Dispose();
this.Database = this.Connect();
Database.Dispose();
Database = Connect();
}
private void Logout() {
this.LastContentId = 0;
LastContentId = 0;
}
private void UpdateReceiver(IFramework framework) {
var contentId = Plugin.ClientState.LocalContentId;
if (contentId != 0) {
this.LastContentId = contentId;
LastContentId = contentId;
}
}
private void GetMessageInfo(IFramework framework) {
if (this.CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) {
this.CheckpointTimer.Restart();
new Thread(() => this.Database.Checkpoint()).Start();
if (CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) {
CheckpointTimer.Restart();
new Thread(() => Database.Checkpoint()).Start();
}
if (!this.Pending.TryDequeue(out var entry)) {
if (!Pending.TryDequeue(out var entry)) {
return;
}
var contentId = this.Plugin.Functions.Chat.GetContentIdForEntry(entry.Item1);
var contentId = Plugin.Functions.Chat.GetContentIdForEntry(entry.Item1);
entry.Item2.ContentId = contentId ?? 0;
if (this.Plugin.Config.DatabaseBattleMessages || !entry.Item2.Code.IsBattle()) {
this.Messages.Update(entry.Item2);
}
}
private long _migrateCurrent;
private long _migrateMax;
private void MigrateDraw() {
ImGui.SetNextWindowSizeConstraints(new Vector2(450, 0), new Vector2(450, float.MaxValue));
if (!ImGui.Begin($"{Plugin.PluginName}##migration-window", ImGuiWindowFlags.AlwaysAutoResize)) {
ImGui.End();
return;
}
ImGui.PushTextWrapPos();
ImGui.TextUnformatted(string.Format(Language.Migration_Line1, Plugin.PluginName));
ImGui.TextUnformatted(string.Format(Language.Migration_Line2, Plugin.PluginName));
ImGui.TextUnformatted(Language.Migration_Line3);
ImGui.TextUnformatted(Language.Migration_Line4);
ImGui.PopTextWrapPos();
ImGui.Spacing();
ImGui.ProgressBar((float) this._migrateCurrent / this._migrateMax, new Vector2(-1, 0), $"{this._migrateCurrent} / {this._migrateMax}");
ImGui.End();
}
internal void MigrateWrapper() {
if (this.Plugin.Config.DatabaseMigration < Configuration.LatestDbVersion) {
Plugin.Interface.UiBuilder.Draw += this.MigrateDraw;
}
try {
this.Migrate();
} finally {
Plugin.Interface.UiBuilder.Draw -= this.MigrateDraw;
}
}
internal void Migrate() {
// re-save all messages, which will add the ExtraChat channel
if (this.Plugin.Config.DatabaseMigration == 0) {
var total = (float) this.Messages.LongCount() / 10_000.0;
var rounds = (long) Math.Ceiling(total);
this._migrateMax = rounds;
var lastId = ObjectId.Empty;
for (var i = 0; i < rounds; i++) {
this._migrateCurrent = i + 1;
Plugin.Log.Info($"Update round {i + 1}/{rounds}");
var messages = this.Messages.Query()
.OrderBy(msg => msg.Id)
.Where(msg => msg.Id > lastId)
.Limit(10_000)
.ToArray();
foreach (var message in messages) {
this.Messages.Update(message);
lastId = message.Id;
}
}
this.Database.Checkpoint();
BsonMapper.Global.Entity<Message>()
.Id(msg => msg.Id)
.Ctor(doc => new Message(
doc["_id"].AsObjectId,
(ulong) doc["Receiver"].AsInt64,
(ulong) doc["ContentId"].AsInt64,
DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64),
doc["Code"].AsDocument,
doc["Sender"].AsArray,
doc["Content"].AsArray,
doc["SenderSource"],
doc["ContentSource"],
doc["SortCode"].AsDocument,
doc["ExtraChatChannel"]
));
this.Plugin.Config.DatabaseMigration = 1;
this.Plugin.SaveConfig();
if (Plugin.Config.DatabaseBattleMessages || !entry.Item2.Code.IsBattle()) {
Messages.Update(entry.Item2);
}
}
internal void AddMessage(Message message, Tab? currentTab) {
if (this.Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) {
this.Messages.Insert(message);
if (Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) {
Messages.Insert(message);
}
var currentMatches = currentTab?.Matches(message) ?? false;
foreach (var tab in this.Plugin.Config.Tabs) {
foreach (var tab in Plugin.Config.Tabs) {
var unread = !(tab.UnreadMode == UnreadMode.Unseen && currentTab != tab && currentMatches);
if (tab.Matches(message)) {
@@ -302,8 +216,8 @@ internal class Store : IDisposable {
}
internal void FilterAllTabs(bool unread = true) {
foreach (var tab in this.Plugin.Config.Tabs) {
this.FilterTab(tab, unread);
foreach (var tab in Plugin.Config.Tabs) {
FilterTab(tab, unread);
}
}
@@ -322,13 +236,13 @@ internal class Store : IDisposable {
}
}
var query = this.Messages
var query = Messages
.Query()
.OrderByDescending(msg => msg.Date)
.Where(msg => sortCodes.Contains(msg.SortCode) || msg.ExtraChatChannel != Guid.Empty)
.Where(msg => msg.Receiver == this.CurrentContentId);
if (!this.Plugin.Config.FilterIncludePreviousSessions) {
query = query.Where(msg => msg.Date >= this.Plugin.GameStarted);
.Where(msg => msg.Receiver == CurrentContentId);
if (!Plugin.Config.FilterIncludePreviousSessions) {
query = query.Where(msg => msg.Date >= Plugin.GameStarted);
}
var messages = query
@@ -348,7 +262,7 @@ internal class Store : IDisposable {
NameFormatting? formatting = null;
if (sender.Payloads.Count > 0) {
formatting = this.FormatFor(chatCode.Type);
formatting = FormatFor(chatCode.Type);
}
var senderChunks = new List<Chunk>();
@@ -364,12 +278,12 @@ internal class Store : IDisposable {
var messageChunks = ChunkUtil.ToChunks(message, ChunkSource.Content, chatCode.Type).ToList();
var msg = new Message(this.CurrentContentId, chatCode, senderChunks, messageChunks, sender, message);
this.AddMessage(msg, this.Plugin.Ui.CurrentTab ?? null);
var msg = new Message(CurrentContentId, chatCode, senderChunks, messageChunks, sender, message);
AddMessage(msg, Plugin.ChatLogWindow.CurrentTab ?? null);
var idx = this.Plugin.Functions.GetCurrentChatLogEntryIndex();
var idx = Plugin.Functions.GetCurrentChatLogEntryIndex();
if (idx != null) {
this.Pending.Enqueue((idx.Value - 1, msg));
Pending.Enqueue((idx.Value - 1, msg));
}
}
@@ -393,7 +307,7 @@ internal class Store : IDisposable {
}
private NameFormatting? FormatFor(ChatType type) {
if (this.Formats.TryGetValue(type, out var cached)) {
if (Formats.TryGetValue(type, out var cached)) {
return cached;
}
@@ -434,7 +348,7 @@ internal class Store : IDisposable {
string.Join("", after)
);
this.Formats[type] = nameFormatting;
Formats[type] = nameFormatting;
return nameFormatting;
}