feat: add direct chat support

This commit is contained in:
Anna 2022-02-01 01:52:51 -05:00
parent 60e22f58ee
commit d0bc1d974f
3 changed files with 60 additions and 13 deletions

View File

@ -104,9 +104,13 @@ internal sealed unsafe class Chat : IDisposable {
#pragma warning restore 0649
// Pointers
[Signature("48 8D 15 ?? ?? ?? ?? 0F B6 C8 48 8D 05", ScanType = ScanType.StaticAddress)]
private readonly char* _currentCharacter = null!;
// Events
internal delegate void ChatActivatedEventDelegate(string? input, ChannelSwitchInfo info, TellReason? reason, TellTarget? target);
internal delegate void ChatActivatedEventDelegate(ChatActivatedArgs args);
internal event ChatActivatedEventDelegate? Activated;
@ -349,7 +353,9 @@ internal sealed unsafe class Chat : IDisposable {
}
try {
this.Activated?.Invoke(null, info, TellReason.Reply, null);
this.Activated?.Invoke(new ChatActivatedArgs(info) {
TellReason = TellReason.Reply,
});
} catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event");
}
@ -374,18 +380,35 @@ internal sealed unsafe class Chat : IDisposable {
return this.ChatLogRefreshHook!.Original(log, eventId, value);
}
string? eventInput = null;
string? input = null;
var option = Framework.Instance()->GetUiModule()->GetConfigModule()->GetValueById(572);
if (option != null) {
var directChat = option->Int > 0;
if (directChat && this._currentCharacter != null) {
// FIXME: this whole system sucks
var c = *this._currentCharacter;
if (c != '\0' && !char.IsControl(c)) {
input = c.ToString();
}
}
}
string? addIfNotPresent = null;
var str = value + 2;
if (str != null && ((int) str->Type & 0xF) == (int) ValueType.String && str->String != null) {
var input = MemoryHelper.ReadStringNullTerminated((IntPtr) str->String);
if (input.Length > 0) {
eventInput = input;
var add = MemoryHelper.ReadStringNullTerminated((IntPtr) str->String);
if (add.Length > 0) {
addIfNotPresent = add;
}
}
try {
this.Activated?.Invoke(eventInput, new ChannelSwitchInfo(null), null, null);
var args = new ChatActivatedArgs(new ChannelSwitchInfo(null)) {
AddIfNotPresent = addIfNotPresent,
Input = input,
};
this.Activated?.Invoke(args);
} catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event");
}
@ -465,7 +488,10 @@ internal sealed unsafe class Chat : IDisposable {
if (name != null) {
try {
var target = new TellTarget(name->ToString(), world, contentId, (TellReason) reason);
this.Activated?.Invoke(null, new ChannelSwitchInfo(InputChannel.Tell), (TellReason) reason, target);
this.Activated?.Invoke(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell)) {
TellReason = (TellReason) reason,
TellTarget = target,
});
} catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event");
}

View File

@ -0,0 +1,13 @@
namespace ChatTwo.GameFunctions.Types;
internal sealed class ChatActivatedArgs {
internal string? AddIfNotPresent { get; init; }
internal string? Input { get; init; }
internal ChannelSwitchInfo ChannelSwitchInfo { get; }
internal TellReason? TellReason { get; init; }
internal TellTarget? TellTarget { get; init; }
internal ChatActivatedArgs(ChannelSwitchInfo channelSwitchInfo) {
this.ChannelSwitchInfo = channelSwitchInfo;
}
}

View File

@ -56,12 +56,18 @@ internal sealed class ChatLog : IUiComponent {
this.Ui.Plugin.CommandManager.RemoveHandler("/clearlog2");
}
private void Activated(string? input, ChannelSwitchInfo info, TellReason? reason, TellTarget? target) {
private void Activated(ChatActivatedArgs args) {
this.Activate = true;
if (input != null && !this.Chat.Contains(input)) {
this.Chat += input;
if (args.AddIfNotPresent != null && !this.Chat.Contains(args.AddIfNotPresent)) {
this.Chat += args.AddIfNotPresent;
}
if (args.Input != null) {
this.Chat += args.Input;
}
var (info, reason, target) = (args.ChannelSwitchInfo, args.TellReason, args.TellTarget);
if (info.Channel != null) {
var prevTemp = this._tempChannel;
@ -231,7 +237,9 @@ internal sealed class ChatLog : IUiComponent {
try {
TellReason? reason = info.Channel == InputChannel.Tell ? TellReason.Reply : null;
this.Activated(null, info, reason, null);
this.Activated(new ChatActivatedArgs(info) {
TellReason = reason,
});
} catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event");
}
@ -267,7 +275,7 @@ internal sealed class ChatLog : IUiComponent {
if (this.Ui.Plugin.Config.HideDuringCutscenes && this._hideState == HideState.None && (this.CutsceneActive || this.GposeActive)) {
this._hideState = HideState.Cutscene;
}
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
if (this._hideState is HideState.Cutscene or HideState.CutsceneOverride && !this.CutsceneActive && !this.GposeActive) {
this._hideState = HideState.None;