feat: add direct chat support
This commit is contained in:
parent
3ec0dc9014
commit
fd441af5ae
|
@ -104,9 +104,13 @@ internal sealed unsafe class Chat : IDisposable {
|
||||||
|
|
||||||
#pragma warning restore 0649
|
#pragma warning restore 0649
|
||||||
|
|
||||||
|
// Pointers
|
||||||
|
[Signature("48 8D 15 ?? ?? ?? ?? 0F B6 C8 48 8D 05", ScanType = ScanType.StaticAddress)]
|
||||||
|
private readonly char* _currentCharacter = null!;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
internal delegate void ChatActivatedEventDelegate(string? input, ChannelSwitchInfo info, TellReason? reason, TellTarget? target);
|
internal delegate void ChatActivatedEventDelegate(ChatActivatedArgs args);
|
||||||
|
|
||||||
internal event ChatActivatedEventDelegate? Activated;
|
internal event ChatActivatedEventDelegate? Activated;
|
||||||
|
|
||||||
|
@ -349,7 +353,9 @@ internal sealed unsafe class Chat : IDisposable {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.Activated?.Invoke(null, info, TellReason.Reply, null);
|
this.Activated?.Invoke(new ChatActivatedArgs(info) {
|
||||||
|
TellReason = TellReason.Reply,
|
||||||
|
});
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
PluginLog.LogError(ex, "Error in chat Activated event");
|
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);
|
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;
|
var str = value + 2;
|
||||||
if (str != null && ((int) str->Type & 0xF) == (int) ValueType.String && str->String != null) {
|
if (str != null && ((int) str->Type & 0xF) == (int) ValueType.String && str->String != null) {
|
||||||
var input = MemoryHelper.ReadStringNullTerminated((IntPtr) str->String);
|
var add = MemoryHelper.ReadStringNullTerminated((IntPtr) str->String);
|
||||||
if (input.Length > 0) {
|
if (add.Length > 0) {
|
||||||
eventInput = input;
|
addIfNotPresent = add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (Exception ex) {
|
||||||
PluginLog.LogError(ex, "Error in chat Activated event");
|
PluginLog.LogError(ex, "Error in chat Activated event");
|
||||||
}
|
}
|
||||||
|
@ -465,7 +488,10 @@ internal sealed unsafe class Chat : IDisposable {
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
try {
|
try {
|
||||||
var target = new TellTarget(name->ToString(), world, contentId, (TellReason) reason);
|
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) {
|
} catch (Exception ex) {
|
||||||
PluginLog.LogError(ex, "Error in chat Activated event");
|
PluginLog.LogError(ex, "Error in chat Activated event");
|
||||||
}
|
}
|
||||||
|
|
13
ChatTwo/GameFunctions/Types/ChatActivatedArgs.cs
Executable file
13
ChatTwo/GameFunctions/Types/ChatActivatedArgs.cs
Executable 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,12 +56,18 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
this.Ui.Plugin.CommandManager.RemoveHandler("/clearlog2");
|
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;
|
this.Activate = true;
|
||||||
if (input != null && !this.Chat.Contains(input)) {
|
if (args.AddIfNotPresent != null && !this.Chat.Contains(args.AddIfNotPresent)) {
|
||||||
this.Chat += input;
|
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) {
|
if (info.Channel != null) {
|
||||||
var prevTemp = this._tempChannel;
|
var prevTemp = this._tempChannel;
|
||||||
|
|
||||||
|
@ -231,7 +237,9 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TellReason? reason = info.Channel == InputChannel.Tell ? TellReason.Reply : null;
|
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) {
|
} catch (Exception ex) {
|
||||||
PluginLog.LogError(ex, "Error in chat Activated event");
|
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)) {
|
if (this.Ui.Plugin.Config.HideDuringCutscenes && this._hideState == HideState.None && (this.CutsceneActive || this.GposeActive)) {
|
||||||
this._hideState = HideState.Cutscene;
|
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 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) {
|
if (this._hideState is HideState.Cutscene or HideState.CutsceneOverride && !this.CutsceneActive && !this.GposeActive) {
|
||||||
this._hideState = HideState.None;
|
this._hideState = HideState.None;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user