feat: add direct chat support
This commit is contained in:
parent
60e22f58ee
commit
d0bc1d974f
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue