From 5c8e239a7b77191f9b1f125b5666a0f8a56f2930 Mon Sep 17 00:00:00 2001 From: Tsubasahane Date: Sat, 27 Dec 2025 17:04:39 +0800 Subject: [PATCH 1/3] implement playerState - use IPlayerState for DalamudUtilService and make things less asynced - make LocationInfo work with ContentFinderData --- .gitignore | 3 + .../FileCache/TransientResourceManager.cs | 2 +- LightlessSync/Plugin.cs | 3 +- .../CharaDataGposeTogetherManager.cs | 2 +- .../Services/CharaData/CharaDataManager.cs | 2 +- .../CharaData/CharaDataNearbyManager.cs | 4 +- .../Services/Chat/ZoneChatService.cs | 6 +- LightlessSync/Services/ContextMenuService.cs | 2 +- LightlessSync/Services/DalamudUtilService.cs | 174 ++++++++++-------- .../LightFinder/LightFinderService.cs | 2 +- .../ServerConfigurationManager.cs | 22 +-- LightlessSync/UI/DtrEntry.cs | 2 +- LightlessSync/UI/TopTabMenu.cs | 2 +- .../SignalR/ApIController.Functions.Users.cs | 2 +- LightlessSync/WebAPI/SignalR/ApiController.cs | 6 +- LightlessSync/WebAPI/SignalR/TokenProvider.cs | 4 +- 16 files changed, 132 insertions(+), 106 deletions(-) diff --git a/.gitignore b/.gitignore index dfcfd56..fecf7ea 100644 --- a/.gitignore +++ b/.gitignore @@ -348,3 +348,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# idea +/.idea diff --git a/LightlessSync/FileCache/TransientResourceManager.cs b/LightlessSync/FileCache/TransientResourceManager.cs index 115c616..ed2cca6 100644 --- a/LightlessSync/FileCache/TransientResourceManager.cs +++ b/LightlessSync/FileCache/TransientResourceManager.cs @@ -78,7 +78,7 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase } } - private string PlayerPersistentDataKey => _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult() + "_" + _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(); + private string PlayerPersistentDataKey => _dalamudUtil.GetPlayerName() + "_" + _dalamudUtil.GetHomeWorldId(); private ConcurrentDictionary> SemiTransientResources { get diff --git a/LightlessSync/Plugin.cs b/LightlessSync/Plugin.cs index a9be72b..cd57c34 100644 --- a/LightlessSync/Plugin.cs +++ b/LightlessSync/Plugin.cs @@ -52,7 +52,7 @@ public sealed class Plugin : IDalamudPlugin IFramework framework, IObjectTable objectTable, IClientState clientState, ICondition condition, IChatGui chatGui, IGameGui gameGui, IDtrBar dtrBar, IPluginLog pluginLog, ITargetManager targetManager, INotificationManager notificationManager, ITextureProvider textureProvider, IContextMenu contextMenu, IGameInteropProvider gameInteropProvider, IGameConfig gameConfig, - ISigScanner sigScanner, INamePlateGui namePlateGui, IAddonLifecycle addonLifecycle) + ISigScanner sigScanner, INamePlateGui namePlateGui, IAddonLifecycle addonLifecycle, IPlayerState playerState) { NativeDll.Initialize(pluginInterface.AssemblyLocation.DirectoryName); if (!Directory.Exists(pluginInterface.ConfigDirectory.FullName)) @@ -216,6 +216,7 @@ public sealed class Plugin : IDalamudPlugin gameData, targetManager, gameConfig, + playerState, sp.GetRequiredService(), sp.GetRequiredService(), sp.GetRequiredService(), diff --git a/LightlessSync/Services/CharaData/CharaDataGposeTogetherManager.cs b/LightlessSync/Services/CharaData/CharaDataGposeTogetherManager.cs index d7463b2..cb5b0aa 100644 --- a/LightlessSync/Services/CharaData/CharaDataGposeTogetherManager.cs +++ b/LightlessSync/Services/CharaData/CharaDataGposeTogetherManager.cs @@ -450,7 +450,7 @@ public class CharaDataGposeTogetherManager : DisposableMediatorSubscriberBase }; } - var loc = await _dalamudUtil.GetMapDataAsync().ConfigureAwait(false); + var loc = _dalamudUtil.GetMapData(); worldData.LocationInfo = loc; if (_forceResendWorldData || worldData != _lastWorldData) diff --git a/LightlessSync/Services/CharaData/CharaDataManager.cs b/LightlessSync/Services/CharaData/CharaDataManager.cs index d8b2387..4a30639 100644 --- a/LightlessSync/Services/CharaData/CharaDataManager.cs +++ b/LightlessSync/Services/CharaData/CharaDataManager.cs @@ -254,7 +254,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase Logger.LogTrace("Attaching World data {data}", worldData); - worldData.LocationInfo = await _dalamudUtilService.GetMapDataAsync().ConfigureAwait(false); + worldData.LocationInfo = _dalamudUtilService.GetMapData(); Logger.LogTrace("World data serialized: {data}", worldData); diff --git a/LightlessSync/Services/CharaData/CharaDataNearbyManager.cs b/LightlessSync/Services/CharaData/CharaDataNearbyManager.cs index b3d4800..c66588d 100644 --- a/LightlessSync/Services/CharaData/CharaDataNearbyManager.cs +++ b/LightlessSync/Services/CharaData/CharaDataNearbyManager.cs @@ -186,8 +186,8 @@ public sealed class CharaDataNearbyManager : DisposableMediatorSubscriberBase var previousPoses = _nearbyData.Keys.ToList(); _nearbyData.Clear(); - var ownLocation = await _dalamudUtilService.RunOnFrameworkThread(() => _dalamudUtilService.GetMapData()).ConfigureAwait(false); - var player = await _dalamudUtilService.RunOnFrameworkThread(() => _dalamudUtilService.GetPlayerCharacter()).ConfigureAwait(false); + var ownLocation = _dalamudUtilService.GetMapData(); + var player = await _dalamudUtilService.GetPlayerCharacterAsync().ConfigureAwait(false); var currentServer = player.CurrentWorld; var playerPos = player.Position; diff --git a/LightlessSync/Services/Chat/ZoneChatService.cs b/LightlessSync/Services/Chat/ZoneChatService.cs index 38e76d9..5d37f2b 100644 --- a/LightlessSync/Services/Chat/ZoneChatService.cs +++ b/LightlessSync/Services/Chat/ZoneChatService.cs @@ -571,7 +571,7 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS try { - var location = await _dalamudUtilService.GetMapDataAsync().ConfigureAwait(false); + var location = _dalamudUtilService.GetMapData(); var territoryId = (ushort)location.TerritoryId; var worldId = (ushort)location.ServerId; @@ -697,7 +697,7 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS { try { - var worldId = (ushort)await _dalamudUtilService.GetWorldIdAsync().ConfigureAwait(false); + var worldId = (ushort)_dalamudUtilService.GetWorldId(); return definition.Descriptor with { WorldId = worldId }; } catch (Exception ex) @@ -1149,7 +1149,7 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS { try { - return _dalamudUtilService.GetPlayerNameAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + return _dalamudUtilService.GetPlayerName(); } catch (Exception ex) { diff --git a/LightlessSync/Services/ContextMenuService.cs b/LightlessSync/Services/ContextMenuService.cs index 7d35529..3fe893c 100644 --- a/LightlessSync/Services/ContextMenuService.cs +++ b/LightlessSync/Services/ContextMenuService.cs @@ -241,7 +241,7 @@ internal class ContextMenuService : IHostedService return; } - var senderCid = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256(); + var senderCid = _dalamudUtil.GetCID().ToString().GetHash256(); var receiverCid = DalamudUtilService.GetHashedCIDFromPlayerPointer(targetData.Address); _logger.LogInformation("Sending pair request: sender {SenderCid}, receiver {ReceiverCid}", senderCid, receiverCid); diff --git a/LightlessSync/Services/DalamudUtilService.cs b/LightlessSync/Services/DalamudUtilService.cs index 91d0037..ef6fe7a 100644 --- a/LightlessSync/Services/DalamudUtilService.cs +++ b/LightlessSync/Services/DalamudUtilService.cs @@ -1,5 +1,4 @@ using Dalamud.Game.ClientState.Conditions; -using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Plugin.Services; @@ -37,6 +36,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber private readonly ICondition _condition; private readonly IDataManager _gameData; private readonly IGameConfig _gameConfig; + private readonly IPlayerState _playerState; private readonly BlockedCharacterHandler _blockedCharacterHandler; private readonly IFramework _framework; private readonly IGameGui _gameGui; @@ -60,7 +60,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber private Lazy _cid; public DalamudUtilService(ILogger logger, IClientState clientState, IObjectTable objectTable, IFramework framework, - IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager, IGameConfig gameConfig, + IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager, IGameConfig gameConfig, IPlayerState playerState, ActorObjectService actorObjectService, BlockedCharacterHandler blockedCharacterHandler, LightlessMediator mediator, PerformanceCollectorService performanceCollector, LightlessConfigService configService, PlayerPerformanceConfigService playerPerformanceConfigService, Lazy pairFactory) { @@ -72,6 +72,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber _condition = condition; _gameData = gameData; _gameConfig = gameConfig; + _playerState = playerState; _actorObjectService = actorObjectService; _targetManager = targetManager; _blockedCharacterHandler = blockedCharacterHandler; @@ -95,6 +96,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber TerritoryData = new(() => BuildTerritoryData(clientLanguage)); TerritoryDataEnglish = new(() => BuildTerritoryData(Dalamud.Game.ClientLanguage.English)); MapData = new(() => BuildMapData(clientLanguage)); + ContentFinderData = new Lazy>(() => + { + return _gameData.GetExcelSheet()! + .Where(w => w.RowId != 0 && !string.IsNullOrEmpty(w.ContentFinderCondition.ValueNullable?.Name.ToString())) + .ToDictionary(w => w.RowId, w => w.ContentFinderCondition.Value.Name.ToString()); + }); mediator.Subscribe(this, (msg) => { if (clientState.IsPvP) return; @@ -279,6 +286,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public Lazy> TerritoryData { get; private set; } public Lazy> TerritoryDataEnglish { get; private set; } public Lazy> MapData { get; private set; } + public Lazy> ContentFinderData { get; private set; } public bool IsLodEnabled { get; private set; } public LightlessMediator Mediator { get; } @@ -372,7 +380,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public bool GetIsPlayerPresent() { EnsureIsOnFramework(); - return _objectTable.LocalPlayer != null && _objectTable.LocalPlayer.IsValid(); + return _objectTable.LocalPlayer != null && _objectTable.LocalPlayer.IsValid() && _playerState.IsLoaded; } public async Task GetIsPlayerPresentAsync() @@ -517,34 +525,17 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public string GetPlayerName() { - EnsureIsOnFramework(); - return _objectTable.LocalPlayer?.Name.ToString() ?? "--"; - } - - public async Task GetPlayerNameAsync() - { - return await RunOnFrameworkThread(GetPlayerName).ConfigureAwait(false); - } - - public async Task GetCIDAsync() - { - return await RunOnFrameworkThread(GetCID).ConfigureAwait(false); + return _playerState.CharacterName; } public unsafe ulong GetCID() { - EnsureIsOnFramework(); - var playerChar = GetPlayerCharacter(); - - if (playerChar == null || playerChar.Address == IntPtr.Zero) - return 0; - - return ((BattleChara*)playerChar.Address)->Character.ContentId; + return _playerState.ContentId; } - public async Task GetPlayerNameHashedAsync() + public string GetPlayerNameHashed() { - return await RunOnFrameworkThread(() => _cid.Value.ToString().GetHash256()).ConfigureAwait(false); + return _cid.Value.ToString().GetHash256(); } public static unsafe bool TryGetHashedCID(IPlayerCharacter? playerCharacter, out string hashedCid) @@ -583,54 +574,100 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public uint GetHomeWorldId() { - EnsureIsOnFramework(); - return _objectTable.LocalPlayer?.HomeWorld.RowId ?? 0; + return _playerState.HomeWorld.RowId; } public uint GetWorldId() { - EnsureIsOnFramework(); - return _objectTable.LocalPlayer!.CurrentWorld.RowId; + return _playerState.CurrentWorld.RowId; } public unsafe LocationInfo GetMapData() { - EnsureIsOnFramework(); - var agentMap = AgentMap.Instance(); var houseMan = HousingManager.Instance(); - uint serverId = 0; - if (_objectTable.LocalPlayer == null) serverId = 0; - else serverId = _objectTable.LocalPlayer.CurrentWorld.RowId; - uint mapId = agentMap == null ? 0 : agentMap->CurrentMapId; - uint territoryId = agentMap == null ? 0 : agentMap->CurrentTerritoryId; - uint divisionId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentDivision()); - uint wardId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentWard() + 1); - uint houseId = 0; - var tempHouseId = houseMan == null ? 0 : (houseMan->GetCurrentPlot()); - if (!houseMan->IsInside()) tempHouseId = 0; - if (tempHouseId < -1) - { - divisionId = tempHouseId == -127 ? 2 : (uint)1; - tempHouseId = 100; - } - if (tempHouseId == -1) tempHouseId = 0; - houseId = (uint)tempHouseId; - if (houseId != 0) - { - territoryId = HousingManager.GetOriginalHouseTerritoryTypeId(); - } - uint roomId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentRoom()); - return new LocationInfo() + var location = new LocationInfo(); + location.ServerId = _playerState.CurrentWorld.RowId; + //location.InstanceId = UIState.Instance()->PublicInstance.InstanceId; //TODO:Need API update first + location.TerritoryId = _clientState.TerritoryType; + location.MapId = _clientState.MapId; + if (houseMan != null) { - ServerId = serverId, - MapId = mapId, - TerritoryId = territoryId, - DivisionId = divisionId, - WardId = wardId, - HouseId = houseId, - RoomId = roomId - }; + if (houseMan->IsInside()) + { + location.TerritoryId = HousingManager.GetOriginalHouseTerritoryTypeId(); + var house = houseMan->GetCurrentIndoorHouseId(); + location.WardId = house.WardIndex + 1u; + location.HouseId = house.IsApartment ? 100 : house.PlotIndex + 1u; + location.RoomId = (uint)house.RoomNumber; + location.DivisionId = house.IsApartment ? house.ApartmentDivision + 1u : houseMan->GetCurrentDivision(); + } + else if (houseMan->IsInWorkshop()) + { + var workShop = houseMan->WorkshopTerritory; + var house = workShop->HouseId; + location.WardId = house.WardIndex + 1u; + location.HouseId = house.PlotIndex + 1u; + } + else if (houseMan->IsOutside()) + { + var outside = houseMan->OutdoorTerritory; + var house = outside->HouseId; + location.WardId = house.WardIndex + 1u; + location.HouseId = (uint)houseMan->GetCurrentPlot() + 1; + location.DivisionId = houseMan->GetCurrentDivision(); + } + //_logger.LogWarning(LocationToString(location)); + } + return location; + } + + public string LocationToString(LocationInfo location) + { + if (location.ServerId is 0 || location.TerritoryId is 0) return String.Empty; + var str = WorldData.Value[(ushort)location.ServerId]; + + if (ContentFinderData.Value.TryGetValue(location.TerritoryId , out var dutyName)) + { + str += $" - [In Duty]{dutyName}"; + } + else + { + if (location.HouseId is not 0 || location.MapId is 0) // Dont show mapName when in house/no map available + { + str += $" - {TerritoryData.Value[(ushort)location.TerritoryId]}"; + } + else + { + str += $" - {MapData.Value[(ushort)location.MapId].MapName}"; + } + + // if (location.InstanceId is not 0) + // { + // str += ((SeIconChar)(57520 + location.InstanceId)).ToIconString(); + // } + + if (location.WardId is not 0) + { + str += $" Ward #{location.WardId}"; + } + + if (location.HouseId is not 0 and not 100) + { + str += $" House #{location.HouseId}"; + } + else if (location.HouseId is 100) + { + str += $" {(location.DivisionId == 2 ? "[Subdivision]" : "")} Apartment"; + } + + if (location.RoomId is not 0) + { + str += $" Room #{location.RoomId}"; + } + } + + return str; } public unsafe void SetMarkerAndOpenMap(Vector3 position, Map map) @@ -642,21 +679,6 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber agentMap->SetFlagMapMarker(map.TerritoryType.RowId, map.RowId, position); } - public async Task GetMapDataAsync() - { - return await RunOnFrameworkThread(GetMapData).ConfigureAwait(false); - } - - public async Task GetWorldIdAsync() - { - return await RunOnFrameworkThread(GetWorldId).ConfigureAwait(false); - } - - public async Task GetHomeWorldIdAsync() - { - return await RunOnFrameworkThread(GetHomeWorldId).ConfigureAwait(false); - } - public unsafe bool IsGameObjectPresent(IntPtr key) { return _objectTable.Any(f => f.Address == key); diff --git a/LightlessSync/Services/LightFinder/LightFinderService.cs b/LightlessSync/Services/LightFinder/LightFinderService.cs index 82a51c7..f07064c 100644 --- a/LightlessSync/Services/LightFinder/LightFinderService.cs +++ b/LightlessSync/Services/LightFinder/LightFinderService.cs @@ -67,7 +67,7 @@ public class LightFinderService : IHostedService, IMediatorSubscriber { try { - var cid = await _dalamudUtil.GetCIDAsync().ConfigureAwait(false); + var cid = _dalamudUtil.GetCID(); return cid.ToString().GetHash256(); } catch (Exception ex) diff --git a/LightlessSync/Services/ServerConfiguration/ServerConfigurationManager.cs b/LightlessSync/Services/ServerConfiguration/ServerConfigurationManager.cs index 5cb3e15..339f462 100644 --- a/LightlessSync/Services/ServerConfiguration/ServerConfigurationManager.cs +++ b/LightlessSync/Services/ServerConfiguration/ServerConfigurationManager.cs @@ -101,9 +101,9 @@ public class ServerConfigurationManager } hasMulti = false; - var charaName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(); - var worldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(); - var cid = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult(); + var charaName = _dalamudUtil.GetPlayerName(); + var worldId = _dalamudUtil.GetHomeWorldId(); + var cid = _dalamudUtil.GetCID(); var auth = currentServer.Authentications.FindAll(f => string.Equals(f.CharacterName, charaName) && f.WorldId == worldId); if (auth.Count >= 2) @@ -148,9 +148,9 @@ public class ServerConfigurationManager } hasMulti = false; - var charaName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(); - var worldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(); - var cid = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult(); + var charaName = _dalamudUtil.GetPlayerName(); + var worldId = _dalamudUtil.GetHomeWorldId(); + var cid = _dalamudUtil.GetCID(); if (!currentServer.Authentications.Any() && currentServer.SecretKeys.Any()) { currentServer.Authentications.Add(new Authentication() @@ -268,16 +268,16 @@ public class ServerConfigurationManager { if (serverSelectionIndex == -1) serverSelectionIndex = CurrentServerIndex; var server = GetServerByIndex(serverSelectionIndex); - if (server.Authentications.Exists(c => string.Equals(c.CharacterName, _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(), StringComparison.Ordinal) - && c.WorldId == _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult())) + if (server.Authentications.Exists(c => string.Equals(c.CharacterName, _dalamudUtil.GetPlayerName(), StringComparison.Ordinal) + && c.WorldId == _dalamudUtil.GetHomeWorldId())) return; server.Authentications.Add(new Authentication() { - CharacterName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(), - WorldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(), + CharacterName = _dalamudUtil.GetPlayerName(), + WorldId = _dalamudUtil.GetHomeWorldId(), SecretKeyIdx = !server.UseOAuth2 ? server.SecretKeys.Last().Key : -1, - LastSeenCID = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult() + LastSeenCID = _dalamudUtil.GetCID() }); Save(); } diff --git a/LightlessSync/UI/DtrEntry.cs b/LightlessSync/UI/DtrEntry.cs index 9cadb4c..71eddfb 100644 --- a/LightlessSync/UI/DtrEntry.cs +++ b/LightlessSync/UI/DtrEntry.cs @@ -344,7 +344,7 @@ public sealed class DtrEntry : IDisposable, IHostedService try { - var cid = _dalamudUtilService.GetCIDAsync().GetAwaiter().GetResult(); + var cid = _dalamudUtilService.GetCID(); var hashedCid = cid.ToString().GetHash256(); _localHashedCid = hashedCid; _localHashedCidFetchedAt = now; diff --git a/LightlessSync/UI/TopTabMenu.cs b/LightlessSync/UI/TopTabMenu.cs index 92215fe..1297fa6 100644 --- a/LightlessSync/UI/TopTabMenu.cs +++ b/LightlessSync/UI/TopTabMenu.cs @@ -440,7 +440,7 @@ public class TopTabMenu try { - var myCidHash = (await _dalamudUtilService.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256(); + var myCidHash = _dalamudUtilService.GetCID().ToString().GetHash256(); await _apiController.TryPairWithContentId(request.HashedCid).ConfigureAwait(false); _pairRequestService.RemoveRequest(request.HashedCid); diff --git a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs index 2f317b9..fdc4719 100644 --- a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs +++ b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs @@ -193,7 +193,7 @@ public partial class ApiController CensusDataDto? censusDto = null; if (_serverManager.SendCensusData && _lastCensus != null) { - var world = await _dalamudUtil.GetWorldIdAsync().ConfigureAwait(false); + var world = _dalamudUtil.GetWorldId(); censusDto = new((ushort)world, _lastCensus.RaceId, _lastCensus.TribeId, _lastCensus.Gender); Logger.LogDebug("Attaching Census Data: {data}", censusDto); } diff --git a/LightlessSync/WebAPI/SignalR/ApiController.cs b/LightlessSync/WebAPI/SignalR/ApiController.cs index 14c90ca..9639f6f 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.cs @@ -544,8 +544,8 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL private void DalamudUtilOnLogIn() { - var charaName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(); - var worldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(); + var charaName = _dalamudUtil.GetPlayerName(); + var worldId = _dalamudUtil.GetHomeWorldId(); var auth = _serverManager.CurrentServer.Authentications.Find(f => string.Equals(f.CharacterName, charaName, StringComparison.Ordinal) && f.WorldId == worldId); if (auth?.AutoLogin ?? false) { @@ -653,7 +653,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL CensusDataDto? dto = null; if (_serverManager.SendCensusData && _lastCensus != null) { - var world = await _dalamudUtil.GetWorldIdAsync().ConfigureAwait(false); + var world = _dalamudUtil.GetWorldId(); dto = new((ushort)world, _lastCensus.RaceId, _lastCensus.TribeId, _lastCensus.Gender); Logger.LogDebug("Attaching Census Data: {data}", dto); } diff --git a/LightlessSync/WebAPI/SignalR/TokenProvider.cs b/LightlessSync/WebAPI/SignalR/TokenProvider.cs index fa23363..2446986 100644 --- a/LightlessSync/WebAPI/SignalR/TokenProvider.cs +++ b/LightlessSync/WebAPI/SignalR/TokenProvider.cs @@ -72,7 +72,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent( [ new KeyValuePair("auth", auth), - new KeyValuePair("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)), + new KeyValuePair("charaIdent", _dalamudUtil.GetPlayerNameHashed()), ]), ct).ConfigureAwait(false); } else @@ -152,7 +152,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber JwtIdentifier jwtIdentifier; try { - var playerIdentifier = await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false); + var playerIdentifier = _dalamudUtil.GetPlayerNameHashed(); if (string.IsNullOrEmpty(playerIdentifier)) { -- 2.49.1 From 70745613e13cb27dd7e90d30a811bd8b1f28d965 Mon Sep 17 00:00:00 2001 From: Tsubasahane Date: Sat, 27 Dec 2025 19:57:21 +0800 Subject: [PATCH 2/3] Location Sharing --- LightlessAPI | 2 +- LightlessSync/Plugin.cs | 1 + LightlessSync/Services/DalamudUtilService.cs | 13 ++-- .../Services/LocationShareService.cs | 78 +++++++++++++++++++ LightlessSync/Services/Mediator/Messages.cs | 2 + .../UI/Components/DrawFolderGroup.cs | 8 ++ LightlessSync/UI/Components/DrawUserPair.cs | 75 ++++++++++++++++++ LightlessSync/UI/DrawEntityFactory.cs | 4 + LightlessSync/UI/PermissionWindowUI.cs | 20 +++++ .../SignalR/ApIController.Functions.Users.cs | 12 +++ .../ApiController.Functions.Callbacks.cs | 13 ++++ LightlessSync/WebAPI/SignalR/ApiController.cs | 2 + 12 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 LightlessSync/Services/LocationShareService.cs diff --git a/LightlessAPI b/LightlessAPI index 5656600..fdd492a 160000 --- a/LightlessAPI +++ b/LightlessAPI @@ -1 +1 @@ -Subproject commit 56566003e0e93bba05dcef49fd3ce23c6a204d81 +Subproject commit fdd492a8f478949d910ed0efd3e4a3ca3312ed9c diff --git a/LightlessSync/Plugin.cs b/LightlessSync/Plugin.cs index cd57c34..4131e40 100644 --- a/LightlessSync/Plugin.cs +++ b/LightlessSync/Plugin.cs @@ -137,6 +137,7 @@ public sealed class Plugin : IDalamudPlugin services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(sp => new TextureMetadataHelper(sp.GetRequiredService>(), gameData)); diff --git a/LightlessSync/Services/DalamudUtilService.cs b/LightlessSync/Services/DalamudUtilService.cs index ef6fe7a..36ce98b 100644 --- a/LightlessSync/Services/DalamudUtilService.cs +++ b/LightlessSync/Services/DalamudUtilService.cs @@ -1,11 +1,13 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Game.Text; using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Control; +using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using LightlessSync.API.Dto.CharaData; @@ -25,6 +27,7 @@ using System.Runtime.CompilerServices; using System.Text; using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; +using Map = Lumina.Excel.Sheets.Map; using VisibilityFlags = FFXIVClientStructs.FFXIV.Client.Game.Object.VisibilityFlags; namespace LightlessSync.Services; @@ -588,7 +591,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber var location = new LocationInfo(); location.ServerId = _playerState.CurrentWorld.RowId; - //location.InstanceId = UIState.Instance()->PublicInstance.InstanceId; //TODO:Need API update first + location.InstanceId = UIState.Instance()->PublicInstance.InstanceId; location.TerritoryId = _clientState.TerritoryType; location.MapId = _clientState.MapId; if (houseMan != null) @@ -642,10 +645,10 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber str += $" - {MapData.Value[(ushort)location.MapId].MapName}"; } - // if (location.InstanceId is not 0) - // { - // str += ((SeIconChar)(57520 + location.InstanceId)).ToIconString(); - // } + if (location.InstanceId is not 0) + { + str += ((SeIconChar)(57520 + location.InstanceId)).ToIconString(); + } if (location.WardId is not 0) { diff --git a/LightlessSync/Services/LocationShareService.cs b/LightlessSync/Services/LocationShareService.cs new file mode 100644 index 0000000..0d3f5dc --- /dev/null +++ b/LightlessSync/Services/LocationShareService.cs @@ -0,0 +1,78 @@ +using LightlessSync.API.Data; +using LightlessSync.API.Dto.CharaData; +using LightlessSync.API.Dto.User; +using LightlessSync.Services.Mediator; +using LightlessSync.WebAPI; +using Microsoft.Extensions.Logging; + +namespace LightlessSync.Services +{ + public class LocationShareService : DisposableMediatorSubscriberBase + { + private readonly DalamudUtilService _dalamudUtilService; + private readonly ApiController _apiController; + private Dictionary _locations = []; + + public LocationShareService(ILogger logger, LightlessMediator mediator, DalamudUtilService dalamudUtilService, ApiController apiController) : base(logger, mediator) + { + _dalamudUtilService = dalamudUtilService; + _apiController = apiController; + + + Mediator.Subscribe(this, (msg) => _locations.Clear()); + Mediator.Subscribe(this, (msg) => + { + _ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, apiController.DisplayName), _dalamudUtilService.GetMapData())); + _ = RequestAllLocation(); + } ); + Mediator.Subscribe(this, UpdateLocationList); + Mediator.Subscribe(this, + msg => _ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, _apiController.DisplayName), _dalamudUtilService.GetMapData()))); + } + + private void UpdateLocationList(LocationMessage msg) + { + if (_locations.ContainsKey(msg.Uid) && msg.LocationInfo.ServerId is 0) + { + _locations.Remove(msg.Uid); + return; + } + + if ( msg.LocationInfo.ServerId is not 0 && !_locations.TryAdd(msg.Uid, msg.LocationInfo)) + { + _locations[msg.Uid] = msg.LocationInfo; + } + } + + private async Task RequestAllLocation() + { + try + { + var data = await _apiController.RequestAllLocationInfo().ConfigureAwait(false); + _locations = data.ToDictionary(x => x.user.UID, x => x.location, StringComparer.Ordinal); + } + catch (Exception e) + { + Logger.LogError(e,"RequestAllLocation error : "); + throw; + } + } + + public string GetUserLocation(string uid) + { + try + { + if (_locations.TryGetValue(uid, out var location)) + { + return _dalamudUtilService.LocationToString(location); + } + return String.Empty; + } + catch (Exception e) + { + Logger.LogError(e,"GetUserLocation error : "); + throw; + } + } + } +} \ No newline at end of file diff --git a/LightlessSync/Services/Mediator/Messages.cs b/LightlessSync/Services/Mediator/Messages.cs index 758b9f5..be0c06b 100644 --- a/LightlessSync/Services/Mediator/Messages.cs +++ b/LightlessSync/Services/Mediator/Messages.cs @@ -135,5 +135,7 @@ public record ChatChannelsUpdated : MessageBase; public record ChatChannelMessageAdded(string ChannelKey, ChatMessageEntry Message) : MessageBase; public record GroupCollectionChangedMessage : MessageBase; public record OpenUserProfileMessage(UserData User) : MessageBase; +public record LocationMessage(string Uid, LocationInfo LocationInfo) : MessageBase; + #pragma warning restore S2094 #pragma warning restore MA0048 // File name must match type name \ No newline at end of file diff --git a/LightlessSync/UI/Components/DrawFolderGroup.cs b/LightlessSync/UI/Components/DrawFolderGroup.cs index c39326c..277115a 100644 --- a/LightlessSync/UI/Components/DrawFolderGroup.cs +++ b/LightlessSync/UI/Components/DrawFolderGroup.cs @@ -131,6 +131,7 @@ public class DrawFolderGroup : DrawFolderBase bool disableSounds = perm.IsDisableSounds(); bool disableAnims = perm.IsDisableAnimations(); bool disableVfx = perm.IsDisableVFX(); + bool shareLocation = perm.IsSharingLocation(); if ((_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations() != disableAnims || _groupFullInfoDto.GroupPermissions.IsPreferDisableSounds() != disableSounds @@ -164,6 +165,13 @@ public class DrawFolderGroup : DrawFolderBase _ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm)); ImGui.CloseCurrentPopup(); } + + if (_uiSharedService.IconTextButton(!shareLocation ? FontAwesomeIcon.Globe : FontAwesomeIcon.StopCircle, !shareLocation ? "Share your location to all users in Syncshell" : "STOP Share your location to all users in Syncshell", menuWidth, true)) + { + perm.SetShareLocation(!shareLocation); + _ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm)); + ImGui.CloseCurrentPopup(); + } if (IsModerator || IsOwner) { diff --git a/LightlessSync/UI/Components/DrawUserPair.cs b/LightlessSync/UI/Components/DrawUserPair.cs index 8e03ae4..5f3d300 100644 --- a/LightlessSync/UI/Components/DrawUserPair.cs +++ b/LightlessSync/UI/Components/DrawUserPair.cs @@ -37,6 +37,7 @@ public class DrawUserPair private readonly UiSharedService _uiSharedService; private readonly PlayerPerformanceConfigService _performanceConfigService; private readonly LightlessConfigService _configService; + private readonly LocationShareService _locationShareService; private readonly CharaDataManager _charaDataManager; private readonly PairLedger _pairLedger; private float _menuWidth = -1; @@ -57,6 +58,7 @@ public class DrawUserPair UiSharedService uiSharedService, PlayerPerformanceConfigService performanceConfigService, LightlessConfigService configService, + LocationShareService locationShareService, CharaDataManager charaDataManager, PairLedger pairLedger) { @@ -74,6 +76,7 @@ public class DrawUserPair _uiSharedService = uiSharedService; _performanceConfigService = performanceConfigService; _configService = configService; + _locationShareService = locationShareService; _charaDataManager = charaDataManager; _pairLedger = pairLedger; } @@ -216,6 +219,17 @@ public class DrawUserPair _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions)); } UiSharedService.AttachToolTip("Changes VFX sync permissions with this user." + (individual ? individualText : string.Empty)); + + var isShareingLocation = _pair.UserPair!.OwnPermissions.IsSharingLocation(); + string isShareingLocationText = isShareingLocation ? "Disable location sharing" : "Enable location sharing"; + var isShareingLocationIcon = isShareingLocation ? FontAwesomeIcon.StopCircle : FontAwesomeIcon.Globe; + if (_uiSharedService.IconTextButton(isShareingLocationIcon, isShareingLocationText, _menuWidth, true)) + { + var permissions = _pair.UserPair.OwnPermissions; + permissions.SetShareLocation(!isShareingLocation); + _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions)); + } + UiSharedService.AttachToolTip("Changes location sharing permissions with this user." + (individual ? individualText : string.Empty)); } private void DrawIndividualMenu() @@ -567,6 +581,7 @@ public class DrawUserPair : UiSharedService.TooltipSeparator + "Hold CTRL to enable preferred permissions while pausing." + Environment.NewLine + "This will leave this pair paused even if unpausing syncshells including this pair.")) : "Resume pairing with " + _pair.UserData.AliasOrUID); + //Location sharing if (_pair.IsPaired) { var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false); @@ -574,6 +589,66 @@ public class DrawUserPair var individualVFXDisabled = (_pair.UserPair?.OwnPermissions.IsDisableVFX() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableVFX() ?? false); var individualIsSticky = _pair.UserPair!.OwnPermissions.IsSticky(); var individualIcon = individualIsSticky ? FontAwesomeIcon.ArrowCircleUp : FontAwesomeIcon.InfoCircle; + + + var shareLocationIcon = FontAwesomeIcon.Globe; + var shareLocation = _pair.UserPair?.OwnPermissions.IsSharingLocation() ?? false; + var shareLocationOther = _pair.UserPair?.OtherPermissions.IsSharingLocation() ?? false; + var shareColor = shareLocation switch + { + true when shareLocationOther => UIColors.Get("LightlessGreen"), + false when shareLocationOther => UIColors.Get("LightlessBlue"), + _ => UIColors.Get("LightlessYellow"), + }; + + if (shareLocation || shareLocationOther) + { + currentRightSide -= (_uiSharedService.GetIconSize(shareLocationIcon).X + spacingX); + ImGui.SameLine(currentRightSide); + using (ImRaii.PushColor(ImGuiCol.Text, shareColor, shareLocation || shareLocationOther)) + _uiSharedService.IconText(shareLocationIcon); + + if (ImGui.IsItemHovered()) + { + ImGui.BeginTooltip(); + if (shareLocationOther) + { + var location = _locationShareService.GetUserLocation(_pair.UserPair!.User.UID); + if (_pair.IsOnline) + { + if (!string.IsNullOrEmpty(location)) + { + _uiSharedService.IconText(FontAwesomeIcon.LocationArrow); + ImGui.SameLine(); + ImGui.TextUnformatted(location); + } + else + { + ImGui.TextUnformatted("Location info not updated, reconnect or waiting for zone-changing."); + } + } + else + { + ImGui.TextUnformatted("User not onlineㄟ( ▔, ▔ )ㄏ"); + } + } + else + { + ImGui.TextUnformatted("NOT Sharing location with you.(⊙x⊙;)"); + } + ImGui.Separator(); + + if (shareLocation) + { + ImGui.TextUnformatted("Sharing your location.ヾ(•ω•`)o"); + } + else + { + ImGui.TextUnformatted("NOT sharing your location.(´。_。`)"); + } + ImGui.EndTooltip(); + } + } if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled || individualIsSticky) { diff --git a/LightlessSync/UI/DrawEntityFactory.cs b/LightlessSync/UI/DrawEntityFactory.cs index 3c71f5c..e810a29 100644 --- a/LightlessSync/UI/DrawEntityFactory.cs +++ b/LightlessSync/UI/DrawEntityFactory.cs @@ -28,6 +28,7 @@ public class DrawEntityFactory private readonly ServerConfigurationManager _serverConfigurationManager; private readonly LightlessConfigService _configService; private readonly UiSharedService _uiSharedService; + private readonly LocationShareService _locationShareService; private readonly PlayerPerformanceConfigService _playerPerformanceConfigService; private readonly CharaDataManager _charaDataManager; private readonly SelectTagForPairUi _selectTagForPairUi; @@ -52,6 +53,7 @@ public class DrawEntityFactory ServerConfigurationManager serverConfigurationManager, LightlessConfigService configService, UiSharedService uiSharedService, + LocationShareService locationShareService, PlayerPerformanceConfigService playerPerformanceConfigService, CharaDataManager charaDataManager, SelectTagForSyncshellUi selectTagForSyncshellUi, @@ -71,6 +73,7 @@ public class DrawEntityFactory _serverConfigurationManager = serverConfigurationManager; _configService = configService; _uiSharedService = uiSharedService; + _locationShareService = locationShareService; _playerPerformanceConfigService = playerPerformanceConfigService; _charaDataManager = charaDataManager; _selectTagForSyncshellUi = selectTagForSyncshellUi; @@ -162,6 +165,7 @@ public class DrawEntityFactory _uiSharedService, _playerPerformanceConfigService, _configService, + _locationShareService, _charaDataManager, _pairLedger); } diff --git a/LightlessSync/UI/PermissionWindowUI.cs b/LightlessSync/UI/PermissionWindowUI.cs index 5dee098..9d88547 100644 --- a/LightlessSync/UI/PermissionWindowUI.cs +++ b/LightlessSync/UI/PermissionWindowUI.cs @@ -43,6 +43,7 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase var disableSounds = _ownPermissions.IsDisableSounds(); var disableAnimations = _ownPermissions.IsDisableAnimations(); var disableVfx = _ownPermissions.IsDisableVFX(); + var shareLocation = _ownPermissions.IsSharingLocation(); var style = ImGui.GetStyle(); var indentSize = ImGui.GetFrameHeight() + style.ItemSpacing.X; @@ -70,6 +71,7 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase var otherDisableSounds = otherPerms.IsDisableSounds(); var otherDisableAnimations = otherPerms.IsDisableAnimations(); var otherDisableVFX = otherPerms.IsDisableVFX(); + var otherShareLocation = otherPerms.IsSharingLocation(); using (ImRaii.PushIndent(indentSize, false)) { @@ -124,6 +126,24 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase ImGui.AlignTextToFramePadding(); ImGui.Text(Pair.UserData.AliasOrUID + " has " + (!otherDisableVFX ? "not " : string.Empty) + "disabled VFX sync with you"); } + + if (ImGui.Checkbox("Enable location Sharing", ref shareLocation)) + { + _ownPermissions.SetShareLocation(shareLocation); + } + _uiSharedService.DrawHelpText("Enable location sharing will only effect your side." + UiSharedService.TooltipSeparator + + "Note: this is NOT bidirectional, you can choose to share even others dont share with you."); + using (ImRaii.PushIndent(indentSize, false)) + { + _uiSharedService.BooleanToColoredIcon(shareLocation, false); + ImGui.SameLine(); + ImGui.AlignTextToFramePadding(); + ImGui.Text((!shareLocation ? "Not" : string.Empty) + "sharing location with " + Pair.UserData.AliasOrUID + " ."); + +#if DEBUG + _uiSharedService.BooleanToColoredIcon(otherShareLocation, true); +#endif + } ImGuiHelpers.ScaledDummy(0.5f); ImGui.Separator(); diff --git a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs index fdc4719..6cd704f 100644 --- a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs +++ b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs @@ -200,5 +200,17 @@ public partial class ApiController await UserPushData(new(visibleCharacters, character, censusDto)).ConfigureAwait(false); } + + public async Task UpdateLocation(LocationDto locationDto, bool offline = false) + { + if (!IsConnected) return; + await _lightlessHub!.SendAsync(nameof(UpdateLocation), locationDto, offline).ConfigureAwait(false); + } + + public async Task> RequestAllLocationInfo() + { + if (!IsConnected) return []; + return await _lightlessHub!.InvokeAsync>(nameof(RequestAllLocationInfo)).ConfigureAwait(false); + } } #pragma warning restore MA0040 \ No newline at end of file diff --git a/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs b/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs index 490800f..01abc88 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs @@ -259,6 +259,13 @@ public partial class ApiController ExecuteSafely(() => Mediator.Publish(new GPoseLobbyReceiveWorldData(userData, worldData))); return Task.CompletedTask; } + + public Task Client_SendLocationToClient(LocationDto locationDto) + { + Logger.LogDebug($"{nameof(Client_SendLocationToClient)}: {locationDto.user}"); + ExecuteSafely(() => Mediator.Publish(new LocationMessage(locationDto.user.UID, locationDto.location))); + return Task.CompletedTask; + } public void OnDownloadReady(Action act) { @@ -440,6 +447,12 @@ public partial class ApiController if (_initialized) return; _lightlessHub!.On(nameof(Client_GposeLobbyPushWorldData), act); } + + public void OnReciveLocation(Action act) + { + if (_initialized) return; + _lightlessHub!.On(nameof(Client_SendLocationToClient), act); + } private void ExecuteSafely(Action act) { diff --git a/LightlessSync/WebAPI/SignalR/ApiController.cs b/LightlessSync/WebAPI/SignalR/ApiController.cs index 9639f6f..a814758 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.cs @@ -606,6 +606,8 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL OnGposeLobbyPushCharacterData((dto) => _ = Client_GposeLobbyPushCharacterData(dto)); OnGposeLobbyPushPoseData((dto, data) => _ = Client_GposeLobbyPushPoseData(dto, data)); OnGposeLobbyPushWorldData((dto, data) => _ = Client_GposeLobbyPushWorldData(dto, data)); + OnReciveLocation(dto => _ = Client_SendLocationToClient(dto)); + _healthCheckTokenSource?.Cancel(); _healthCheckTokenSource?.Dispose(); -- 2.49.1 From eeda5aeb66943d3075c04882dd35ec5e4bb3992b Mon Sep 17 00:00:00 2001 From: Tsubasahane Date: Sun, 28 Dec 2025 10:54:01 +0800 Subject: [PATCH 3/3] Revert "Location Sharing" This reverts commit 70745613e13cb27dd7e90d30a811bd8b1f28d965. --- LightlessAPI | 2 +- LightlessSync/Plugin.cs | 1 - LightlessSync/Services/DalamudUtilService.cs | 13 ++-- .../Services/LocationShareService.cs | 78 ------------------- LightlessSync/Services/Mediator/Messages.cs | 2 - .../UI/Components/DrawFolderGroup.cs | 8 -- LightlessSync/UI/Components/DrawUserPair.cs | 75 ------------------ LightlessSync/UI/DrawEntityFactory.cs | 4 - LightlessSync/UI/PermissionWindowUI.cs | 20 ----- .../SignalR/ApIController.Functions.Users.cs | 12 --- .../ApiController.Functions.Callbacks.cs | 13 ---- LightlessSync/WebAPI/SignalR/ApiController.cs | 2 - 12 files changed, 6 insertions(+), 224 deletions(-) delete mode 100644 LightlessSync/Services/LocationShareService.cs diff --git a/LightlessAPI b/LightlessAPI index fdd492a..5656600 160000 --- a/LightlessAPI +++ b/LightlessAPI @@ -1 +1 @@ -Subproject commit fdd492a8f478949d910ed0efd3e4a3ca3312ed9c +Subproject commit 56566003e0e93bba05dcef49fd3ce23c6a204d81 diff --git a/LightlessSync/Plugin.cs b/LightlessSync/Plugin.cs index 4131e40..cd57c34 100644 --- a/LightlessSync/Plugin.cs +++ b/LightlessSync/Plugin.cs @@ -137,7 +137,6 @@ public sealed class Plugin : IDalamudPlugin services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(sp => new TextureMetadataHelper(sp.GetRequiredService>(), gameData)); diff --git a/LightlessSync/Services/DalamudUtilService.cs b/LightlessSync/Services/DalamudUtilService.cs index 36ce98b..ef6fe7a 100644 --- a/LightlessSync/Services/DalamudUtilService.cs +++ b/LightlessSync/Services/DalamudUtilService.cs @@ -1,13 +1,11 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Game.Text; using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Control; -using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using LightlessSync.API.Dto.CharaData; @@ -27,7 +25,6 @@ using System.Runtime.CompilerServices; using System.Text; using DalamudObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; -using Map = Lumina.Excel.Sheets.Map; using VisibilityFlags = FFXIVClientStructs.FFXIV.Client.Game.Object.VisibilityFlags; namespace LightlessSync.Services; @@ -591,7 +588,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber var location = new LocationInfo(); location.ServerId = _playerState.CurrentWorld.RowId; - location.InstanceId = UIState.Instance()->PublicInstance.InstanceId; + //location.InstanceId = UIState.Instance()->PublicInstance.InstanceId; //TODO:Need API update first location.TerritoryId = _clientState.TerritoryType; location.MapId = _clientState.MapId; if (houseMan != null) @@ -645,10 +642,10 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber str += $" - {MapData.Value[(ushort)location.MapId].MapName}"; } - if (location.InstanceId is not 0) - { - str += ((SeIconChar)(57520 + location.InstanceId)).ToIconString(); - } + // if (location.InstanceId is not 0) + // { + // str += ((SeIconChar)(57520 + location.InstanceId)).ToIconString(); + // } if (location.WardId is not 0) { diff --git a/LightlessSync/Services/LocationShareService.cs b/LightlessSync/Services/LocationShareService.cs deleted file mode 100644 index 0d3f5dc..0000000 --- a/LightlessSync/Services/LocationShareService.cs +++ /dev/null @@ -1,78 +0,0 @@ -using LightlessSync.API.Data; -using LightlessSync.API.Dto.CharaData; -using LightlessSync.API.Dto.User; -using LightlessSync.Services.Mediator; -using LightlessSync.WebAPI; -using Microsoft.Extensions.Logging; - -namespace LightlessSync.Services -{ - public class LocationShareService : DisposableMediatorSubscriberBase - { - private readonly DalamudUtilService _dalamudUtilService; - private readonly ApiController _apiController; - private Dictionary _locations = []; - - public LocationShareService(ILogger logger, LightlessMediator mediator, DalamudUtilService dalamudUtilService, ApiController apiController) : base(logger, mediator) - { - _dalamudUtilService = dalamudUtilService; - _apiController = apiController; - - - Mediator.Subscribe(this, (msg) => _locations.Clear()); - Mediator.Subscribe(this, (msg) => - { - _ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, apiController.DisplayName), _dalamudUtilService.GetMapData())); - _ = RequestAllLocation(); - } ); - Mediator.Subscribe(this, UpdateLocationList); - Mediator.Subscribe(this, - msg => _ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, _apiController.DisplayName), _dalamudUtilService.GetMapData()))); - } - - private void UpdateLocationList(LocationMessage msg) - { - if (_locations.ContainsKey(msg.Uid) && msg.LocationInfo.ServerId is 0) - { - _locations.Remove(msg.Uid); - return; - } - - if ( msg.LocationInfo.ServerId is not 0 && !_locations.TryAdd(msg.Uid, msg.LocationInfo)) - { - _locations[msg.Uid] = msg.LocationInfo; - } - } - - private async Task RequestAllLocation() - { - try - { - var data = await _apiController.RequestAllLocationInfo().ConfigureAwait(false); - _locations = data.ToDictionary(x => x.user.UID, x => x.location, StringComparer.Ordinal); - } - catch (Exception e) - { - Logger.LogError(e,"RequestAllLocation error : "); - throw; - } - } - - public string GetUserLocation(string uid) - { - try - { - if (_locations.TryGetValue(uid, out var location)) - { - return _dalamudUtilService.LocationToString(location); - } - return String.Empty; - } - catch (Exception e) - { - Logger.LogError(e,"GetUserLocation error : "); - throw; - } - } - } -} \ No newline at end of file diff --git a/LightlessSync/Services/Mediator/Messages.cs b/LightlessSync/Services/Mediator/Messages.cs index be0c06b..758b9f5 100644 --- a/LightlessSync/Services/Mediator/Messages.cs +++ b/LightlessSync/Services/Mediator/Messages.cs @@ -135,7 +135,5 @@ public record ChatChannelsUpdated : MessageBase; public record ChatChannelMessageAdded(string ChannelKey, ChatMessageEntry Message) : MessageBase; public record GroupCollectionChangedMessage : MessageBase; public record OpenUserProfileMessage(UserData User) : MessageBase; -public record LocationMessage(string Uid, LocationInfo LocationInfo) : MessageBase; - #pragma warning restore S2094 #pragma warning restore MA0048 // File name must match type name \ No newline at end of file diff --git a/LightlessSync/UI/Components/DrawFolderGroup.cs b/LightlessSync/UI/Components/DrawFolderGroup.cs index 277115a..c39326c 100644 --- a/LightlessSync/UI/Components/DrawFolderGroup.cs +++ b/LightlessSync/UI/Components/DrawFolderGroup.cs @@ -131,7 +131,6 @@ public class DrawFolderGroup : DrawFolderBase bool disableSounds = perm.IsDisableSounds(); bool disableAnims = perm.IsDisableAnimations(); bool disableVfx = perm.IsDisableVFX(); - bool shareLocation = perm.IsSharingLocation(); if ((_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations() != disableAnims || _groupFullInfoDto.GroupPermissions.IsPreferDisableSounds() != disableSounds @@ -165,13 +164,6 @@ public class DrawFolderGroup : DrawFolderBase _ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm)); ImGui.CloseCurrentPopup(); } - - if (_uiSharedService.IconTextButton(!shareLocation ? FontAwesomeIcon.Globe : FontAwesomeIcon.StopCircle, !shareLocation ? "Share your location to all users in Syncshell" : "STOP Share your location to all users in Syncshell", menuWidth, true)) - { - perm.SetShareLocation(!shareLocation); - _ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm)); - ImGui.CloseCurrentPopup(); - } if (IsModerator || IsOwner) { diff --git a/LightlessSync/UI/Components/DrawUserPair.cs b/LightlessSync/UI/Components/DrawUserPair.cs index 5f3d300..8e03ae4 100644 --- a/LightlessSync/UI/Components/DrawUserPair.cs +++ b/LightlessSync/UI/Components/DrawUserPair.cs @@ -37,7 +37,6 @@ public class DrawUserPair private readonly UiSharedService _uiSharedService; private readonly PlayerPerformanceConfigService _performanceConfigService; private readonly LightlessConfigService _configService; - private readonly LocationShareService _locationShareService; private readonly CharaDataManager _charaDataManager; private readonly PairLedger _pairLedger; private float _menuWidth = -1; @@ -58,7 +57,6 @@ public class DrawUserPair UiSharedService uiSharedService, PlayerPerformanceConfigService performanceConfigService, LightlessConfigService configService, - LocationShareService locationShareService, CharaDataManager charaDataManager, PairLedger pairLedger) { @@ -76,7 +74,6 @@ public class DrawUserPair _uiSharedService = uiSharedService; _performanceConfigService = performanceConfigService; _configService = configService; - _locationShareService = locationShareService; _charaDataManager = charaDataManager; _pairLedger = pairLedger; } @@ -219,17 +216,6 @@ public class DrawUserPair _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions)); } UiSharedService.AttachToolTip("Changes VFX sync permissions with this user." + (individual ? individualText : string.Empty)); - - var isShareingLocation = _pair.UserPair!.OwnPermissions.IsSharingLocation(); - string isShareingLocationText = isShareingLocation ? "Disable location sharing" : "Enable location sharing"; - var isShareingLocationIcon = isShareingLocation ? FontAwesomeIcon.StopCircle : FontAwesomeIcon.Globe; - if (_uiSharedService.IconTextButton(isShareingLocationIcon, isShareingLocationText, _menuWidth, true)) - { - var permissions = _pair.UserPair.OwnPermissions; - permissions.SetShareLocation(!isShareingLocation); - _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions)); - } - UiSharedService.AttachToolTip("Changes location sharing permissions with this user." + (individual ? individualText : string.Empty)); } private void DrawIndividualMenu() @@ -581,7 +567,6 @@ public class DrawUserPair : UiSharedService.TooltipSeparator + "Hold CTRL to enable preferred permissions while pausing." + Environment.NewLine + "This will leave this pair paused even if unpausing syncshells including this pair.")) : "Resume pairing with " + _pair.UserData.AliasOrUID); - //Location sharing if (_pair.IsPaired) { var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false); @@ -589,66 +574,6 @@ public class DrawUserPair var individualVFXDisabled = (_pair.UserPair?.OwnPermissions.IsDisableVFX() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableVFX() ?? false); var individualIsSticky = _pair.UserPair!.OwnPermissions.IsSticky(); var individualIcon = individualIsSticky ? FontAwesomeIcon.ArrowCircleUp : FontAwesomeIcon.InfoCircle; - - - var shareLocationIcon = FontAwesomeIcon.Globe; - var shareLocation = _pair.UserPair?.OwnPermissions.IsSharingLocation() ?? false; - var shareLocationOther = _pair.UserPair?.OtherPermissions.IsSharingLocation() ?? false; - var shareColor = shareLocation switch - { - true when shareLocationOther => UIColors.Get("LightlessGreen"), - false when shareLocationOther => UIColors.Get("LightlessBlue"), - _ => UIColors.Get("LightlessYellow"), - }; - - if (shareLocation || shareLocationOther) - { - currentRightSide -= (_uiSharedService.GetIconSize(shareLocationIcon).X + spacingX); - ImGui.SameLine(currentRightSide); - using (ImRaii.PushColor(ImGuiCol.Text, shareColor, shareLocation || shareLocationOther)) - _uiSharedService.IconText(shareLocationIcon); - - if (ImGui.IsItemHovered()) - { - ImGui.BeginTooltip(); - if (shareLocationOther) - { - var location = _locationShareService.GetUserLocation(_pair.UserPair!.User.UID); - if (_pair.IsOnline) - { - if (!string.IsNullOrEmpty(location)) - { - _uiSharedService.IconText(FontAwesomeIcon.LocationArrow); - ImGui.SameLine(); - ImGui.TextUnformatted(location); - } - else - { - ImGui.TextUnformatted("Location info not updated, reconnect or waiting for zone-changing."); - } - } - else - { - ImGui.TextUnformatted("User not onlineㄟ( ▔, ▔ )ㄏ"); - } - } - else - { - ImGui.TextUnformatted("NOT Sharing location with you.(⊙x⊙;)"); - } - ImGui.Separator(); - - if (shareLocation) - { - ImGui.TextUnformatted("Sharing your location.ヾ(•ω•`)o"); - } - else - { - ImGui.TextUnformatted("NOT sharing your location.(´。_。`)"); - } - ImGui.EndTooltip(); - } - } if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled || individualIsSticky) { diff --git a/LightlessSync/UI/DrawEntityFactory.cs b/LightlessSync/UI/DrawEntityFactory.cs index e810a29..3c71f5c 100644 --- a/LightlessSync/UI/DrawEntityFactory.cs +++ b/LightlessSync/UI/DrawEntityFactory.cs @@ -28,7 +28,6 @@ public class DrawEntityFactory private readonly ServerConfigurationManager _serverConfigurationManager; private readonly LightlessConfigService _configService; private readonly UiSharedService _uiSharedService; - private readonly LocationShareService _locationShareService; private readonly PlayerPerformanceConfigService _playerPerformanceConfigService; private readonly CharaDataManager _charaDataManager; private readonly SelectTagForPairUi _selectTagForPairUi; @@ -53,7 +52,6 @@ public class DrawEntityFactory ServerConfigurationManager serverConfigurationManager, LightlessConfigService configService, UiSharedService uiSharedService, - LocationShareService locationShareService, PlayerPerformanceConfigService playerPerformanceConfigService, CharaDataManager charaDataManager, SelectTagForSyncshellUi selectTagForSyncshellUi, @@ -73,7 +71,6 @@ public class DrawEntityFactory _serverConfigurationManager = serverConfigurationManager; _configService = configService; _uiSharedService = uiSharedService; - _locationShareService = locationShareService; _playerPerformanceConfigService = playerPerformanceConfigService; _charaDataManager = charaDataManager; _selectTagForSyncshellUi = selectTagForSyncshellUi; @@ -165,7 +162,6 @@ public class DrawEntityFactory _uiSharedService, _playerPerformanceConfigService, _configService, - _locationShareService, _charaDataManager, _pairLedger); } diff --git a/LightlessSync/UI/PermissionWindowUI.cs b/LightlessSync/UI/PermissionWindowUI.cs index 9d88547..5dee098 100644 --- a/LightlessSync/UI/PermissionWindowUI.cs +++ b/LightlessSync/UI/PermissionWindowUI.cs @@ -43,7 +43,6 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase var disableSounds = _ownPermissions.IsDisableSounds(); var disableAnimations = _ownPermissions.IsDisableAnimations(); var disableVfx = _ownPermissions.IsDisableVFX(); - var shareLocation = _ownPermissions.IsSharingLocation(); var style = ImGui.GetStyle(); var indentSize = ImGui.GetFrameHeight() + style.ItemSpacing.X; @@ -71,7 +70,6 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase var otherDisableSounds = otherPerms.IsDisableSounds(); var otherDisableAnimations = otherPerms.IsDisableAnimations(); var otherDisableVFX = otherPerms.IsDisableVFX(); - var otherShareLocation = otherPerms.IsSharingLocation(); using (ImRaii.PushIndent(indentSize, false)) { @@ -126,24 +124,6 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase ImGui.AlignTextToFramePadding(); ImGui.Text(Pair.UserData.AliasOrUID + " has " + (!otherDisableVFX ? "not " : string.Empty) + "disabled VFX sync with you"); } - - if (ImGui.Checkbox("Enable location Sharing", ref shareLocation)) - { - _ownPermissions.SetShareLocation(shareLocation); - } - _uiSharedService.DrawHelpText("Enable location sharing will only effect your side." + UiSharedService.TooltipSeparator - + "Note: this is NOT bidirectional, you can choose to share even others dont share with you."); - using (ImRaii.PushIndent(indentSize, false)) - { - _uiSharedService.BooleanToColoredIcon(shareLocation, false); - ImGui.SameLine(); - ImGui.AlignTextToFramePadding(); - ImGui.Text((!shareLocation ? "Not" : string.Empty) + "sharing location with " + Pair.UserData.AliasOrUID + " ."); - -#if DEBUG - _uiSharedService.BooleanToColoredIcon(otherShareLocation, true); -#endif - } ImGuiHelpers.ScaledDummy(0.5f); ImGui.Separator(); diff --git a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs index 6cd704f..fdc4719 100644 --- a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs +++ b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs @@ -200,17 +200,5 @@ public partial class ApiController await UserPushData(new(visibleCharacters, character, censusDto)).ConfigureAwait(false); } - - public async Task UpdateLocation(LocationDto locationDto, bool offline = false) - { - if (!IsConnected) return; - await _lightlessHub!.SendAsync(nameof(UpdateLocation), locationDto, offline).ConfigureAwait(false); - } - - public async Task> RequestAllLocationInfo() - { - if (!IsConnected) return []; - return await _lightlessHub!.InvokeAsync>(nameof(RequestAllLocationInfo)).ConfigureAwait(false); - } } #pragma warning restore MA0040 \ No newline at end of file diff --git a/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs b/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs index 01abc88..490800f 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.Functions.Callbacks.cs @@ -259,13 +259,6 @@ public partial class ApiController ExecuteSafely(() => Mediator.Publish(new GPoseLobbyReceiveWorldData(userData, worldData))); return Task.CompletedTask; } - - public Task Client_SendLocationToClient(LocationDto locationDto) - { - Logger.LogDebug($"{nameof(Client_SendLocationToClient)}: {locationDto.user}"); - ExecuteSafely(() => Mediator.Publish(new LocationMessage(locationDto.user.UID, locationDto.location))); - return Task.CompletedTask; - } public void OnDownloadReady(Action act) { @@ -447,12 +440,6 @@ public partial class ApiController if (_initialized) return; _lightlessHub!.On(nameof(Client_GposeLobbyPushWorldData), act); } - - public void OnReciveLocation(Action act) - { - if (_initialized) return; - _lightlessHub!.On(nameof(Client_SendLocationToClient), act); - } private void ExecuteSafely(Action act) { diff --git a/LightlessSync/WebAPI/SignalR/ApiController.cs b/LightlessSync/WebAPI/SignalR/ApiController.cs index a814758..9639f6f 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.cs @@ -606,8 +606,6 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL OnGposeLobbyPushCharacterData((dto) => _ = Client_GposeLobbyPushCharacterData(dto)); OnGposeLobbyPushPoseData((dto, data) => _ = Client_GposeLobbyPushPoseData(dto, data)); OnGposeLobbyPushWorldData((dto, data) => _ = Client_GposeLobbyPushWorldData(dto, data)); - OnReciveLocation(dto => _ = Client_SendLocationToClient(dto)); - _healthCheckTokenSource?.Cancel(); _healthCheckTokenSource?.Dispose(); -- 2.49.1