fix #81
This commit is contained in:
@@ -22,7 +22,14 @@ tags:
|
||||
- Chat
|
||||
- Replacement
|
||||
changelog: |-
|
||||
**Misc**
|
||||
**Added**
|
||||
- Implement 24-hour clock timestamp option [default false]
|
||||
- Fix hide activity channels not being saved across sessions
|
||||
|
||||
**Fixes**
|
||||
- Bozja/Eureka tells should work again
|
||||
- Invites in Bozja/Eureka should work again
|
||||
- Added a notification that warns about fails duo missing player id
|
||||
- Hide activity channels are now saved across sessions
|
||||
|
||||
**Misc**
|
||||
- Loc updates
|
||||
|
||||
@@ -30,20 +30,23 @@ internal sealed unsafe class Chat : IDisposable
|
||||
private readonly delegate* unmanaged<RaptureLogModule*, ushort, Utf8String*, Utf8String*, ulong, ulong, ushort, byte, int, byte, void> PrintTellNative = null!;
|
||||
|
||||
[Signature("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D 8C 24 ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01")]
|
||||
private readonly delegate* unmanaged<NetworkModule*, ulong, ushort, Utf8String*, Utf8String*, ushort, ushort, bool> SendTellNative = null!;
|
||||
private readonly delegate* unmanaged<NetworkModule*, ulong, ushort, Utf8String*, Utf8String*, ushort, ushort, byte> SendTellNative = null!;
|
||||
|
||||
// Client::UI::AddonChatLog.OnRefresh
|
||||
[Signature("40 53 56 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 49 8B F0 8B FA", DetourName = nameof(ChatLogRefreshDetour))]
|
||||
private Hook<ChatLogRefreshDelegate>? ChatLogRefreshHook { get; init; }
|
||||
private delegate byte ChatLogRefreshDelegate(nint log, ushort eventId, AtkValue* value);
|
||||
|
||||
// Replace with CS version later
|
||||
[Signature("E8 ?? ?? ?? ?? EB 81 48 8B 1D", DetourName = nameof(ContextMenuTellInForayDetour))]
|
||||
private Hook<ContextMenuTellInForayDelegate>? ContextMenuTellInForayHook { get; set; }
|
||||
private delegate void ContextMenuTellInForayDelegate(RaptureShellModule* module, Utf8String* playerName, Utf8String* worldName, ushort worldId, ulong accountId, ulong contentId, ushort reason);
|
||||
|
||||
private Hook<AgentChatLog.Delegates.ChangeChannelName> ChangeChannelNameHook { get; init; }
|
||||
private Hook<RaptureShellModule.Delegates.ReplyInSelectedChatMode>? ReplyInSelectedChatModeHook { get; init; }
|
||||
private Hook<RaptureShellModule.Delegates.SetContextTellTarget>? SetChatLogTellTargetHook { get; init; }
|
||||
private Hook<RaptureShellModule.Delegates.SetContextTellTargetInForay>? EurekaContextMenuTellHook { get; init; }
|
||||
|
||||
// Pointers
|
||||
|
||||
[Signature("48 8D 35 ?? ?? ?? ?? 8B 05", ScanType = ScanType.StaticAddress)]
|
||||
private readonly char* CurrentCharacter = null!;
|
||||
|
||||
@@ -75,6 +78,7 @@ internal sealed unsafe class Chat : IDisposable
|
||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
|
||||
ChatLogRefreshHook?.Enable();
|
||||
ContextMenuTellInForayHook?.Enable();
|
||||
|
||||
ChangeChannelNameHook = Plugin.GameInteropProvider.HookFromAddress<AgentChatLog.Delegates.ChangeChannelName>(AgentChatLog.MemberFunctionPointers.ChangeChannelName, ChangeChannelNameDetour);
|
||||
ChangeChannelNameHook.Enable();
|
||||
@@ -85,9 +89,6 @@ internal sealed unsafe class Chat : IDisposable
|
||||
SetChatLogTellTargetHook = Plugin.GameInteropProvider.HookFromAddress<RaptureShellModule.Delegates.SetContextTellTarget>(RaptureShellModule.MemberFunctionPointers.SetContextTellTarget, SetContextTellTarget);
|
||||
SetChatLogTellTargetHook.Enable();
|
||||
|
||||
// EurekaContextMenuTellHook = Plugin.GameInteropProvider.HookFromAddress<RaptureShellModule.Delegates.SetContextTellTargetInForay>(RaptureShellModule.MemberFunctionPointers.SetContextTellTargetInForay, SetContextTellTargetInForay);
|
||||
// EurekaContextMenuTellHook.Enable();
|
||||
|
||||
Plugin.ClientState.Login += Login;
|
||||
Login();
|
||||
}
|
||||
@@ -100,7 +101,7 @@ internal sealed unsafe class Chat : IDisposable
|
||||
ReplyInSelectedChatModeHook?.Dispose();
|
||||
ChangeChannelNameHook?.Dispose();
|
||||
ChatLogRefreshHook?.Dispose();
|
||||
EurekaContextMenuTellHook?.Dispose();
|
||||
ContextMenuTellInForayHook?.Dispose();
|
||||
}
|
||||
|
||||
internal string? GetLinkshellName(uint idx)
|
||||
@@ -213,6 +214,11 @@ internal sealed unsafe class Chat : IDisposable
|
||||
|
||||
try
|
||||
{
|
||||
// We already called this function once, so we skip the duplicated call
|
||||
// Also return the original value here so that vanilla chat receives all information
|
||||
if (Plugin.ChatLogWindow.TellSpecial)
|
||||
return ChatLogRefreshHook!.Original(log, eventId, value);
|
||||
|
||||
Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(null)) { AddIfNotPresent = addIfNotPresent, });
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -294,35 +300,34 @@ internal sealed unsafe class Chat : IDisposable
|
||||
return SetChatLogTellTargetHook!.Original(a1, playerName, worldName, worldId, accountId, contentId, reason, setChatType);
|
||||
}
|
||||
|
||||
// private void SetContextTellTargetInForay(RaptureShellModule* a1, Utf8String* playerName, Utf8String* worldName, ushort worldId, ulong accountId, ulong contentId, ushort reason)
|
||||
// {
|
||||
// Plugin.Log.Information($"SetContextTellTargetInForay");
|
||||
// if (!UsesTellTempChannel)
|
||||
// {
|
||||
// UsesTellTempChannel = true;
|
||||
// PreviousChannel = Channel.Channel;
|
||||
// }
|
||||
//
|
||||
// if (playerName != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// Plugin.Log.Information($"Name {playerName->ToString()} World {worldName->ToString()} WorldId {worldId} accountId {accountId} ContentId {contentId} Reason {reason} rapture reason {a1->TellReason}");
|
||||
// var target = new TellTarget(playerName->ToString(), worldId, contentId, (TellReason) reason);
|
||||
// Activated?.Invoke(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell))
|
||||
// {
|
||||
// TellReason = (TellReason) reason,
|
||||
// TellTarget = target,
|
||||
// });
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Plugin.Log.Error(ex, "Error in chat Activated event");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// EurekaContextMenuTellHook!.Original(a1, playerName, worldName, worldId, accountId, contentId, reason);
|
||||
// }
|
||||
private void ContextMenuTellInForayDetour(RaptureShellModule* a1, Utf8String* playerName, Utf8String* worldName, ushort worldId, ulong accountId, ulong contentId, ushort reason)
|
||||
{
|
||||
if (!UsesTellTempChannel)
|
||||
{
|
||||
UsesTellTempChannel = true;
|
||||
PreviousChannel = Channel.Channel;
|
||||
}
|
||||
|
||||
if (playerName != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var target = new TellTarget(playerName->ToString(), worldId, contentId, (TellReason) reason);
|
||||
Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell))
|
||||
{
|
||||
TellReason = (TellReason) reason,
|
||||
TellTarget = target,
|
||||
TellSpecial = true,
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Plugin.Log.Error(ex, "Error in chat Activated event");
|
||||
}
|
||||
}
|
||||
|
||||
ContextMenuTellInForayHook!.Original(a1, playerName, worldName, worldId, accountId, contentId, reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the channel is any non-linkshell channel, or if the
|
||||
@@ -457,6 +462,16 @@ internal sealed unsafe class Chat : IDisposable
|
||||
return new TellHistoryInfo(name, world, contentId);
|
||||
}
|
||||
|
||||
internal void SendTellUsingCommandInner(byte[] message)
|
||||
{
|
||||
var mes = new Utf8String(message);
|
||||
|
||||
RaptureShellModule.Instance()->ExecuteCommandInner(&mes, UIModule.Instance());
|
||||
RaptureAtkModule.Instance()->ClearFocus(); // Clear the focus of vanilla chat that was still active
|
||||
|
||||
mes.Dtor(true);
|
||||
}
|
||||
|
||||
internal void SendTell(TellReason reason, ulong contentId, string name, ushort homeWorld, byte[] message, string rawText)
|
||||
{
|
||||
var uName = Utf8String.FromString(name);
|
||||
@@ -470,15 +485,19 @@ internal sealed unsafe class Chat : IDisposable
|
||||
var logModule = RaptureLogModule.Instance();
|
||||
var networkModule = Framework.Instance()->GetNetworkModuleProxy()->NetworkModule;
|
||||
|
||||
// TODO: Remap TellReasons
|
||||
// // TODO: Remap TellReasons
|
||||
if (reason == TellReason.Direct)
|
||||
reason = TellReason.Friend;
|
||||
|
||||
var ok = SendTellNative(networkModule, contentId, homeWorld, uName, encoded, (ushort) reason, homeWorld);
|
||||
if (ok)
|
||||
if (ok == 1)
|
||||
{
|
||||
PrintTellNative(logModule, 33, uName, &decodedUtf8String, 0, contentId, homeWorld, 255, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Plugin.ChatGui.PrintError(Language.Chat_SendTell_Error);
|
||||
}
|
||||
|
||||
encoded->Dtor(true);
|
||||
uName->Dtor(true);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using ChatTwo.Resources;
|
||||
using ChatTwo.Util;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
||||
|
||||
namespace ChatTwo.GameFunctions;
|
||||
|
||||
internal sealed unsafe class Party
|
||||
internal static unsafe class Party
|
||||
{
|
||||
internal static void InviteSameWorld(string name, ushort world, ulong contentId)
|
||||
{
|
||||
@@ -20,13 +22,23 @@ internal sealed unsafe class Party
|
||||
// if they're not on that world, it will fail
|
||||
// pass 0 and it will work on any world EXCEPT for the world the
|
||||
// current player is on
|
||||
if (contentId != 0)
|
||||
if (contentId == 0)
|
||||
{
|
||||
WrapperUtil.AddNotification(Language.PartyInvite_NoId, NotificationType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
InfoProxyPartyInvite.Instance()->InviteToPartyContentId(contentId, 0);
|
||||
}
|
||||
|
||||
internal static void InviteInInstance(ulong contentId)
|
||||
{
|
||||
if (contentId != 0)
|
||||
if (contentId == 0)
|
||||
{
|
||||
WrapperUtil.AddNotification(Language.PartyInvite_NoId, NotificationType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
InfoProxyPartyInvite.Instance()->InviteToPartyInInstance(contentId);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ internal sealed class ChatActivatedArgs
|
||||
internal ChannelSwitchInfo ChannelSwitchInfo { get; }
|
||||
internal TellReason? TellReason { get; init; }
|
||||
internal TellTarget? TellTarget { get; init; }
|
||||
internal bool TellSpecial { get; init; } // specific to Eureka/Bozja/Zadnor
|
||||
|
||||
internal ChatActivatedArgs(ChannelSwitchInfo channelSwitchInfo)
|
||||
{
|
||||
|
||||
Generated
+9
@@ -3416,6 +3416,15 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to find ID for this message, please try another one..
|
||||
/// </summary>
|
||||
internal static string PartyInvite_NoId {
|
||||
get {
|
||||
return ResourceManager.GetString("PartyInvite_NoId", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Discard.
|
||||
/// </summary>
|
||||
|
||||
@@ -964,6 +964,9 @@
|
||||
<data name="Context_CopySuccess">
|
||||
<value>Copied message to clipboard</value>
|
||||
</data>
|
||||
<data name="PartyInvite_NoId">
|
||||
<value>Unable to find ID for this message, please try another one.</value>
|
||||
</data>
|
||||
<data name="Context_CopyLink" xml:space="preserve">
|
||||
<value>Copy link to clipboard</value>
|
||||
</data>
|
||||
|
||||
@@ -59,6 +59,7 @@ public sealed class ChatLogWindow : Window
|
||||
private int LastTab { get; set; }
|
||||
private InputChannel? TempChannel;
|
||||
private TellTarget? TellTarget;
|
||||
public bool TellSpecial;
|
||||
private readonly Stopwatch LastResize = new();
|
||||
private AutoCompleteInfo? AutoCompleteInfo;
|
||||
private bool AutoCompleteOpen;
|
||||
@@ -145,6 +146,8 @@ public sealed class ChatLogWindow : Window
|
||||
|
||||
internal void Activated(ChatActivatedArgs args)
|
||||
{
|
||||
TellSpecial = args.TellSpecial;
|
||||
|
||||
Activate = true;
|
||||
PlayedClosingSound = false;
|
||||
if (Plugin.Config.PlaySounds)
|
||||
@@ -857,6 +860,21 @@ public sealed class ChatLogWindow : Window
|
||||
AddBacklog(trimmed);
|
||||
InputBacklogIdx = -1;
|
||||
|
||||
if (TellSpecial)
|
||||
{
|
||||
var tellBytes = Encoding.UTF8.GetBytes(trimmed);
|
||||
AutoTranslate.ReplaceWithPayload(ref tellBytes);
|
||||
|
||||
Plugin.Functions.Chat.SendTellUsingCommandInner(tellBytes);
|
||||
|
||||
TellSpecial = false;
|
||||
if (TempChannel is InputChannel.Tell)
|
||||
TellTarget = null;
|
||||
|
||||
Chat = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trimmed.StartsWith('/'))
|
||||
{
|
||||
if (TellTarget != null)
|
||||
|
||||
Reference in New Issue
Block a user