Skip to content

Commit

Permalink
Add text event log database in debug builds
Browse files Browse the repository at this point in the history
  • Loading branch information
karashiiro committed Mar 22, 2024
1 parent 39a5f7e commit 5c66fe8
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 4 deletions.
9 changes: 9 additions & 0 deletions scripts/db/QueryTextEvents.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SELECT Timestamp,
LAST(SPLIT(FIRST(SPLIT(Event._type, ', ')), '.')) AS Type,
Event.Source AS Source,
Event.ChatType AS ChatType,
COALESCE(Event.Speaker, Event.SpeakerName) AS Speaker,
Event.Text AS Text,
Event
FROM event
ORDER BY Timestamp DESC;
10 changes: 10 additions & 0 deletions src/TextToTalk.Data/Model/TextEventLogEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TextToTalk.Data.Model;

public class TextEventLogEntry
{
public Guid Id { get; init; }

public required DateTime Timestamp { get; init; }

public required object Event { get; init; }
}
27 changes: 27 additions & 0 deletions src/TextToTalk.Data/Service/TextEventLogCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using LiteDB;
using TextToTalk.Data.Model;

namespace TextToTalk.Data.Service;

public class TextEventLogCollection(ILiteDatabase db)
{
private const string TextEventLogCollectionName = "event";

public void StoreEvent(TextEventLogEntry entry)
{
var collection = GetTextEventLogCollection();
collection.Insert(entry);
}

private ILiteCollection<TextEventLogEntry> GetTextEventLogCollection()
{
var collection = db.GetCollection<TextEventLogEntry>(TextEventLogCollectionName);
EnsureIndices(collection);
return collection;
}

private static void EnsureIndices(ILiteCollection<TextEventLogEntry> collection)
{
collection.EnsureIndex(p => p.Timestamp);
}
}
17 changes: 15 additions & 2 deletions src/TextToTalk/Events/TextEvent.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
namespace TextToTalk.Events;
using System;
using TextToTalk.Data.Model;

public abstract class TextEvent;
namespace TextToTalk.Events;

public abstract class TextEvent
{
public TextEventLogEntry ToLogEntry()
{
return new TextEventLogEntry
{
Event = this,
Timestamp = DateTime.UtcNow,
};
}
}
24 changes: 24 additions & 0 deletions src/TextToTalk/ObjectMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Runtime.CompilerServices;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Text.SeStringHandling;
using LiteDB;

namespace TextToTalk;

public class ObjectMapper
{
[ModuleInitializer]
internal static void Initialize()
{
// Register one-way SeString mapper
BsonMapper.Global.RegisterType<SeString>(
serialize: value => value.TextValue,
deserialize: _ => throw new NotSupportedException());

// Register one-way GameObject mapper
BsonMapper.Global.RegisterType<GameObject>(
serialize: value => value.Name.TextValue,
deserialize: _ => throw new NotSupportedException());
}
}
27 changes: 25 additions & 2 deletions src/TextToTalk/TextToTalk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Dalamud.IoC;
using Dalamud.Plugin;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
Expand All @@ -22,6 +23,7 @@
using TextToTalk.Backends.Websocket;
using TextToTalk.CommandModules;
using TextToTalk.Data.Service;
using TextToTalk.Events;
using TextToTalk.GameEnums;
using TextToTalk.Middleware;
using TextToTalk.Talk;
Expand Down Expand Up @@ -70,6 +72,9 @@ public partial class TextToTalk : IDalamudPlugin

private readonly IDisposable unsubscribeAll;

private ILiteDatabase? textEventLogDatabase;
private TextEventLogCollection? textEventLog;

private bool failedToBindWsPort;
private bool notifiedFailedToBindPort;
private bool notifiedNoPresetsConfigured;
Expand Down Expand Up @@ -97,6 +102,7 @@ public TextToTalk(
this.framework = framework;

CreateDatabasePath();
CreateEventLogDatabase();
this.database = new LiteDatabase(GetDatabasePath("TextToTalk.db"));
var playerCollection = new PlayerCollection(this.database);
var npcCollection = new NpcCollection(this.database);
Expand Down Expand Up @@ -178,30 +184,46 @@ private string GetDatabasePath(string fileName)
return Path.Combine(this.pluginInterface.GetPluginConfigDirectory(), fileName);
}

[Conditional("DEBUG")]
private void CreateEventLogDatabase()
{
this.textEventLogDatabase = new LiteDatabase(GetDatabasePath("log.db"));
this.textEventLog = new TextEventLogCollection(this.textEventLogDatabase);
}

private IDisposable HandleTextCancel()
{
return OnTextSourceCancel()
.Where(this, static (_, p) => p.config is { Enabled: true, CancelSpeechOnTextAdvance: true })
.Do(LogTextEvent)
.SubscribeOnThreadPool()
.Subscribe(
ev => FunctionalUtils.RunSafely(
() => this.backendManager.CancelSay(ev.Source),
ex => DetailedLog.Error(ex, "Failed to handle text cancel event")),
ex => DetailedLog.Error(ex, "Text cancel event sequence has faulted"),
_ => {});
_ => { });
}

private IDisposable HandleTextEmit()
{
return OnTextEmit()
.Where(this, static (_, p) => p.config.Enabled)
.Do(LogTextEvent)
.SubscribeOnThreadPool()
.Subscribe(
ev => FunctionalUtils.RunSafely(
() => Say(ev.Speaker, ev.SpeakerName, ev.Text.TextValue, ev.Source),
ex => DetailedLog.Error(ex, "Failed to handle text emit event")),
ex => DetailedLog.Error(ex, "Text emit event sequence has faulted"),
_ => {});
_ => { });
}

private void LogTextEvent(TextEvent ev)
{
FunctionalUtils.RunSafely(
() => this.textEventLog?.StoreEvent(ev.ToLogEntry()),
ex => DetailedLog.Error(ex, "Failed to log text emit event"));
}

private IDisposable HandleFailedToBindWSPort()
Expand Down Expand Up @@ -468,6 +490,7 @@ protected virtual void Dispose(bool disposing)
this.backendManager.Dispose();
this.http.Dispose();

this.textEventLogDatabase?.Dispose();
this.database.Dispose();

this.addonBattleTalkManager.Dispose();
Expand Down

0 comments on commit 5c66fe8

Please sign in to comment.