v1.0.5: Exact match trigger option; cross-world Friends for auto-accept
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [1.0.5] - 2025-02-21
|
||||
|
||||
### Added
|
||||
|
||||
- **Exact match option** – When enabled, the entire message must exactly match the trigger (e.g. `!` triggers only on messages that are just `!`, not `hello!`).
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Cross-world friends for auto-accept** – Auto-accept now works when a friend invites you from another world or while visiting another world (fallback to name-only match when world ID differs).
|
||||
|
||||
## [1.0.4] - 2025-02-20
|
||||
|
||||
### Added
|
||||
|
||||
@@ -24,6 +24,13 @@ public class FriendFcCache
|
||||
return Friends.Exists(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && p.WorldId == worldId);
|
||||
}
|
||||
|
||||
/// <summary>Name-only match for cross-world friends (e.g. friend visiting another world).</summary>
|
||||
public bool IsInFriendsByName(string name)
|
||||
{
|
||||
if (Friends == null || Friends.Count == 0) return false;
|
||||
return Friends.Exists(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public bool IsInFreeCompany(string name, ushort worldId)
|
||||
{
|
||||
if (FreeCompanyMembers == null || FreeCompanyMembers.Count == 0) return false;
|
||||
|
||||
@@ -15,6 +15,12 @@ public class HSRToolsConfiguration
|
||||
/// </summary>
|
||||
public bool CaseSensitive { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// When true, the entire message must exactly match the trigger (after trimming).
|
||||
/// When false, the message only needs to contain the trigger anywhere.
|
||||
/// </summary>
|
||||
public bool TriggerExactMatch { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to monitor Free Company chat.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Dalamud.NET.Sdk/14.0.1">
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Version>1.0.4.0</Version>
|
||||
<Version>1.0.5.0</Version>
|
||||
<Author>Knack117</Author>
|
||||
<Name>HSRTools</Name>
|
||||
<InternalName>HSRTools</InternalName>
|
||||
|
||||
@@ -126,7 +126,7 @@ public sealed class AutoAcceptPartyService
|
||||
if (_config.Debug)
|
||||
_log.Info($"[AutoAccept] Inviter: '{inviterName}' (worldId={inviterWorldId})");
|
||||
|
||||
var isFriend = _config.AutoAcceptFromFriends && (IsFriendCached(inviterName, inviterWorldId) || IsFriend(inviterName, inviterWorldId));
|
||||
var isFriend = _config.AutoAcceptFromFriends && (IsFriendCached(inviterName, inviterWorldId) || IsFriend(inviterName, inviterWorldId) || IsFriendCachedByName(inviterName));
|
||||
var isFcMember = _config.AutoAcceptFromFreeCompany && (IsFreeCompanyMemberCached(inviterName, inviterWorldId) || IsFreeCompanyMember(inviterName, inviterWorldId));
|
||||
|
||||
if (_config.Debug)
|
||||
@@ -159,6 +159,7 @@ public sealed class AutoAcceptPartyService
|
||||
}
|
||||
|
||||
private bool IsFriendCached(string characterName, ushort worldId) => _cacheService.IsInFriends(characterName, worldId);
|
||||
private bool IsFriendCachedByName(string characterName) => _cacheService.IsInFriendsByName(characterName);
|
||||
private bool IsFreeCompanyMemberCached(string characterName, ushort worldId) => _cacheService.IsInFreeCompany(characterName, worldId);
|
||||
|
||||
private unsafe bool IsFriend(string characterName, ushort worldId)
|
||||
|
||||
@@ -150,8 +150,16 @@ public sealed class ChatMonitorService
|
||||
var trigger = _config.TriggerText;
|
||||
var comparison = _config.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||
|
||||
if (_config.TriggerExactMatch)
|
||||
{
|
||||
if (!messageText.Trim().Equals(trigger, comparison))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!messageText.Contains(trigger, comparison))
|
||||
return;
|
||||
}
|
||||
|
||||
// Read log module first for non-tells (sender data only valid at callback start; overwritten quickly).
|
||||
var (logContentId, logWorldId) = type != XivChatType.TellIncoming
|
||||
|
||||
@@ -86,6 +86,12 @@ public sealed class FriendFcCacheService
|
||||
lock (_cacheLock) { return _cache.IsInFriends(name, worldId); }
|
||||
}
|
||||
|
||||
/// <summary>Name-only match for cross-world friends (friend visiting another world).</summary>
|
||||
public bool IsInFriendsByName(string name)
|
||||
{
|
||||
lock (_cacheLock) { return _cache.IsInFriendsByName(name); }
|
||||
}
|
||||
|
||||
public bool IsInFreeCompany(string name, ushort worldId)
|
||||
{
|
||||
lock (_cacheLock) { return _cache.IsInFreeCompany(name, worldId); }
|
||||
|
||||
@@ -9,6 +9,7 @@ public sealed class ConfigWindow : Window
|
||||
private readonly HSRToolsConfiguration _config;
|
||||
private string _triggerTextInput = string.Empty;
|
||||
private bool _caseSensitive;
|
||||
private bool _triggerExactMatch;
|
||||
private bool _monitorFreeCompany;
|
||||
private bool _monitorLinkShell;
|
||||
private bool _monitorCrossWorldLinkShell;
|
||||
@@ -32,6 +33,7 @@ public sealed class ConfigWindow : Window
|
||||
{
|
||||
_triggerTextInput = _config.TriggerText ?? string.Empty;
|
||||
_caseSensitive = _config.CaseSensitive;
|
||||
_triggerExactMatch = _config.TriggerExactMatch;
|
||||
_monitorFreeCompany = _config.MonitorFreeCompany;
|
||||
_monitorLinkShell = _config.MonitorLinkShell;
|
||||
_monitorCrossWorldLinkShell = _config.MonitorCrossWorldLinkShell;
|
||||
@@ -51,6 +53,7 @@ public sealed class ConfigWindow : Window
|
||||
{
|
||||
_config.TriggerText = "inv";
|
||||
_config.CaseSensitive = false;
|
||||
_config.TriggerExactMatch = false;
|
||||
_config.MonitorFreeCompany = true;
|
||||
_config.MonitorLinkShell = true;
|
||||
_config.MonitorCrossWorldLinkShell = true;
|
||||
@@ -74,8 +77,10 @@ public sealed class ConfigWindow : Window
|
||||
if (ImGui.InputText("##trigger", ref _triggerTextInput, 128))
|
||||
_config.TriggerText = _triggerTextInput.Trim();
|
||||
|
||||
ImGui.Checkbox("Case sensitive", ref _caseSensitive);
|
||||
if (ImGui.Checkbox("Case sensitive", ref _caseSensitive))
|
||||
_config.CaseSensitive = _caseSensitive;
|
||||
if (ImGui.Checkbox("Exact match (whole message must equal trigger)", ref _triggerExactMatch))
|
||||
_config.TriggerExactMatch = _triggerExactMatch;
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("Monitor these channels:");
|
||||
|
||||
Reference in New Issue
Block a user