Removed obselete functions, changed download bars a bit. renamed files correctly

This commit is contained in:
cake
2025-11-30 08:09:58 +01:00
parent cab13874d8
commit a9181d2592
24 changed files with 357 additions and 197 deletions

View File

@@ -636,8 +636,7 @@ public sealed class FileCacheManager : IHostedService
private FileCacheEntity? CreateFileCacheEntity(FileInfo fileInfo, string prefixedPath, string? hash = null) private FileCacheEntity? CreateFileCacheEntity(FileInfo fileInfo, string prefixedPath, string? hash = null)
{ {
var algo = Crypto.DetectAlgo(Path.GetFileNameWithoutExtension(fileInfo.Name)); hash ??= Crypto.ComputeFileHash(fileInfo.FullName, Crypto.HashAlgo.Sha1);
hash ??= Crypto.ComputeFileHash(fileInfo.FullName, algo);
var entity = new FileCacheEntity(hash, prefixedPath, fileInfo.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture), fileInfo.Length); var entity = new FileCacheEntity(hash, prefixedPath, fileInfo.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture), fileInfo.Length);
entity = ReplacePathPrefixes(entity); entity = ReplacePathPrefixes(entity);
AddHashedFile(entity); AddHashedFile(entity);

View File

@@ -1,7 +1,7 @@
using LightlessSync.FileCache; using LightlessSync.FileCache;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.Services;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Services.PairProcessing;
using LightlessSync.Services.TextureCompression; using LightlessSync.Services.TextureCompression;
using LightlessSync.WebAPI.Files; using LightlessSync.WebAPI.Files;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@@ -10,6 +10,7 @@ using LightlessSync.PlayerData.Handlers;
using LightlessSync.Services; using LightlessSync.Services;
using LightlessSync.Services.Events; using LightlessSync.Services.Events;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Services.PairProcessing;
using LightlessSync.Services.ServerConfiguration; using LightlessSync.Services.ServerConfiguration;
using LightlessSync.Services.TextureCompression; using LightlessSync.Services.TextureCompression;
using LightlessSync.Utils; using LightlessSync.Utils;

View File

@@ -38,6 +38,8 @@ using System.IO;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Reflection; using System.Reflection;
using OtterTex; using OtterTex;
using LightlessSync.Services.LightFinder;
using LightlessSync.Services.PairProcessing;
namespace LightlessSync; namespace LightlessSync;
@@ -189,8 +191,8 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<PairRequestService>(), s.GetRequiredService<PairRequestService>(),
s.GetRequiredService<ApiController>(), s.GetRequiredService<ApiController>(),
s.GetRequiredService<ServerConfigurationManager>(), s.GetRequiredService<ServerConfigurationManager>(),
s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightFinderService>(),
s.GetRequiredService<BroadcastScannerService>(), s.GetRequiredService<LightFinderScannerService>(),
s.GetRequiredService<DalamudUtilService>())); s.GetRequiredService<DalamudUtilService>()));
collection.AddSingleton(s => new PairCoordinator( collection.AddSingleton(s => new PairCoordinator(
s.GetRequiredService<ILogger<PairCoordinator>>(), s.GetRequiredService<ILogger<PairCoordinator>>(),
@@ -201,15 +203,15 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<PairLedger>(), s.GetRequiredService<PairLedger>(),
s.GetRequiredService<ServerConfigurationManager>())); s.GetRequiredService<ServerConfigurationManager>()));
collection.AddSingleton<RedrawManager>(); collection.AddSingleton<RedrawManager>();
collection.AddSingleton<BroadcastService>(); collection.AddSingleton<LightFinderService>();
collection.AddSingleton(addonLifecycle); collection.AddSingleton(addonLifecycle);
collection.AddSingleton(p => new ContextMenuService(contextMenu, pluginInterface, gameData, p.GetRequiredService<ILogger<ContextMenuService>>(), p.GetRequiredService<DalamudUtilService>(), p.GetRequiredService<ApiController>(), objectTable, collection.AddSingleton(p => new ContextMenuService(contextMenu, pluginInterface, gameData, p.GetRequiredService<ILogger<ContextMenuService>>(), p.GetRequiredService<DalamudUtilService>(), p.GetRequiredService<ApiController>(), objectTable,
p.GetRequiredService<LightlessConfigService>(), p.GetRequiredService<LightlessConfigService>(),
p.GetRequiredService<PairRequestService>(), p.GetRequiredService<PairRequestService>(),
p.GetRequiredService<PairUiService>(), p.GetRequiredService<PairUiService>(),
clientState, clientState,
p.GetRequiredService<BroadcastScannerService>(), p.GetRequiredService<LightFinderScannerService>(),
p.GetRequiredService<BroadcastService>(), p.GetRequiredService<LightFinderService>(),
p.GetRequiredService<LightlessProfileManager>(), p.GetRequiredService<LightlessProfileManager>(),
p.GetRequiredService<LightlessMediator>())); p.GetRequiredService<LightlessMediator>()));
collection.AddSingleton((s) => new IpcCallerPenumbra(s.GetRequiredService<ILogger<IpcCallerPenumbra>>(), pluginInterface, collection.AddSingleton((s) => new IpcCallerPenumbra(s.GetRequiredService<ILogger<IpcCallerPenumbra>>(), pluginInterface,
@@ -288,7 +290,7 @@ public sealed class Plugin : IDalamudPlugin
clientState, clientState,
sp.GetRequiredService<LightlessMediator>())); sp.GetRequiredService<LightlessMediator>()));
collection.AddSingleton<HubFactory>(); collection.AddSingleton<HubFactory>();
collection.AddSingleton(s => new BroadcastScannerService(s.GetRequiredService<ILogger<BroadcastScannerService>>(), framework, s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<NameplateHandler>(), s.GetRequiredService<ActorObjectService>())); collection.AddSingleton(s => new LightFinderScannerService(s.GetRequiredService<ILogger<LightFinderScannerService>>(), framework, s.GetRequiredService<LightFinderService>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<NameplateHandler>(), s.GetRequiredService<ActorObjectService>()));
// add scoped services // add scoped services
@@ -314,8 +316,8 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<FileDialogManager>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<FileDialogManager>(),
s.GetRequiredService<LightlessProfileManager>(), s.GetRequiredService<ProfileTagService>(), s.GetRequiredService<PerformanceCollectorService>())); s.GetRequiredService<LightlessProfileManager>(), s.GetRequiredService<ProfileTagService>(), s.GetRequiredService<PerformanceCollectorService>()));
collection.AddScoped<WindowMediatorSubscriberBase, PopupHandler>(); collection.AddScoped<WindowMediatorSubscriberBase, PopupHandler>();
collection.AddScoped<WindowMediatorSubscriberBase, BroadcastUI>((s) => new BroadcastUI(s.GetRequiredService<ILogger<BroadcastUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>())); collection.AddScoped<WindowMediatorSubscriberBase, LightFinderUI>((s) => new LightFinderUI(s.GetRequiredService<ILogger<LightFinderUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<LightFinderService>(), s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<LightFinderScannerService>()));
collection.AddScoped<WindowMediatorSubscriberBase, SyncshellFinderUI>((s) => new SyncshellFinderUI(s.GetRequiredService<ILogger<SyncshellFinderUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>(), s.GetRequiredService<PairUiService>(), s.GetRequiredService<DalamudUtilService>())); collection.AddScoped<WindowMediatorSubscriberBase, SyncshellFinderUI>((s) => new SyncshellFinderUI(s.GetRequiredService<ILogger<SyncshellFinderUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<LightFinderService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<LightFinderScannerService>(), s.GetRequiredService<PairUiService>(), s.GetRequiredService<DalamudUtilService>()));
collection.AddScoped<IPopupHandler, BanUserPopupHandler>(); collection.AddScoped<IPopupHandler, BanUserPopupHandler>();
collection.AddScoped<WindowMediatorSubscriberBase, LightlessNotificationUi>((s) => collection.AddScoped<WindowMediatorSubscriberBase, LightlessNotificationUi>((s) =>
new LightlessNotificationUi( new LightlessNotificationUi(
@@ -343,7 +345,7 @@ public sealed class Plugin : IDalamudPlugin
collection.AddScoped((s) => new NameplateService(s.GetRequiredService<ILogger<NameplateService>>(), s.GetRequiredService<LightlessConfigService>(), clientState, gameGui, objectTable, gameInteropProvider, collection.AddScoped((s) => new NameplateService(s.GetRequiredService<ILogger<NameplateService>>(), s.GetRequiredService<LightlessConfigService>(), clientState, gameGui, objectTable, gameInteropProvider,
s.GetRequiredService<LightlessMediator>(),s.GetRequiredService<PairUiService>())); s.GetRequiredService<LightlessMediator>(),s.GetRequiredService<PairUiService>()));
collection.AddScoped((s) => new NameplateHandler(s.GetRequiredService<ILogger<NameplateHandler>>(), addonLifecycle, gameGui, collection.AddScoped((s) => new NameplateHandler(s.GetRequiredService<ILogger<NameplateHandler>>(), addonLifecycle, gameGui,
s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<LightlessMediator>(), clientState, s.GetRequiredService<PairUiService>())); s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<LightlessMediator>(), objectTable, s.GetRequiredService<PairUiService>()));
collection.AddHostedService(p => p.GetRequiredService<ConfigurationSaveService>()); collection.AddHostedService(p => p.GetRequiredService<ConfigurationSaveService>());
collection.AddHostedService(p => p.GetRequiredService<ActorObjectService>()); collection.AddHostedService(p => p.GetRequiredService<ActorObjectService>());
@@ -359,7 +361,7 @@ public sealed class Plugin : IDalamudPlugin
collection.AddHostedService(p => p.GetRequiredService<IpcProvider>()); collection.AddHostedService(p => p.GetRequiredService<IpcProvider>());
collection.AddHostedService(p => p.GetRequiredService<LightlessPlugin>()); collection.AddHostedService(p => p.GetRequiredService<LightlessPlugin>());
collection.AddHostedService(p => p.GetRequiredService<ContextMenuService>()); collection.AddHostedService(p => p.GetRequiredService<ContextMenuService>());
collection.AddHostedService(p => p.GetRequiredService<BroadcastService>()); collection.AddHostedService(p => p.GetRequiredService<LightFinderService>());
}) })
.Build(); .Build();

