Fix UI + Amélioration AutoDetect & Self Analyse + Update Penumbra API

This commit is contained in:
2025-10-12 12:42:31 +02:00
parent d4a46910f9
commit d225a3844a
14 changed files with 763 additions and 95 deletions

View File

@@ -0,0 +1,209 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Plugin.Services;
using Lumina.Excel.Sheets;
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Models;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Services.AutoDetect;
public sealed class AutoDetectSuppressionService : IHostedService, IMediatorSubscriber
{
private static readonly string[] ContentTypeKeywords =
[
"dungeon",
"donjon",
"raid",
"trial",
"défi",
"front",
"frontline",
"pvp",
"jcj",
"conflict",
"conflit"
];
private readonly ILogger<AutoDetectSuppressionService> _logger;
private readonly MareConfigService _configService;
private readonly IClientState _clientState;
private readonly IDataManager _dataManager;
private readonly MareMediator _mediator;
private readonly DalamudUtilService _dalamudUtilService;
private bool _isSuppressed;
private bool _hasSavedState;
private bool _savedDiscoveryEnabled;
private bool _savedAllowRequests;
private bool _suppressionWarningShown;
public bool IsSuppressed => _isSuppressed;
public AutoDetectSuppressionService(ILogger<AutoDetectSuppressionService> logger,
MareConfigService configService, IClientState clientState,
IDataManager dataManager, DalamudUtilService dalamudUtilService, MareMediator mediator)
{
_logger = logger;
_configService = configService;
_clientState = clientState;
_dataManager = dataManager;
_dalamudUtilService = dalamudUtilService;
_mediator = mediator;
}
public MareMediator Mediator => _mediator;
public Task StartAsync(CancellationToken cancellationToken)
{
_mediator.Subscribe<ZoneSwitchEndMessage>(this, _ => UpdateSuppressionState());
_mediator.Subscribe<DalamudLoginMessage>(this, _ => UpdateSuppressionState());
_mediator.Subscribe<DalamudLogoutMessage>(this, _ => ClearSuppression());
UpdateSuppressionState();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_mediator.UnsubscribeAll(this);
return Task.CompletedTask;
}
private void UpdateSuppressionState()
{
_ = _dalamudUtilService.RunOnFrameworkThread(() =>
{
try
{
if (!_clientState.IsLoggedIn || _clientState.LocalPlayer == null)
{
ClearSuppression();
return;
}
uint territoryId = _clientState.TerritoryType;
bool shouldSuppress = ShouldSuppressForTerritory(territoryId);
ApplySuppression(shouldSuppress, territoryId);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to update AutoDetect suppression state");
}
});
}
private void ApplySuppression(bool shouldSuppress, uint territoryId)
{
if (shouldSuppress)
{
if (!_isSuppressed)
{
_savedDiscoveryEnabled = _configService.Current.EnableAutoDetectDiscovery;
_savedAllowRequests = _configService.Current.AllowAutoDetectPairRequests;
_hasSavedState = true;
_isSuppressed = true;
}
bool changed = false;
if (_configService.Current.EnableAutoDetectDiscovery)
{
_configService.Current.EnableAutoDetectDiscovery = false;
changed = true;
}
if (_configService.Current.AllowAutoDetectPairRequests)
{
_configService.Current.AllowAutoDetectPairRequests = false;
changed = true;
}
if (changed)
{
_logger.LogInformation("AutoDetect temporarily disabled in instanced content (territory {territoryId}).", territoryId);
if (!_suppressionWarningShown)
{
_suppressionWarningShown = true;
const string warningText = "Zone instanciée détectée : les fonctions AutoDetect/Nearby sont coupées pour économiser de la bande passante.";
_mediator.Publish(new DualNotificationMessage("AutoDetect désactivé",
warningText,
NotificationType.Warning, TimeSpan.FromSeconds(5)));
}
}
return;
}
else
{
if (!_isSuppressed) return;
bool changed = false;
bool wasSuppressed = _suppressionWarningShown;
if (_hasSavedState)
{
if (_configService.Current.EnableAutoDetectDiscovery != _savedDiscoveryEnabled)
{
_configService.Current.EnableAutoDetectDiscovery = _savedDiscoveryEnabled;
changed = true;
}
if (_configService.Current.AllowAutoDetectPairRequests != _savedAllowRequests)
{
_configService.Current.AllowAutoDetectPairRequests = _savedAllowRequests;
changed = true;
}
}
_isSuppressed = false;
_hasSavedState = false;
_suppressionWarningShown = false;
if (changed || wasSuppressed)
{
_logger.LogInformation("AutoDetect restored after leaving instanced content (territory {territoryId}).", territoryId);
const string restoredText = "Vous avez quitté la zone instanciée : AutoDetect/Nearby fonctionnent de nouveau.";
_mediator.Publish(new DualNotificationMessage("AutoDetect réactivé",
restoredText,
NotificationType.Info, TimeSpan.FromSeconds(5)));
}
}
}
private void ClearSuppression()
{
if (!_isSuppressed) return;
_isSuppressed = false;
if (_hasSavedState)
{
_configService.Current.EnableAutoDetectDiscovery = _savedDiscoveryEnabled;
_configService.Current.AllowAutoDetectPairRequests = _savedAllowRequests;
}
_hasSavedState = false;
_suppressionWarningShown = false;
}
private bool ShouldSuppressForTerritory(uint territoryId)
{
if (territoryId == 0) return false;
var cfcSheet = _dataManager.GetExcelSheet<ContentFinderCondition>();
if (cfcSheet == null) return false;
var cfc = cfcSheet.FirstOrDefault(c => c.TerritoryType.RowId == territoryId);
if (cfc.RowId == 0) return false;
if (MatchesSuppressionKeyword(cfc.Name.ToString())) return true;
var contentType = cfc.ContentType.Value;
if (contentType.RowId == 0) return false;
return MatchesSuppressionKeyword(contentType.Name.ToString());
}
private static bool MatchesSuppressionKeyword(string? text)
{
if (string.IsNullOrWhiteSpace(text)) return false;
return ContentTypeKeywords.Any(keyword => text.Contains(keyword, StringComparison.OrdinalIgnoreCase));
}
}