implement playerState

- use IPlayerState for DalamudUtilService and make things less asynced
- make LocationInfo work with ContentFinderData
This commit is contained in:
Tsubasahane
2025-12-27 17:04:39 +08:00
parent 1632258c4f
commit 5c8e239a7b
16 changed files with 132 additions and 106 deletions

View File

@@ -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<ulong> _cid;
public DalamudUtilService(ILogger<DalamudUtilService> 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> 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<Dictionary<uint, string>>(() =>
{
return _gameData.GetExcelSheet<TerritoryType>()!
.Where(w => w.RowId != 0 && !string.IsNullOrEmpty(w.ContentFinderCondition.ValueNullable?.Name.ToString()))
.ToDictionary(w => w.RowId, w => w.ContentFinderCondition.Value.Name.ToString());
});
mediator.Subscribe<TargetPairMessage>(this, (msg) =>
{
if (clientState.IsPvP) return;
@@ -279,6 +286,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public Lazy<Dictionary<uint, string>> TerritoryData { get; private set; }
public Lazy<Dictionary<uint, string>> TerritoryDataEnglish { get; private set; }
public Lazy<Dictionary<uint, (Map Map, string MapName)>> MapData { get; private set; }
public Lazy<Dictionary<uint, string>> 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<bool> GetIsPlayerPresentAsync()
@@ -517,34 +525,17 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public string GetPlayerName()
{
EnsureIsOnFramework();
return _objectTable.LocalPlayer?.Name.ToString() ?? "--";
}
public async Task<string> GetPlayerNameAsync()
{
return await RunOnFrameworkThread(GetPlayerName).ConfigureAwait(false);
}
public async Task<ulong> 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<string> 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<LocationInfo> GetMapDataAsync()
{
return await RunOnFrameworkThread(GetMapData).ConfigureAwait(false);
}
public async Task<uint> GetWorldIdAsync()
{
return await RunOnFrameworkThread(GetWorldId).ConfigureAwait(false);
}
public async Task<uint> GetHomeWorldIdAsync()
{
return await RunOnFrameworkThread(GetHomeWorldId).ConfigureAwait(false);
}
public unsafe bool IsGameObjectPresent(IntPtr key)
{
return _objectTable.Any(f => f.Address == key);