View File

@@ -116,7 +116,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
{ {
foreach (var entry in objectEntries.Values) foreach (var entry in objectEntries.Values)
{ {
if (!entry.FilePaths.Any(path => normalized.Contains(path))) if (!entry.FilePaths.Exists(path => normalized.Contains(path)))
{ {
continue; continue;
} }

View File

@@ -131,7 +131,7 @@ public sealed class CommandManagerService : IDisposable
} }
else if (string.Equals(splitArgs[0], "finder", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(splitArgs[0], "finder", StringComparison.OrdinalIgnoreCase))
{ {
_mediator.Publish(new UiToggleMessage(typeof(BroadcastUI))); _mediator.Publish(new UiToggleMessage(typeof(LightFinderUI)));
} }
} }
} }

View File

@@ -12,6 +12,7 @@ using LightlessSync.UI.Services;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using LightlessSync.UI; using LightlessSync.UI;
using LightlessSync.Services.LightFinder;
namespace LightlessSync.Services; namespace LightlessSync.Services;
@@ -28,8 +29,8 @@ internal class ContextMenuService : IHostedService
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly IObjectTable _objectTable; private readonly IObjectTable _objectTable;
private readonly LightlessConfigService _configService; private readonly LightlessConfigService _configService;
private readonly BroadcastScannerService _broadcastScannerService; private readonly LightFinderScannerService _broadcastScannerService;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private readonly LightlessProfileManager _lightlessProfileManager; private readonly LightlessProfileManager _lightlessProfileManager;
private readonly LightlessMediator _mediator; private readonly LightlessMediator _mediator;
@@ -47,8 +48,8 @@ internal class ContextMenuService : IHostedService
PairRequestService pairRequestService, PairRequestService pairRequestService,
PairUiService pairUiService, PairUiService pairUiService,
IClientState clientState, IClientState clientState,
BroadcastScannerService broadcastScannerService, LightFinderScannerService broadcastScannerService,
BroadcastService broadcastService, LightFinderService broadcastService,
LightlessProfileManager lightlessProfileManager, LightlessProfileManager lightlessProfileManager,
LightlessMediator mediator) LightlessMediator mediator)
{ {

View File

@@ -14,14 +14,12 @@ using LightlessSync.Interop;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Factories; using LightlessSync.PlayerData.Factories;
using LightlessSync.PlayerData.Handlers; using LightlessSync.PlayerData.Handlers;
using LightlessSync.PlayerData.Pairs;
using LightlessSync.Services.ActorTracking; using LightlessSync.Services.ActorTracking;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Utils; using LightlessSync.Utils;
using Lumina.Excel.Sheets; using Lumina.Excel.Sheets;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Linq;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
@@ -249,7 +247,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public bool GetIsPlayerPresent() public bool GetIsPlayerPresent()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid(); return _objectTable.LocalPlayer != null && _objectTable.LocalPlayer.IsValid();
} }
public async Task<bool> GetIsPlayerPresentAsync() public async Task<bool> GetIsPlayerPresentAsync()
@@ -293,7 +291,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IPlayerCharacter GetPlayerCharacter() public IPlayerCharacter GetPlayerCharacter()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer!; return _objectTable.LocalPlayer!;
} }
public IntPtr GetPlayerCharacterFromCachedTableByIdent(string characterName) public IntPtr GetPlayerCharacterFromCachedTableByIdent(string characterName)
@@ -306,7 +304,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public string GetPlayerName() public string GetPlayerName()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer?.Name.ToString() ?? "--"; return _objectTable.LocalPlayer?.Name.ToString() ?? "--";
} }
public async Task<string> GetPlayerNameAsync() public async Task<string> GetPlayerNameAsync()
@@ -339,7 +337,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IntPtr GetPlayerPtr() public IntPtr GetPlayerPtr()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer?.Address ?? IntPtr.Zero; return _objectTable.LocalPlayer?.Address ?? IntPtr.Zero;
} }
public async Task<IntPtr> GetPlayerPointerAsync() public async Task<IntPtr> GetPlayerPointerAsync()
@@ -350,13 +348,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public uint GetHomeWorldId() public uint GetHomeWorldId()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer?.HomeWorld.RowId ?? 0; return _objectTable.LocalPlayer?.HomeWorld.RowId ?? 0;
} }
public uint GetWorldId() public uint GetWorldId()
{ {
EnsureIsOnFramework(); EnsureIsOnFramework();
return _clientState.LocalPlayer!.CurrentWorld.RowId; return _objectTable.LocalPlayer!.CurrentWorld.RowId;
} }
public unsafe LocationInfo GetMapData() public unsafe LocationInfo GetMapData()
@@ -365,8 +363,8 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
var agentMap = AgentMap.Instance(); var agentMap = AgentMap.Instance();
var houseMan = HousingManager.Instance(); var houseMan = HousingManager.Instance();
uint serverId = 0; uint serverId = 0;
if (_clientState.LocalPlayer == null) serverId = 0; if (_objectTable.LocalPlayer == null) serverId = 0;
else serverId = _clientState.LocalPlayer.CurrentWorld.RowId; else serverId = _objectTable.LocalPlayer.CurrentWorld.RowId;
uint mapId = agentMap == null ? 0 : agentMap->CurrentMapId; uint mapId = agentMap == null ? 0 : agentMap->CurrentMapId;
uint territoryId = agentMap == null ? 0 : agentMap->CurrentTerritoryId; uint territoryId = agentMap == null ? 0 : agentMap->CurrentTerritoryId;
uint divisionId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentDivision()); uint divisionId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentDivision());
@@ -494,7 +492,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_framework.Update += FrameworkOnUpdate; _framework.Update += FrameworkOnUpdate;
if (IsLoggedIn) if (IsLoggedIn)
{ {
_classJobId = _clientState.LocalPlayer!.ClassJob.RowId; _classJobId = _objectTable.LocalPlayer!.ClassJob.RowId;
} }
_logger.LogInformation("Started DalamudUtilService"); _logger.LogInformation("Started DalamudUtilService");
@@ -647,7 +645,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
private unsafe void FrameworkOnUpdateInternal() private unsafe void FrameworkOnUpdateInternal()
{ {
if ((_clientState.LocalPlayer?.IsDead ?? false) && _condition[ConditionFlag.BoundByDuty]) if ((_objectTable.LocalPlayer?.IsDead ?? false) && _condition[ConditionFlag.BoundByDuty])
{ {
return; return;
} }
@@ -805,7 +803,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
Mediator.Publish(new ResumeScanMessage(nameof(ConditionFlag.BetweenAreas))); Mediator.Publish(new ResumeScanMessage(nameof(ConditionFlag.BetweenAreas)));
} }
var localPlayer = _clientState.LocalPlayer; var localPlayer = _objectTable.LocalPlayer;
if (localPlayer != null) if (localPlayer != null)
{ {
_classJobId = localPlayer.ClassJob.RowId; _classJobId = localPlayer.ClassJob.RowId;

View File

@@ -5,15 +5,15 @@ using LightlessSync.Services.Mediator;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace LightlessSync.Services; namespace LightlessSync.Services.LightFinder;
public class BroadcastScannerService : DisposableMediatorSubscriberBase public class LightFinderScannerService : DisposableMediatorSubscriberBase
{ {
private readonly ILogger<BroadcastScannerService> _logger; private readonly ILogger<LightFinderScannerService> _logger;
private readonly ActorObjectService _actorTracker; private readonly ActorObjectService _actorTracker;
private readonly IFramework _framework; private readonly IFramework _framework;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private readonly NameplateHandler _nameplateHandler; private readonly NameplateHandler _nameplateHandler;
private readonly ConcurrentDictionary<string, BroadcastEntry> _broadcastCache = new(StringComparer.Ordinal); private readonly ConcurrentDictionary<string, BroadcastEntry> _broadcastCache = new(StringComparer.Ordinal);
@@ -37,9 +37,9 @@ public class BroadcastScannerService : DisposableMediatorSubscriberBase
public IReadOnlyDictionary<string, BroadcastEntry> BroadcastCache => _broadcastCache; public IReadOnlyDictionary<string, BroadcastEntry> BroadcastCache => _broadcastCache;
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID); public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
public BroadcastScannerService(ILogger<BroadcastScannerService> logger, public LightFinderScannerService(ILogger<LightFinderScannerService> logger,
IFramework framework, IFramework framework,
BroadcastService broadcastService, LightFinderService broadcastService,
LightlessMediator mediator, LightlessMediator mediator,
NameplateHandler nameplateHandler, NameplateHandler nameplateHandler,
ActorObjectService actorTracker) : base(logger, mediator) ActorObjectService actorTracker) : base(logger, mediator)

View File

@@ -1,21 +1,21 @@
using Dalamud.Interface; using Dalamud.Interface;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.UI;
using LightlessSync.UI.Models;
using LightlessSync.API.Dto.Group; using LightlessSync.API.Dto.Group;
using LightlessSync.API.Dto.User; using LightlessSync.API.Dto.User;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.UI;
using LightlessSync.UI.Models;
using LightlessSync.Utils; using LightlessSync.Utils;
using LightlessSync.WebAPI; using LightlessSync.WebAPI;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace LightlessSync.Services; namespace LightlessSync.Services.LightFinder;
public class BroadcastService : IHostedService, IMediatorSubscriber public class LightFinderService : IHostedService, IMediatorSubscriber
{ {
private readonly ILogger<BroadcastService> _logger; private readonly ILogger<LightFinderService> _logger;
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly LightlessMediator _mediator; private readonly LightlessMediator _mediator;
private readonly LightlessConfigService _config; private readonly LightlessConfigService _config;
@@ -44,7 +44,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
} }
} }
public BroadcastService(ILogger<BroadcastService> logger, LightlessMediator mediator, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController) public LightFinderService(ILogger<LightFinderService> logger, LightlessMediator mediator, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController)
{ {
_logger = logger; _logger = logger;
_mediator = mediator; _mediator = mediator;
@@ -281,7 +281,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
if (!msg.Enabled) if (!msg.Enabled)
{ {
ApplyBroadcastDisabled(forcePublish: true); ApplyBroadcastDisabled(forcePublish: true);
Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(BroadcastService), Services.Events.EventSeverity.Informational, $"Disabled Lightfinder for Player: {msg.HashedCid}"))); Mediator.Publish(new EventMessage(new Events.Event(nameof(LightFinderService), Services.Events.EventSeverity.Informational, $"Disabled Lightfinder for Player: {msg.HashedCid}")));
return; return;
} }
@@ -294,7 +294,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
if (TryApplyBroadcastEnabled(ttl, "client request")) if (TryApplyBroadcastEnabled(ttl, "client request"))
{ {
_logger.LogDebug("Fetched TTL from server: {TTL}", ttl); _logger.LogDebug("Fetched TTL from server: {TTL}", ttl);
Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(BroadcastService), Services.Events.EventSeverity.Informational, $"Enabled Lightfinder for Player: {msg.HashedCid}"))); Mediator.Publish(new EventMessage(new Events.Event(nameof(LightFinderService), Services.Events.EventSeverity.Informational, $"Enabled Lightfinder for Player: {msg.HashedCid}")));
} }
else else
{ {

View File

@@ -26,7 +26,7 @@ public unsafe class NameplateHandler : IMediatorSubscriber
private readonly ILogger<NameplateHandler> _logger; private readonly ILogger<NameplateHandler> _logger;
private readonly IAddonLifecycle _addonLifecycle; private readonly IAddonLifecycle _addonLifecycle;
private readonly IGameGui _gameGui; private readonly IGameGui _gameGui;
private readonly IClientState _clientState; private readonly IObjectTable _objectTable;
private readonly LightlessConfigService _configService; private readonly LightlessConfigService _configService;
private readonly PairUiService _pairUiService; private readonly PairUiService _pairUiService;
private readonly LightlessMediator _mediator; private readonly LightlessMediator _mediator;
@@ -48,14 +48,14 @@ public unsafe class NameplateHandler : IMediatorSubscriber
private ImmutableHashSet<string> _activeBroadcastingCids = []; private ImmutableHashSet<string> _activeBroadcastingCids = [];
public NameplateHandler(ILogger<NameplateHandler> logger, IAddonLifecycle addonLifecycle, IGameGui gameGui, LightlessConfigService configService, LightlessMediator mediator, IClientState clientState, PairUiService pairUiService) public NameplateHandler(ILogger<NameplateHandler> logger, IAddonLifecycle addonLifecycle, IGameGui gameGui, LightlessConfigService configService, LightlessMediator mediator, IObjectTable objectTable, PairUiService pairUiService)
{ {
_logger = logger; _logger = logger;
_addonLifecycle = addonLifecycle; _addonLifecycle = addonLifecycle;
_gameGui = gameGui; _gameGui = gameGui;
_configService = configService; _configService = configService;
_mediator = mediator; _mediator = mediator;
_clientState = clientState; _objectTable = objectTable;
_pairUiService = pairUiService; _pairUiService = pairUiService;
System.Array.Fill(_cachedNameplateTextOffsets, int.MinValue); System.Array.Fill(_cachedNameplateTextOffsets, int.MinValue);
@@ -323,7 +323,7 @@ public unsafe class NameplateHandler : IMediatorSubscriber
continue; continue;
} }
var local = _clientState.LocalPlayer; var local = _objectTable.LocalPlayer;
if (!config.LightfinderLabelShowOwn && local != null && if (!config.LightfinderLabelShowOwn && local != null &&
objectInfo->GameObject->GetGameObjectId() == local.GameObjectId) objectInfo->GameObject->GetGameObjectId() == local.GameObjectId)
{ {

View File

@@ -28,7 +28,7 @@ public class NotificationService : DisposableMediatorSubscriberBase, IHostedServ
private readonly INotificationManager _notificationManager; private readonly INotificationManager _notificationManager;
private readonly IChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly PairRequestService _pairRequestService; private readonly PairRequestService _pairRequestService;
private readonly HashSet<string> _shownPairRequestNotifications = new(); private readonly HashSet<string> _shownPairRequestNotifications = [];
private readonly PairUiService _pairUiService; private readonly PairUiService _pairUiService;
private readonly PairFactory _pairFactory; private readonly PairFactory _pairFactory;

View File

@@ -1,9 +1,8 @@
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Services.PairProcessing;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace LightlessSync.Services; namespace LightlessSync.Services.PairProcessing;
public sealed class PairProcessingLimiter : DisposableMediatorSubscriberBase public sealed class PairProcessingLimiter : DisposableMediatorSubscriberBase
{ {

View File

@@ -1,7 +1,4 @@
using System;
using System.IO;
using LightlessSync.API.Data; using LightlessSync.API.Data;
using LightlessSync.API.Data.Extensions;
using LightlessSync.FileCache; using LightlessSync.FileCache;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Pairs; using LightlessSync.PlayerData.Pairs;

View File

@@ -39,6 +39,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _noUserDescription, Description: _noUserDescription,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessUserProfileData _loadingProfileUserData = new( private readonly LightlessUserProfileData _loadingProfileUserData = new(
IsFlagged: false, IsFlagged: false,
IsNSFW: false, IsNSFW: false,
@@ -47,6 +48,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _loadingData, Description: _loadingData,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessGroupProfileData _loadingProfileGroupData = new( private readonly LightlessGroupProfileData _loadingProfileGroupData = new(
IsDisabled: false, IsDisabled: false,
IsNsfw: false, IsNsfw: false,
@@ -54,6 +56,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _loadingData, Description: _loadingData,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessGroupProfileData _defaultProfileGroupData = new( private readonly LightlessGroupProfileData _defaultProfileGroupData = new(
IsDisabled: false, IsDisabled: false,
IsNsfw: false, IsNsfw: false,
@@ -61,6 +64,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _noGroupDescription, Description: _noGroupDescription,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessUserProfileData _nsfwProfileUserData = new( private readonly LightlessUserProfileData _nsfwProfileUserData = new(
IsFlagged: false, IsFlagged: false,
IsNSFW: true, IsNSFW: true,
@@ -69,6 +73,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: string.Empty, Base64BannerPicture: string.Empty,
Description: _nsfwDescription, Description: _nsfwDescription,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessGroupProfileData _nsfwProfileGroupData = new( private readonly LightlessGroupProfileData _nsfwProfileGroupData = new(
IsDisabled: false, IsDisabled: false,
IsNsfw: true, IsNsfw: true,
@@ -76,6 +81,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: string.Empty, Base64BannerPicture: string.Empty,
Description: _nsfwDescription, Description: _nsfwDescription,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private const string _noDescription = "-- Profile has no description set --"; private const string _noDescription = "-- Profile has no description set --";
private readonly ConcurrentDictionary<UserData, LightlessProfileData> _lightlessProfiles = new(UserDataComparer.Instance); private readonly ConcurrentDictionary<UserData, LightlessProfileData> _lightlessProfiles = new(UserDataComparer.Instance);
private readonly LightlessProfileData _defaultProfileData = new( private readonly LightlessProfileData _defaultProfileData = new(
@@ -86,6 +92,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _noDescription, Description: _noDescription,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessProfileData _loadingProfileData = new( private readonly LightlessProfileData _loadingProfileData = new(
IsFlagged: false, IsFlagged: false,
IsNSFW: false, IsNSFW: false,
@@ -94,6 +101,7 @@ public class LightlessProfileManager : MediatorSubscriberBase
Base64BannerPicture: _lightlessBanner, Base64BannerPicture: _lightlessBanner,
Description: _loadingData, Description: _loadingData,
Tags: _emptyTagSet); Tags: _emptyTagSet);
private readonly LightlessProfileData _nsfwProfileData = new( private readonly LightlessProfileData _nsfwProfileData = new(
IsFlagged: false, IsFlagged: false,
IsNSFW: false, IsNSFW: false,

View File

@@ -9,6 +9,7 @@ using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Handlers; using LightlessSync.PlayerData.Handlers;
using LightlessSync.PlayerData.Pairs; using LightlessSync.PlayerData.Pairs;
using LightlessSync.Services; using LightlessSync.Services;
using LightlessSync.Services.LightFinder;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Services.ServerConfiguration; using LightlessSync.Services.ServerConfiguration;
using LightlessSync.UI.Components; using LightlessSync.UI.Components;
@@ -54,7 +55,7 @@ public class CompactUi : WindowMediatorSubscriberBase
private readonly TopTabMenu _tabMenu; private readonly TopTabMenu _tabMenu;
private readonly TagHandler _tagHandler; private readonly TagHandler _tagHandler;
private readonly UiSharedService _uiSharedService; private readonly UiSharedService _uiSharedService;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private List<IDrawFolder> _drawFolders; private List<IDrawFolder> _drawFolders;
private Pair? _lastAddedUser; private Pair? _lastAddedUser;
@@ -66,7 +67,7 @@ public class CompactUi : WindowMediatorSubscriberBase
private bool _wasOpen; private bool _wasOpen;
private float _windowContentWidth; private float _windowContentWidth;
private readonly SeluneBrush _seluneBrush = new(); private readonly SeluneBrush _seluneBrush = new();
private const float ConnectButtonHighlightThickness = 14f; private const float _connectButtonHighlightThickness = 14f;
public CompactUi( public CompactUi(
ILogger<CompactUi> logger, ILogger<CompactUi> logger,
@@ -87,7 +88,7 @@ public class CompactUi : WindowMediatorSubscriberBase
RenameSyncshellTagUi renameSyncshellTagUi, RenameSyncshellTagUi renameSyncshellTagUi,
PerformanceCollectorService performanceCollectorService, PerformanceCollectorService performanceCollectorService,
IpcManager ipcManager, IpcManager ipcManager,
BroadcastService broadcastService, LightFinderService broadcastService,
CharacterAnalyzer characterAnalyzer, CharacterAnalyzer characterAnalyzer,
PlayerPerformanceConfigService playerPerformanceConfig, PairRequestService pairRequestService, DalamudUtilService dalamudUtilService, NotificationService lightlessNotificationService, PairLedger pairLedger) : base(logger, mediator, "###LightlessSyncMainUI", performanceCollectorService) PlayerPerformanceConfigService playerPerformanceConfig, PairRequestService pairRequestService, DalamudUtilService dalamudUtilService, NotificationService lightlessNotificationService, PairLedger pairLedger) : base(logger, mediator, "###LightlessSyncMainUI", performanceCollectorService)
{ {
@@ -112,8 +113,8 @@ public class CompactUi : WindowMediatorSubscriberBase
AllowPinning = true; AllowPinning = true;
AllowClickthrough = false; AllowClickthrough = false;
TitleBarButtons = new() TitleBarButtons =
{ [
new TitleBarButton() new TitleBarButton()
{ {
Icon = FontAwesomeIcon.Cog, Icon = FontAwesomeIcon.Cog,
@@ -144,7 +145,7 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.EndTooltip(); ImGui.EndTooltip();
} }
}, },
}; ];
_drawFolders = [.. DrawFolders]; _drawFolders = [.. DrawFolders];
@@ -406,7 +407,7 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.GetItemRectMax(), ImGui.GetItemRectMax(),
SeluneHighlightMode.Both, SeluneHighlightMode.Both,
borderOnly: true, borderOnly: true,
borderThicknessOverride: ConnectButtonHighlightThickness, borderThicknessOverride: _connectButtonHighlightThickness,
exactSize: true, exactSize: true,
clipToElement: true, clipToElement: true,
roundingOverride: ImGui.GetStyle().FrameRounding); roundingOverride: ImGui.GetStyle().FrameRounding);
@@ -634,7 +635,7 @@ public class CompactUi : WindowMediatorSubscriberBase
} }
if (ImGui.IsItemClicked()) if (ImGui.IsItemClicked())
_lightlessMediator.Publish(new UiToggleMessage(typeof(BroadcastUI))); _lightlessMediator.Publish(new UiToggleMessage(typeof(LightFinderUI)));
} }
ImGui.SetCursorPosY(cursorY); ImGui.SetCursorPosY(cursorY);

View File

@@ -24,6 +24,15 @@ public class DownloadUi : WindowMediatorSubscriberBase
private readonly PairProcessingLimiter _pairProcessingLimiter; private readonly PairProcessingLimiter _pairProcessingLimiter;
private readonly ConcurrentDictionary<GameObjectHandler, bool> _uploadingPlayers = new(); private readonly ConcurrentDictionary<GameObjectHandler, bool> _uploadingPlayers = new();
private readonly Dictionary<GameObjectHandler, Vector2> _smoothed = []; private readonly Dictionary<GameObjectHandler, Vector2> _smoothed = [];
private readonly Dictionary<GameObjectHandler, DownloadSpeedTracker> _downloadSpeeds = new();
private sealed class DownloadSpeedTracker
{
public long LastBytes;
public double LastTime;
public double SpeedBytesPerSecond;
}
private bool _notificationDismissed = true; private bool _notificationDismissed = true;
private int _lastDownloadStateHash = 0; private int _lastDownloadStateHash = 0;
@@ -96,105 +105,37 @@ public class DownloadUi : WindowMediatorSubscriberBase
{ {
if (_configService.Current.ShowTransferWindow) if (_configService.Current.ShowTransferWindow)
{ {
var limiterSnapshot = _pairProcessingLimiter.GetSnapshot(); DrawDownloadSummaryBox();
if (_configService.Current.ShowUploading)
{
const int transparency = 100;
foreach (var player in _uploadingPlayers.Select(p => p.Key).ToList())
{
var screenPos = _dalamudUtilService.WorldToScreen(player.GetGameObject());
if (screenPos == Vector2.Zero) continue;
try try
{ {
if (_fileTransferManager.IsUploading) using var _ = _uiShared.UidFont.Push();
{ var uploadText = "Uploading";
var currentUploads = _fileTransferManager.GetCurrentUploadsSnapshot(); var textSize = ImGui.CalcTextSize(uploadText);
var totalUploads = currentUploads.Count;
var doneUploads = currentUploads.Count(c => c.IsTransferred); var drawList = ImGui.GetBackgroundDrawList();
var totalUploaded = currentUploads.Sum(c => c.Transferred);
var totalToUpload = currentUploads.Sum(c => c.Total);
UiSharedService.DrawOutlinedFont($"▲", ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1);
ImGui.SameLine();
var xDistance = ImGui.GetCursorPosX();
UiSharedService.DrawOutlinedFont($"Compressing+Uploading {doneUploads}/{totalUploads}",
ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1);
ImGui.NewLine();
ImGui.SameLine(xDistance);
UiSharedService.DrawOutlinedFont( UiSharedService.DrawOutlinedFont(
$"{UiSharedService.ByteToString(totalUploaded, addSuffix: false)}/{UiSharedService.ByteToString(totalToUpload)}", drawList,
ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1); uploadText,
screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 },
if (_currentDownloads.Any()) ImGui.Separator(); UiSharedService.Color(255, 255, 0, transparency),
} UiSharedService.Color(0, 0, 0, transparency),
2
);
} }
catch catch
{ {
_logger.LogDebug("Error drawing upload progress"); _logger.LogDebug("Error drawing upload progress");
} }
try
{
// Check if download notifications are enabled (not set to TextOverlay)
var useNotifications = _configService.Current.UseLightlessNotifications
? _configService.Current.LightlessDownloadNotification != NotificationLocation.TextOverlay
: _configService.Current.UseNotificationsForDownloads;
if (useNotifications)
{
// Use notification system
if (_currentDownloads.Any())
{
UpdateDownloadNotificationIfChanged(limiterSnapshot);
_notificationDismissed = false;
} }
else if (!_notificationDismissed)
{
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
_notificationDismissed = true;
_lastDownloadStateHash = 0;
}
}
else
{
// Use text overlay
if (limiterSnapshot.IsEnabled)
{
var queueColor = limiterSnapshot.Waiting > 0 ? ImGuiColors.DalamudYellow : ImGuiColors.DalamudGrey;
var queueText = $"Pair queue {limiterSnapshot.InFlight}/{limiterSnapshot.Limit}";
queueText += limiterSnapshot.Waiting > 0 ? $" ({limiterSnapshot.Waiting} waiting, {limiterSnapshot.Remaining} free)" : $" ({limiterSnapshot.Remaining} free)";
UiSharedService.DrawOutlinedFont(queueText, queueColor, new Vector4(0, 0, 0, 255), 1);
ImGui.NewLine();
}
else
{
UiSharedService.DrawOutlinedFont("Pair apply limiter disabled", ImGuiColors.DalamudGrey, new Vector4(0, 0, 0, 255), 1);
ImGui.NewLine();
}
foreach (var item in _currentDownloads.ToList())
{
var dlSlot = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForSlot);
var dlQueue = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForQueue);
var dlProg = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Downloading);
var dlDecomp = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Decompressing);
var totalFiles = item.Value.Sum(c => c.Value.TotalFiles);
var transferredFiles = item.Value.Sum(c => c.Value.TransferredFiles);
var totalBytes = item.Value.Sum(c => c.Value.TotalBytes);
var transferredBytes = item.Value.Sum(c => c.Value.TransferredBytes);
UiSharedService.DrawOutlinedFont($"▼", ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1);
ImGui.SameLine();
var xDistance = ImGui.GetCursorPosX();
UiSharedService.DrawOutlinedFont(
$"{item.Key.Name} [W:{dlSlot}/Q:{dlQueue}/P:{dlProg}/D:{dlDecomp}]",
ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1);
ImGui.NewLine();
ImGui.SameLine(xDistance);
UiSharedService.DrawOutlinedFont(
$"{transferredFiles}/{totalFiles} ({UiSharedService.ByteToString(transferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)})",
ImGuiColors.DalamudWhite, new Vector4(0, 0, 0, 255), 1);
}
}
}
catch
{
_logger.LogDebug("Error drawing download progress");
} }
} }
@@ -202,11 +143,14 @@ public class DownloadUi : WindowMediatorSubscriberBase
{ {
const int transparency = 100; const int transparency = 100;
const int dlBarBorder = 3; const int dlBarBorder = 3;
const float rounding = 6f;
var shadowOffset = new Vector2(2, 2);
foreach (var transfer in _currentDownloads.ToList()) foreach (var transfer in _currentDownloads.ToList())
{ {
var transferKey = transfer.Key; var transferKey = transfer.Key;
var rawPos = _dalamudUtilService.WorldToScreen(transferKey.GetGameObject()); var rawPos = _dalamudUtilService.WorldToScreen(transferKey.GetGameObject());
//If RawPos is zero, remove it from smoothed dictionary //If RawPos is zero, remove it from smoothed dictionary
if (rawPos == Vector2.Zero) if (rawPos == Vector2.Zero)
{ {
@@ -214,43 +158,66 @@ public class DownloadUi : WindowMediatorSubscriberBase
continue; continue;
} }
//Smoothing out the movement and fix jitter around the position. //Smoothing out the movement and fix jitter around the position.
Vector2 screenPos = _smoothed.TryGetValue(transferKey, out var lastPos) ? (rawPos - lastPos).Length() < 4f ? lastPos : rawPos : rawPos;
_smoothed[transferKey] = screenPos;
Vector2 screenPos = _smoothed.TryGetValue(transferKey, out var lastPos)
? (rawPos - lastPos).Length() < 4f ? lastPos : rawPos
: rawPos;
_smoothed[transferKey] = screenPos;
var totalBytes = transfer.Value.Sum(c => c.Value.TotalBytes); var totalBytes = transfer.Value.Sum(c => c.Value.TotalBytes);
var transferredBytes = transfer.Value.Sum(c => c.Value.TransferredBytes); var transferredBytes = transfer.Value.Sum(c => c.Value.TransferredBytes);
var maxDlText = $"{UiSharedService.ByteToString(totalBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)}"; var maxDlText = $"{UiSharedService.ByteToString(totalBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)}";
var textSize = _configService.Current.TransferBarsShowText ? ImGui.CalcTextSize(maxDlText) : new Vector2(10, 10); var textSize = _configService.Current.TransferBarsShowText
? ImGui.CalcTextSize(maxDlText)
: new Vector2(10, 10);
int dlBarHeight = _configService.Current.TransferBarsHeight > ((int)textSize.Y + 5) ? _configService.Current.TransferBarsHeight : (int)textSize.Y + 5; int dlBarHeight = _configService.Current.TransferBarsHeight > ((int)textSize.Y + 5)
int dlBarWidth = _configService.Current.TransferBarsWidth > ((int)textSize.X + 10) ? _configService.Current.TransferBarsWidth : (int)textSize.X + 10; ? _configService.Current.TransferBarsHeight
: (int)textSize.Y + 5;
int dlBarWidth = _configService.Current.TransferBarsWidth > ((int)textSize.X + 10)
? _configService.Current.TransferBarsWidth
: (int)textSize.X + 10;
var dlBarStart = new Vector2(screenPos.X - dlBarWidth / 2f, screenPos.Y - dlBarHeight / 2f); var dlBarStart = new Vector2(screenPos.X - dlBarWidth / 2f, screenPos.Y - dlBarHeight / 2f);
var dlBarEnd = new Vector2(screenPos.X + dlBarWidth / 2f, screenPos.Y + dlBarHeight / 2f); var dlBarEnd = new Vector2(screenPos.X + dlBarWidth / 2f, screenPos.Y + dlBarHeight / 2f);
// Precompute rects
var outerStart = new Vector2(dlBarStart.X - dlBarBorder - 1, dlBarStart.Y - dlBarBorder - 1);
var outerEnd = new Vector2(dlBarEnd.X + dlBarBorder + 1, dlBarEnd.Y + dlBarBorder + 1);
var borderStart = new Vector2(dlBarStart.X - dlBarBorder, dlBarStart.Y - dlBarBorder);
var borderEnd = new Vector2(dlBarEnd.X + dlBarBorder, dlBarEnd.Y + dlBarBorder);
var drawList = ImGui.GetBackgroundDrawList(); var drawList = ImGui.GetBackgroundDrawList();
drawList.AddRectFilled(
dlBarStart with { X = dlBarStart.X - dlBarBorder - 1, Y = dlBarStart.Y - dlBarBorder - 1 }, //Shadow, background, border, bar background
dlBarEnd with { X = dlBarEnd.X + dlBarBorder + 1, Y = dlBarEnd.Y + dlBarBorder + 1 }, drawList.AddRectFilled(outerStart + shadowOffset, outerEnd + shadowOffset, UiSharedService.Color(0, 0, 0, transparency / 2), rounding + 2);
UiSharedService.Color(0, 0, 0, transparency), 1); drawList.AddRectFilled(outerStart, outerEnd, UiSharedService.Color(0, 0, 0, transparency), rounding + 2);
drawList.AddRectFilled(dlBarStart with { X = dlBarStart.X - dlBarBorder, Y = dlBarStart.Y - dlBarBorder }, drawList.AddRectFilled(borderStart, borderEnd, UiSharedService.Color(220, 220, 220, transparency), rounding);
dlBarEnd with { X = dlBarEnd.X + dlBarBorder, Y = dlBarEnd.Y + dlBarBorder }, drawList.AddRectFilled(dlBarStart, dlBarEnd, UiSharedService.Color(0, 0, 0, transparency), rounding);
UiSharedService.Color(220, 220, 220, transparency), 1);
drawList.AddRectFilled(dlBarStart, dlBarEnd,
UiSharedService.Color(0, 0, 0, transparency), 1);
var dlProgressPercent = transferredBytes / (double)totalBytes; var dlProgressPercent = transferredBytes / (double)totalBytes;
drawList.AddRectFilled(dlBarStart, var progressEndX = dlBarStart.X + (float)(dlProgressPercent * dlBarWidth);
dlBarEnd with { X = dlBarStart.X + (float)(dlProgressPercent * dlBarWidth) }, var progressEnd = new Vector2(progressEndX, dlBarEnd.Y);
UiSharedService.Color(UIColors.Get("LightlessPurple")));
drawList.AddRectFilled(
dlBarStart,
progressEnd,
UiSharedService.Color(UIColors.Get("LightlessPurple")),
rounding
);
if (_configService.Current.TransferBarsShowText) if (_configService.Current.TransferBarsShowText)
{ {
var downloadText = $"{UiSharedService.ByteToString(transferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)}"; var downloadText = $"{UiSharedService.ByteToString(transferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)}";
UiSharedService.DrawOutlinedFont(drawList, downloadText, UiSharedService.DrawOutlinedFont(
drawList,
downloadText,
screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 }, screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 },
UiSharedService.Color(255, 255, 255, transparency), UiSharedService.Color(255, 255, 255, transparency),
UiSharedService.Color(0, 0, 0, transparency), 1); UiSharedService.Color(0, 0, 0, transparency),
1
);
} }
} }
@@ -269,10 +236,14 @@ public class DownloadUi : WindowMediatorSubscriberBase
var textSize = ImGui.CalcTextSize(uploadText); var textSize = ImGui.CalcTextSize(uploadText);
var drawList = ImGui.GetBackgroundDrawList(); var drawList = ImGui.GetBackgroundDrawList();
UiSharedService.DrawOutlinedFont(drawList, uploadText, UiSharedService.DrawOutlinedFont(
drawList,
uploadText,
screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 }, screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 },
UiSharedService.Color(255, 255, 0, transparency), UiSharedService.Color(255, 255, 0, transparency),
UiSharedService.Color(0, 0, 0, transparency), 2); UiSharedService.Color(0, 0, 0, transparency),
2
);
} }
catch catch
{ {
@@ -283,6 +254,185 @@ public class DownloadUi : WindowMediatorSubscriberBase
} }
} }
private void DrawDownloadSummaryBox()
{
if (!_currentDownloads.Any())
return;
const int transparency = 150;
const float padding = 6f;
const float spacingY = 2f;
const float minBoxWidth = 320f;
var now = ImGui.GetTime();
int totalFiles = 0;
int transferredFiles = 0;
long totalBytes = 0;
long transferredBytes = 0;
var perPlayer = new List<(string Name, int TransferredFiles, int TotalFiles, long TransferredBytes, long TotalBytes, double SpeedBytesPerSecond)>();
foreach (var transfer in _currentDownloads.ToList())
{
var handler = transfer.Key;
var statuses = transfer.Value.Values;
var playerTotalFiles = statuses.Sum(s => s.TotalFiles);
var playerTransferredFiles = statuses.Sum(s => s.TransferredFiles);
var playerTotalBytes = statuses.Sum(s => s.TotalBytes);
var playerTransferredBytes = statuses.Sum(s => s.TransferredBytes);
totalFiles += playerTotalFiles;
transferredFiles += playerTransferredFiles;
totalBytes += playerTotalBytes;
transferredBytes += playerTransferredBytes;
double speed = 0;
if (playerTotalBytes > 0)
{
if (!_downloadSpeeds.TryGetValue(handler, out var tracker))
{
tracker = new DownloadSpeedTracker
{
LastBytes = playerTransferredBytes,
LastTime = now,
SpeedBytesPerSecond = 0
};
_downloadSpeeds[handler] = tracker;
}
var dt = now - tracker.LastTime;
var dBytes = playerTransferredBytes - tracker.LastBytes;
if (dt > 0.1 && dBytes >= 0)
{
var instant = dBytes / dt;
tracker.SpeedBytesPerSecond = tracker.SpeedBytesPerSecond <= 0
? instant
: tracker.SpeedBytesPerSecond * 0.8 + instant * 0.2;
}
tracker.LastTime = now;
tracker.LastBytes = playerTransferredBytes;
speed = tracker.SpeedBytesPerSecond;
}
perPlayer.Add((
handler.Name,
playerTransferredFiles,
playerTotalFiles,
playerTransferredBytes,
playerTotalBytes,
speed
));
}
foreach (var handler in _downloadSpeeds.Keys.ToList())
{
if (!_currentDownloads.ContainsKey(handler))
_downloadSpeeds.Remove(handler);
}
if (totalFiles == 0 || totalBytes == 0)
return;
var drawList = ImGui.GetBackgroundDrawList();
var windowPos = ImGui.GetWindowPos();
var headerText = $"Downloading {transferredFiles}/{totalFiles} files";
var bytesText = $"{UiSharedService.ByteToString(transferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(totalBytes)}";
var totalSpeed = perPlayer.Sum(p => p.SpeedBytesPerSecond);
var speedText = totalSpeed > 0
? $"{UiSharedService.ByteToString((long)totalSpeed)}/s"
: "Calculating lightspeed...";
var headerSize = ImGui.CalcTextSize(headerText);
var bytesSize = ImGui.CalcTextSize(bytesText);
var speedSize = ImGui.CalcTextSize(speedText);
float contentWidth = headerSize.X;
if (bytesSize.X > contentWidth) contentWidth = bytesSize.X;
if (speedSize.X > contentWidth) contentWidth = speedSize.X;
foreach (var p in perPlayer)
{
var playerSpeedText = p.SpeedBytesPerSecond > 0
? $"{UiSharedService.ByteToString((long)p.SpeedBytesPerSecond)}/s"
: "-";
var line = $"{p.Name}: {p.TransferredFiles}/{p.TotalFiles} " +
$"({UiSharedService.ByteToString(p.TransferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(p.TotalBytes)}) " +
$"@ {playerSpeedText}";
var lineSize = ImGui.CalcTextSize(line);
if (lineSize.X > contentWidth)
contentWidth = lineSize.X;
}
var boxWidth = contentWidth + padding * 2;
if (boxWidth < minBoxWidth)
boxWidth = minBoxWidth;
var lineHeight = ImGui.GetTextLineHeight();
var numTextLines = 3 + perPlayer.Count;
var barHeight = lineHeight * 0.8f;
var boxHeight = padding * 3 + barHeight + numTextLines * (lineHeight + spacingY);
var origin = windowPos;
var boxMin = origin;
var boxMax = origin + new Vector2(boxWidth, boxHeight);
drawList.AddRectFilled(boxMin, boxMax, UiSharedService.Color(0, 0, 0, transparency), 5f);
drawList.AddRect(boxMin, boxMax, UiSharedService.Color(220, 220, 220, transparency), 5f);
// Progress bar
var cursor = boxMin + new Vector2(padding, padding);
var barMin = cursor;
var barMax = new Vector2(boxMin.X + boxWidth - padding, cursor.Y + barHeight);
var progress = (float)transferredBytes / totalBytes;
drawList.AddRectFilled(barMin, barMax, UiSharedService.Color(40, 40, 40, transparency), 3f);
drawList.AddRectFilled(
barMin,
new Vector2(barMin.X + (barMax.X - barMin.X) * progress, barMax.Y),
UiSharedService.Color(UIColors.Get("LightlessPurple")),
3f
);
cursor.Y = barMax.Y + padding;
// Header
UiSharedService.DrawOutlinedFont(drawList, headerText, cursor, UiSharedService.Color(255, 255, 255, transparency), UiSharedService.Color(0, 0, 0, transparency), 1);
cursor.Y += lineHeight + spacingY;
// Bytes
UiSharedService.DrawOutlinedFont(drawList, bytesText, cursor, UiSharedService.Color(255, 255, 255, transparency), UiSharedService.Color(0, 0, 0, transparency), 1);
cursor.Y += lineHeight + spacingY;
// Total speed WIP
UiSharedService.DrawOutlinedFont(drawList, speedText, cursor, UiSharedService.Color(200, 255, 200, transparency), UiSharedService.Color(0, 0, 0, transparency), 1);
cursor.Y += lineHeight * 1.4f;
// Per-player lines
foreach (var p in perPlayer.OrderByDescending(p => p.TotalBytes))
{
var playerSpeedText = p.SpeedBytesPerSecond > 0
? $"{UiSharedService.ByteToString((long)p.SpeedBytesPerSecond)}/s"
: "-";
var line = $"{p.Name}: {p.TransferredFiles}/{p.TotalFiles} " +
$"({UiSharedService.ByteToString(p.TransferredBytes, addSuffix: false)}/{UiSharedService.ByteToString(p.TotalBytes)}) " +
$"@ {playerSpeedText}";
UiSharedService.DrawOutlinedFont(drawList, line, cursor, UiSharedService.Color(255, 255, 255, transparency), UiSharedService.Color(0, 0, 0, transparency), 1);
cursor.Y += lineHeight + spacingY;
}
}
public override bool DrawConditions() public override bool DrawConditions()
{ {
if (_uiShared.EditTrackerPosition) return true; if (_uiShared.EditTrackerPosition) return true;

View File

@@ -19,6 +19,7 @@ using System.Text;
using LightlessSync.UI.Services; using LightlessSync.UI.Services;
using LightlessSync.PlayerData.Pairs; using LightlessSync.PlayerData.Pairs;
using static LightlessSync.Services.PairRequestService; using static LightlessSync.Services.PairRequestService;
using LightlessSync.Services.LightFinder;
namespace LightlessSync.UI; namespace LightlessSync.UI;
@@ -35,8 +36,8 @@ public sealed class DtrEntry : IDisposable, IHostedService
private readonly Lazy<IDtrBarEntry> _statusEntry; private readonly Lazy<IDtrBarEntry> _statusEntry;
private readonly Lazy<IDtrBarEntry> _lightfinderEntry; private readonly Lazy<IDtrBarEntry> _lightfinderEntry;
private readonly ILogger<DtrEntry> _logger; private readonly ILogger<DtrEntry> _logger;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private readonly BroadcastScannerService _broadcastScannerService; private readonly LightFinderScannerService _broadcastScannerService;
private readonly LightlessMediator _lightlessMediator; private readonly LightlessMediator _lightlessMediator;
private readonly PairUiService _pairUiService; private readonly PairUiService _pairUiService;
private readonly PairRequestService _pairRequestService; private readonly PairRequestService _pairRequestService;
@@ -62,8 +63,8 @@ public sealed class DtrEntry : IDisposable, IHostedService
PairRequestService pairRequestService, PairRequestService pairRequestService,
ApiController apiController, ApiController apiController,
ServerConfigurationManager serverManager, ServerConfigurationManager serverManager,
BroadcastService broadcastService, LightFinderService broadcastService,
BroadcastScannerService broadcastScannerService, LightFinderScannerService broadcastScannerService,
DalamudUtilService dalamudUtilService) DalamudUtilService dalamudUtilService)
{ {
_logger = logger; _logger = logger;

View File

@@ -7,6 +7,7 @@ using LightlessSync.API.Data.Extensions;
using LightlessSync.API.Dto.Group; using LightlessSync.API.Dto.Group;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.Services; using LightlessSync.Services;
using LightlessSync.Services.LightFinder;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Utils; using LightlessSync.Utils;
using LightlessSync.WebAPI; using LightlessSync.WebAPI;
@@ -15,28 +16,28 @@ using System.Numerics;
namespace LightlessSync.UI namespace LightlessSync.UI
{ {
public class BroadcastUI : WindowMediatorSubscriberBase public class LightFinderUI : WindowMediatorSubscriberBase
{ {
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly LightlessConfigService _configService; private readonly LightlessConfigService _configService;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private readonly UiSharedService _uiSharedService; private readonly UiSharedService _uiSharedService;
private readonly BroadcastScannerService _broadcastScannerService; private readonly LightFinderScannerService _broadcastScannerService;
private IReadOnlyList<GroupFullInfoDto> _allSyncshells = Array.Empty<GroupFullInfoDto>(); private IReadOnlyList<GroupFullInfoDto> _allSyncshells = Array.Empty<GroupFullInfoDto>();
private string _userUid = string.Empty; private string _userUid = string.Empty;
private readonly List<(string Label, string? GID, bool IsAvailable)> _syncshellOptions = new(); private readonly List<(string Label, string? GID, bool IsAvailable)> _syncshellOptions = new();
public BroadcastUI( public LightFinderUI(
ILogger<BroadcastUI> logger, ILogger<LightFinderUI> logger,
LightlessMediator mediator, LightlessMediator mediator,
PerformanceCollectorService performanceCollectorService, PerformanceCollectorService performanceCollectorService,
BroadcastService broadcastService, LightFinderService broadcastService,
LightlessConfigService configService, LightlessConfigService configService,
UiSharedService uiShared, UiSharedService uiShared,
ApiController apiController, ApiController apiController,
BroadcastScannerService broadcastScannerService LightFinderScannerService broadcastScannerService
) : base(logger, mediator, "Lightfinder###LightlessLightfinderUI", performanceCollectorService) ) : base(logger, mediator, "Lightfinder###LightlessLightfinderUI", performanceCollectorService)
{ {
_broadcastService = broadcastService; _broadcastService = broadcastService;

View File

@@ -38,6 +38,7 @@ using System.Net.Http.Json;
using System.Numerics; using System.Numerics;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using LightlessSync.Services.PairProcessing;
namespace LightlessSync.UI; namespace LightlessSync.UI;

View File

@@ -15,15 +15,16 @@ using LightlessSync.WebAPI;
using LightlessSync.UI.Services; using LightlessSync.UI.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Numerics; using System.Numerics;
using LightlessSync.Services.LightFinder;
namespace LightlessSync.UI; namespace LightlessSync.UI;
public class SyncshellFinderUI : WindowMediatorSubscriberBase public class SyncshellFinderUI : WindowMediatorSubscriberBase
{ {
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly BroadcastService _broadcastService; private readonly LightFinderService _broadcastService;
private readonly UiSharedService _uiSharedService; private readonly UiSharedService _uiSharedService;
private readonly BroadcastScannerService _broadcastScannerService; private readonly LightFinderScannerService _broadcastScannerService;
private readonly PairUiService _pairUiService; private readonly PairUiService _pairUiService;
private readonly DalamudUtilService _dalamudUtilService; private readonly DalamudUtilService _dalamudUtilService;
@@ -44,10 +45,10 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
ILogger<SyncshellFinderUI> logger, ILogger<SyncshellFinderUI> logger,
LightlessMediator mediator, LightlessMediator mediator,
PerformanceCollectorService performanceCollectorService, PerformanceCollectorService performanceCollectorService,
BroadcastService broadcastService, LightFinderService broadcastService,
UiSharedService uiShared, UiSharedService uiShared,
ApiController apiController, ApiController apiController,
BroadcastScannerService broadcastScannerService, LightFinderScannerService broadcastScannerService,
PairUiService pairUiService, PairUiService pairUiService,
DalamudUtilService dalamudUtilService) : base(logger, mediator, "Shellfinder###LightlessSyncshellFinderUI", performanceCollectorService) DalamudUtilService dalamudUtilService) : base(logger, mediator, "Shellfinder###LightlessSyncshellFinderUI", performanceCollectorService)
{ {
@@ -111,7 +112,7 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
if (ImGui.Button("Open Lightfinder", new Vector2(200 * ImGuiHelpers.GlobalScale, 0))) if (ImGui.Button("Open Lightfinder", new Vector2(200 * ImGuiHelpers.GlobalScale, 0)))
{ {
Mediator.Publish(new UiToggleMessage(typeof(BroadcastUI))); Mediator.Publish(new UiToggleMessage(typeof(LightFinderUI)));
} }
ImGui.PopStyleColor(); ImGui.PopStyleColor();

View File

@@ -781,7 +781,7 @@ public class TopTabMenu
if (_uiSharedService.IconTextButton(FontAwesomeIcon.PersonCirclePlus, "Lightfinder", buttonX, center: true)) if (_uiSharedService.IconTextButton(FontAwesomeIcon.PersonCirclePlus, "Lightfinder", buttonX, center: true))
{ {
_lightlessMediator.Publish(new UiToggleMessage(typeof(BroadcastUI))); _lightlessMediator.Publish(new UiToggleMessage(typeof(LightFinderUI)));
} }
ImGui.SameLine(); ImGui.SameLine();

View File

@@ -4,7 +4,6 @@ using LightlessSync.API.Dto.Files;
using LightlessSync.API.Routes; using LightlessSync.API.Routes;
using LightlessSync.FileCache; using LightlessSync.FileCache;
using LightlessSync.PlayerData.Handlers; using LightlessSync.PlayerData.Handlers;
using LightlessSync.Services;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Services.TextureCompression; using LightlessSync.Services.TextureCompression;
using LightlessSync.WebAPI.Files.Models; using LightlessSync.WebAPI.Files.Models;
@@ -13,6 +12,7 @@ using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Net.Http.Json; using System.Net.Http.Json;
using LightlessSync.LightlessConfiguration; using LightlessSync.LightlessConfiguration;
using LightlessSync.Services.PairProcessing;
namespace LightlessSync.WebAPI.Files; namespace LightlessSync.WebAPI.Files;