Generated
+90
@@ -1634,6 +1634,33 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Clear the message history database.
|
||||
/// </summary>
|
||||
internal static string Options_ClearDatabase_Button {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_ClearDatabase_Button", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Successfully cleared the chat database.
|
||||
/// </summary>
|
||||
internal static string Options_ClearDatabase_Success {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_ClearDatabase_Success", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Removes all message history. Cannot be restored. Hold Ctrl+Shift to click..
|
||||
/// </summary>
|
||||
internal static string Options_ClearDatabase_Tooltip {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_ClearDatabase_Tooltip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Replace consecutive duplicate messages with a counter appended to the first instance of the message..
|
||||
/// </summary>
|
||||
@@ -1688,6 +1715,69 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Click to copy database directory path.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_CopyConfigPath {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_CopyConfigPath", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copied database directory path to clipboard.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_CopyConfigPathNotification {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_CopyConfigPathNotification", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Database details:.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_Heading {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_Heading", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Log size: {0}.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_LogSize {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_LogSize", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Stored messages: {0:N0}/{1:N0}.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_MessageCount {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_MessageCount", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Path: {0}.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_Path {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_Path", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Size: {0}.
|
||||
/// </summary>
|
||||
internal static string Options_Database_Metadata_Size {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Database_Metadata_Size", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Database.
|
||||
/// </summary>
|
||||
|
||||
@@ -952,4 +952,34 @@
|
||||
<data name="Options_HideInLoadingScreens_Description" xml:space="preserve">
|
||||
<value>Hide {0} during loading screens.</value>
|
||||
</data>
|
||||
<data name="Options_ClearDatabase_Button">
|
||||
<value>Clear the message history database</value>
|
||||
</data>
|
||||
<data name="Options_ClearDatabase_Success">
|
||||
<value>Successfully cleared the chat database</value>
|
||||
</data>
|
||||
<data name="Options_ClearDatabase_Tooltip">
|
||||
<value>Removes all message history. Cannot be restored. Hold Ctrl+Shift to click.</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_CopyConfigPath">
|
||||
<value>Click to copy database directory path</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_CopyConfigPathNotification">
|
||||
<value>Copied database directory path to clipboard</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_Heading">
|
||||
<value>Database details:</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_LogSize">
|
||||
<value>Log size: {0}</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_MessageCount">
|
||||
<value>Stored messages: {0:N0}/{1:N0}</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_Path">
|
||||
<value>Path: {0}</value>
|
||||
</data>
|
||||
<data name="Options_Database_Metadata_Size">
|
||||
<value>Size: {0}</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
+32
-6
@@ -140,9 +140,6 @@ internal class Store : IDisposable {
|
||||
bson => DateTime.UnixEpoch.AddMilliseconds(bson.AsInt64)
|
||||
);
|
||||
Database = Connect();
|
||||
Messages.EnsureIndex(msg => msg.Date);
|
||||
Messages.EnsureIndex(msg => msg.SortCode);
|
||||
Messages.EnsureIndex(msg => msg.ExtraChatChannel);
|
||||
|
||||
Plugin.ChatGui.ChatMessageUnhandled += ChatMessage;
|
||||
Plugin.Framework.Update += GetMessageInfo;
|
||||
@@ -159,17 +156,26 @@ internal class Store : IDisposable {
|
||||
Database.Dispose();
|
||||
}
|
||||
|
||||
private ILiteDatabase Connect() {
|
||||
internal static string DatabasePath()
|
||||
{
|
||||
var dir = Plugin.Interface.ConfigDirectory;
|
||||
dir.Create();
|
||||
return Path.Join(dir.FullName, "chat.db");
|
||||
}
|
||||
|
||||
var dbPath = Path.Join(dir.FullName, "chat.db");
|
||||
private LiteDatabase Connect() {
|
||||
var dbPath = DatabasePath();
|
||||
var connection = Plugin.Config.SharedMode ? "shared" : "direct";
|
||||
var connString = $"Filename='{dbPath}';Connection={connection}";
|
||||
return new LiteDatabase(connString, BsonMapper.Global) {
|
||||
var conn = new LiteDatabase(connString, BsonMapper.Global) {
|
||||
CheckpointSize = 1_000,
|
||||
Timeout = TimeSpan.FromSeconds(1),
|
||||
};
|
||||
var messages = conn.GetCollection<Message>("messages");
|
||||
messages.EnsureIndex(msg => msg.Date);
|
||||
messages.EnsureIndex(msg => msg.SortCode);
|
||||
messages.EnsureIndex(msg => msg.ExtraChatChannel);
|
||||
return conn;
|
||||
}
|
||||
|
||||
internal void Reconnect() {
|
||||
@@ -177,6 +183,26 @@ internal class Store : IDisposable {
|
||||
Database = Connect();
|
||||
}
|
||||
|
||||
internal void ClearDatabase()
|
||||
{
|
||||
Messages.DeleteAll();
|
||||
Database.Rebuild();
|
||||
}
|
||||
|
||||
internal static long DatabaseSize()
|
||||
{
|
||||
var dbPath = DatabasePath();
|
||||
return !File.Exists(dbPath) ? 0 : new FileInfo(dbPath).Length;
|
||||
}
|
||||
|
||||
internal static long DatabaseLogSize()
|
||||
{
|
||||
var dbLogPath = Path.Join(Plugin.Interface.ConfigDirectory.FullName, "chat-log.db");
|
||||
return !File.Exists(dbLogPath) ? 0 : new FileInfo(dbLogPath).Length;
|
||||
}
|
||||
|
||||
internal int MessageCount() => Messages.Count();
|
||||
|
||||
private void Logout() {
|
||||
LastContentId = 0;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public sealed class SettingsWindow : Window, IUiComponent
|
||||
new Ui.SettingsTabs.Fonts(Mutable),
|
||||
new ChatColours(Mutable, Plugin),
|
||||
new Tabs(Plugin, Mutable),
|
||||
new Database(Mutable, Plugin.Store),
|
||||
new Database(Mutable, Plugin),
|
||||
new Miscellaneous(Mutable),
|
||||
new About(),
|
||||
};
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
using ChatTwo.Resources;
|
||||
using ChatTwo.Util;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace ChatTwo.Ui.SettingsTabs;
|
||||
|
||||
internal sealed class Database : ISettingsTab {
|
||||
private Configuration Mutable { get; }
|
||||
private Store Store { get; }
|
||||
private Plugin Plugin { get; }
|
||||
|
||||
public string Name => Language.Options_Database_Tab + "###tabs-database";
|
||||
|
||||
internal Database(Configuration mutable, Store store) {
|
||||
Store = store;
|
||||
internal Database(Configuration mutable, Plugin plugin) {
|
||||
Plugin = plugin;
|
||||
Mutable = mutable;
|
||||
}
|
||||
|
||||
private bool _showAdvanced;
|
||||
|
||||
private long _databaseLastRefreshTicks;
|
||||
private long _databaseSize;
|
||||
private long _databaseLogSize;
|
||||
private int _databaseMessageCount;
|
||||
|
||||
public void Draw(bool changed) {
|
||||
if (changed) {
|
||||
_showAdvanced = ImGui.GetIO().KeyShift;
|
||||
@@ -46,18 +52,88 @@ internal sealed class Database : ISettingsTab {
|
||||
);
|
||||
ImGuiUtil.WarningText(string.Format(Language.Options_SharedMode_Warning, Plugin.PluginName));
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
if (_showAdvanced && ImGui.TreeNodeEx(Language.Options_Database_Advanced)) {
|
||||
ImGui.Text(Language.Options_Database_Metadata_Heading);
|
||||
var style = ImGui.GetStyle();
|
||||
ImGui.Indent(style.IndentSpacing);
|
||||
|
||||
// Refresh the database size and message count every 5 seconds to avoid
|
||||
// constant stat calls and spamming the database.
|
||||
if (_databaseLastRefreshTicks + 5 * 1000 < Environment.TickCount64)
|
||||
{
|
||||
_databaseSize = Store.DatabaseSize();
|
||||
_databaseLogSize = Store.DatabaseLogSize();
|
||||
_databaseMessageCount = Plugin.Store.MessageCount();
|
||||
_databaseLastRefreshTicks = Environment.TickCount64;
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_Path, Store.DatabasePath()));
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
// Copy the directory path instead of the file path so people can
|
||||
// paste it into their file explorer.
|
||||
var path = Path.GetDirectoryName(Store.DatabasePath());
|
||||
ImGui.SetClipboardText(path);
|
||||
WrapperUtil.AddNotification(Language.Options_Database_Metadata_CopyConfigPathNotification, NotificationType.Info);
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.Text(Language.Options_Database_Metadata_CopyConfigPath);
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_Size, StringUtil.BytesToString(_databaseSize)));
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.Text(_databaseSize.ToString("N0") + "B");
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_LogSize, StringUtil.BytesToString(_databaseLogSize)));
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.Text(_databaseLogSize.ToString("N0") + "B");
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_MessageCount, _databaseMessageCount, Store.MessagesLimit));
|
||||
|
||||
if (ImGuiUtil.CtrlShiftButton(Language.Options_ClearDatabase_Button, Language.Options_ClearDatabase_Tooltip))
|
||||
{
|
||||
Plugin.Log.Warning("Clearing database");
|
||||
Plugin.Store.ClearDatabase();
|
||||
foreach (var tab in Plugin.Config.Tabs)
|
||||
{
|
||||
tab.Clear();
|
||||
}
|
||||
// Refresh on next draw
|
||||
_databaseLastRefreshTicks = 0;
|
||||
WrapperUtil.AddNotification(Language.Options_ClearDatabase_Success, NotificationType.Info);
|
||||
}
|
||||
|
||||
ImGui.Unindent(style.IndentSpacing);
|
||||
ImGui.Spacing();
|
||||
|
||||
if (_showAdvanced && ImGui.TreeNodeEx(Language.Options_Database_Advanced))
|
||||
{
|
||||
ImGui.PushTextWrapPos();
|
||||
ImGuiUtil.WarningText(Language.Options_Database_Advanced_Warning);
|
||||
|
||||
if (ImGui.Button("Checkpoint")) {
|
||||
Store.Database.Checkpoint();
|
||||
if (ImGuiUtil.CtrlShiftButton("Checkpoint", "Ctrl+Shift: Database.Checkpoint()"))
|
||||
{
|
||||
Plugin.Store.Database.Checkpoint();
|
||||
}
|
||||
|
||||
if (ImGui.Button("Rebuild")) {
|
||||
Store.Database.Rebuild();
|
||||
if (ImGuiUtil.CtrlShiftButton("Rebuild", "Ctrl+Shift: Database.Rebuild()"))
|
||||
{
|
||||
Plugin.Store.Database.Rebuild();
|
||||
}
|
||||
|
||||
ImGui.PopTextWrapPos();
|
||||
|
||||
@@ -234,6 +234,22 @@ internal static class ImGuiUtil {
|
||||
return r;
|
||||
}
|
||||
|
||||
internal static bool CtrlShiftButton(string label, string tooltip = "")
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
var ctrlShiftHeld = io.KeyCtrl && io.KeyShift;
|
||||
if (!ctrlShiftHeld) ImGui.BeginDisabled();
|
||||
var ret = ImGui.Button(label) && ctrlShiftHeld;
|
||||
if (!ctrlShiftHeld) ImGui.EndDisabled();
|
||||
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) {
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.TextUnformatted(tooltip);
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal static bool TryToImGui(this VirtualKey key, out ImGuiKey result) {
|
||||
result = key switch {
|
||||
VirtualKey.NO_KEY => ImGuiKey.None,
|
||||
|
||||
@@ -10,4 +10,16 @@ internal static class StringUtil {
|
||||
bytes[^1] = 0;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// Taken from https://stackoverflow.com/a/4975942
|
||||
internal static String BytesToString(long byteCount) {
|
||||
string[] suf = ["B", "KB", "MB", "GB", "TB", "PB", "EB"]; // Longs run out around EB
|
||||
if (byteCount == 0)
|
||||
return "0" + suf[0];
|
||||
|
||||
var bytes = Math.Abs(byteCount);
|
||||
var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
|
||||
var num = Math.Round(bytes / Math.Pow(1024, place), 1);
|
||||
return (Math.Sign(byteCount) * num).ToString("N0") + suf[place];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user