Reimplemented profile conversion to V5 using some heuristics based on excel sheets
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
|
||||
65
CustomizePlus.GameData/Data/ReverseNameDicts.cs
Normal file
65
CustomizePlus.GameData/Data/ReverseNameDicts.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using CustomizePlus.GameData.ReverseSearchDictionaries;
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.GameData.DataContainers;
|
||||
using Penumbra.GameData.Structs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CustomizePlus.GameData.Data;
|
||||
|
||||
/// <summary> A collection service for all the name dictionaries required for reverse name search. </summary>
|
||||
/// note: this is mvp for profile upgrading purposes, not intended to be used for anything else.
|
||||
public sealed class ReverseNameDicts(
|
||||
ReverseSearchDictMount _mounts,
|
||||
ReverseSearchDictCompanion _companions,
|
||||
ReverseSearchDictBNpc _bNpcs,
|
||||
ReverseSearchDictENpc _eNpcs)
|
||||
: IAsyncService
|
||||
{
|
||||
/// <summary> Valid Mount ids by name in title case. </summary>
|
||||
public readonly ReverseSearchDictMount Mounts = _mounts;
|
||||
|
||||
/// <summary> Valid Companion ids by name in title case. </summary>
|
||||
public readonly ReverseSearchDictCompanion Companions = _companions;
|
||||
|
||||
/// <summary> Valid BNPC ids by name in title case. </summary>
|
||||
public readonly ReverseSearchDictBNpc BNpcs = _bNpcs;
|
||||
|
||||
/// <summary> Valid ENPC ids by name in title case. </summary>
|
||||
public readonly ReverseSearchDictENpc ENpcs = _eNpcs;
|
||||
|
||||
/// <summary> Finished when all name dictionaries are finished. </summary>
|
||||
public Task Awaiter { get; } =
|
||||
Task.WhenAll(_mounts.Awaiter, _companions.Awaiter, _bNpcs.Awaiter, _eNpcs.Awaiter);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Finished
|
||||
=> Awaiter.IsCompletedSuccessfully;
|
||||
|
||||
/// <summary> Convert a given name for a certain ObjectKind to an ID. </summary>
|
||||
/// <returns> default or a valid id. </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public uint ToID(ObjectKind kind, string name)
|
||||
=> TryGetID(kind, name, out var ret) ? ret : default;
|
||||
|
||||
/// <summary> Convert a given ID for a certain ObjectKind to a name. </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public bool TryGetID(ObjectKind kind, string name, [NotNullWhen(true)] out uint npcId)
|
||||
{
|
||||
npcId = default;
|
||||
return kind switch
|
||||
{
|
||||
ObjectKind.MountType => Mounts.TryGetValue(name, out npcId),
|
||||
ObjectKind.Companion => Companions.TryGetValue(name, out npcId),
|
||||
ObjectKind.BattleNpc => BNpcs.TryGetValue(name, out npcId),
|
||||
ObjectKind.EventNpc => ENpcs.TryGetValue(name, out npcId),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Plugin;
|
||||
using FFXIVClientStructs.FFXIV.Common.Lua;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.DataContainers.Bases;
|
||||
using Penumbra.GameData.Structs;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CustomizePlus.GameData.ReverseSearchDictionaries.Bases;
|
||||
|
||||
/// <summary> A base class for dictionaries from NPC names to their IDs. </summary>
|
||||
/// <param name="pluginInterface"> The plugin interface. </param>
|
||||
/// <param name="log"> A logger. </param>
|
||||
/// <param name="gameData"> The data manger to fetch the data from. </param>
|
||||
/// <param name="name"> The name of the data share. </param>
|
||||
/// <param name="version"> The version of the data share. </param>
|
||||
/// <param name="factory"> The factory function to create the data from. </param>
|
||||
public abstract class ReverseNameDictionary(
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
Logger log,
|
||||
IDataManager gameData,
|
||||
string name,
|
||||
int version,
|
||||
Func<IReadOnlyDictionary<string, uint>> factory)
|
||||
: DataSharer<IReadOnlyDictionary<string, uint>>(pluginInterface, log, name, gameData.Language, version, factory),
|
||||
IReadOnlyDictionary<string, NpcId>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IEnumerator<KeyValuePair<string, NpcId>> GetEnumerator()
|
||||
=> Value.Select(kvp => new KeyValuePair<string, NpcId>(kvp.Key, new NpcId(kvp.Value))).GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Count
|
||||
=> Value.Count;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ContainsKey(string key)
|
||||
=> Value.ContainsKey(key);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool TryGetValue(string key, [NotNullWhen(true)] out NpcId value)
|
||||
{
|
||||
if (!Value.TryGetValue(key, out var uintVal))
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = new NpcId(uintVal);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public NpcId this[string key]
|
||||
=> new NpcId(Value[key]);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<string> Keys
|
||||
=> Value.Keys;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<NpcId> Values
|
||||
=> Value.Values.Select(k => new NpcId(k));
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override long ComputeMemory()
|
||||
=> DataUtility.DictionaryMemory(16, Count) + Keys.Sum(v => v.Length * 2); //this seems to be only used by diagnostics stuff so I don't particularly care for this to be correct.
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override int ComputeTotalCount()
|
||||
=> Count;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Plugin;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Data;
|
||||
using System.Collections.Frozen;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using CustomizePlus.GameData.ReverseSearchDictionaries.Bases;
|
||||
|
||||
namespace CustomizePlus.GameData.ReverseSearchDictionaries;
|
||||
|
||||
/// <summary> A dictionary that matches names to battle npc ids. </summary>
|
||||
public sealed class ReverseSearchDictBNpc(IDalamudPluginInterface pluginInterface, Logger log, IDataManager gameData)
|
||||
: ReverseNameDictionary(pluginInterface, log, gameData, "ReverseSearchBNpcs", 7, () => CreateBNpcData(gameData))
|
||||
{
|
||||
/// <summary> Create the data. </summary>
|
||||
private static IReadOnlyDictionary<string, uint> CreateBNpcData(IDataManager gameData)
|
||||
{
|
||||
var sheet = gameData.GetExcelSheet<BNpcName>(gameData.Language)!;
|
||||
var dict = new Dictionary<string, uint>((int)sheet.RowCount);
|
||||
foreach (var n in sheet.Where(n => n.Singular.RawData.Length > 0))
|
||||
dict.TryAdd(DataUtility.ToTitleCaseExtended(n.Singular, n.Article), n.RowId);
|
||||
return dict.ToFrozenDictionary();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.TryGetValue"/>
|
||||
public bool TryGetValue(string key, [NotNullWhen(true)] out uint value)
|
||||
=> Value.TryGetValue(key, out value);
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.this"/>
|
||||
public uint this[string key]
|
||||
=> Value[key];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Plugin;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Data;
|
||||
using System.Collections.Frozen;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using CustomizePlus.GameData.ReverseSearchDictionaries.Bases;
|
||||
|
||||
namespace CustomizePlus.GameData.ReverseSearchDictionaries;
|
||||
|
||||
/// <summary> A dictionary that matches companion names to their ids. </summary>
|
||||
public sealed class ReverseSearchDictCompanion(IDalamudPluginInterface pluginInterface, Logger log, IDataManager gameData)
|
||||
: ReverseNameDictionary(pluginInterface, log, gameData, "ReverseSearchCompanions", 7, () => CreateCompanionData(gameData))
|
||||
{
|
||||
/// <summary> Create the data. </summary>
|
||||
private static IReadOnlyDictionary<string, uint> CreateCompanionData(IDataManager gameData)
|
||||
{
|
||||
var sheet = gameData.GetExcelSheet<Companion>(gameData.Language)!;
|
||||
var dict = new Dictionary<string, uint>((int)sheet.RowCount);
|
||||
foreach (var c in sheet.Where(c => c.Singular.RawData.Length > 0 && c.Order < ushort.MaxValue))
|
||||
dict.TryAdd(DataUtility.ToTitleCaseExtended(c.Singular, c.Article), c.RowId);
|
||||
return dict.ToFrozenDictionary();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.TryGetValue"/>
|
||||
public bool TryGetValue(string key, [NotNullWhen(true)] out uint value)
|
||||
=> Value.TryGetValue(key, out value);
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.this"/>
|
||||
public uint this[string key]
|
||||
=> Value[key];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Plugin;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Data;
|
||||
using System.Collections.Frozen;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using CustomizePlus.GameData.ReverseSearchDictionaries.Bases;
|
||||
|
||||
namespace CustomizePlus.GameData.ReverseSearchDictionaries;
|
||||
|
||||
/// <summary> A dictionary that matches names to event npc ids. </summary>
|
||||
public sealed class ReverseSearchDictENpc(IDalamudPluginInterface pluginInterface, Logger log, IDataManager gameData)
|
||||
: ReverseNameDictionary(pluginInterface, log, gameData, "ReverseSearchENpcs", 7, () => CreateENpcData(gameData))
|
||||
{
|
||||
/// <summary> Create the data. </summary>
|
||||
private static IReadOnlyDictionary<string, uint> CreateENpcData(IDataManager gameData)
|
||||
{
|
||||
var sheet = gameData.GetExcelSheet<ENpcResident>(gameData.Language)!;
|
||||
var dict = new Dictionary<string, uint>((int)sheet.RowCount);
|
||||
foreach (var n in sheet.Where(e => e.Singular.RawData.Length > 0))
|
||||
dict.TryAdd(DataUtility.ToTitleCaseExtended(n.Singular, n.Article), n.RowId);
|
||||
return dict.ToFrozenDictionary();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.TryGetValue"/>
|
||||
public bool TryGetValue(string key, [NotNullWhen(true)] out uint value)
|
||||
=> Value.TryGetValue(key, out value);
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.this"/>
|
||||
public uint this[string key]
|
||||
=> Value[key];
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Plugin;
|
||||
using OtterGui.Log;
|
||||
using Penumbra.GameData.Data;
|
||||
using System.Collections.Frozen;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using CustomizePlus.GameData.ReverseSearchDictionaries.Bases;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace CustomizePlus.GameData.ReverseSearchDictionaries;
|
||||
|
||||
/// <summary> A dictionary that matches names to mount ids. </summary>
|
||||
public sealed class ReverseSearchDictMount(IDalamudPluginInterface pluginInterface, Logger log, IDataManager gameData)
|
||||
: ReverseNameDictionary(pluginInterface, log, gameData, "ReverseSearchMounts", 7, () => CreateMountData(gameData))
|
||||
{
|
||||
/// <summary> Create the data. </summary>
|
||||
private static IReadOnlyDictionary<string, uint> CreateMountData(IDataManager gameData)
|
||||
{
|
||||
var sheet = gameData.GetExcelSheet<Mount>(gameData.Language)!;
|
||||
var dict = new Dictionary<string, uint>((int)sheet.RowCount);
|
||||
// Add some custom data.
|
||||
dict.TryAdd("Falcon (Porter)", 119);
|
||||
dict.TryAdd("Hippo Cart (Quest)", 295);
|
||||
dict.TryAdd("Hippo Cart (Quest)", 296);
|
||||
dict.TryAdd("Miw Miisv (Quest)", 298);
|
||||
dict.TryAdd("Moon-hopper (Quest)", 309);
|
||||
foreach (var m in sheet)
|
||||
{
|
||||
if (m.Singular.RawData.Length > 0 && m.Order >= 0)
|
||||
{
|
||||
dict.TryAdd(DataUtility.ToTitleCaseExtended(m.Singular, m.Article), m.RowId);
|
||||
}
|
||||
else if (m.Unknown18.RawData.Length > 0)
|
||||
{
|
||||
// Try to transform some file names into category names.
|
||||
var whistle = m.Unknown18.ToDalamudString().ToString();
|
||||
whistle = whistle.Replace("SE_Bt_Etc_", string.Empty)
|
||||
.Replace("Mount_", string.Empty)
|
||||
.Replace("_call", string.Empty)
|
||||
.Replace("Whistle", string.Empty);
|
||||
dict.TryAdd($"? {whistle} #{m.RowId}", m.RowId);
|
||||
}
|
||||
}
|
||||
|
||||
return dict.ToFrozenDictionary();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.TryGetValue"/>
|
||||
public bool TryGetValue(string key, [NotNullWhen(true)] out uint value)
|
||||
=> Value.TryGetValue(key, out value);
|
||||
|
||||
/// <inheritdoc cref="ReverseNameDictionary.this"/>
|
||||
public uint this[string key]
|
||||
=> Value[key];
|
||||
}
|
||||
@@ -14,7 +14,7 @@ internal static class V3ProfileToV4Converter
|
||||
var profile = new Profile
|
||||
{
|
||||
Name = $"{v3Profile.ProfileName} - {v3Profile.CharacterName}",
|
||||
CharacterName = v3Profile.CharacterName,
|
||||
//CharacterName = v3Profile.CharacterName, //todo
|
||||
CreationDate = v3Profile.CreationDate,
|
||||
ModifiedDate = DateTimeOffset.UtcNow,
|
||||
Enabled = v3Profile.Enabled,
|
||||
|
||||
@@ -13,6 +13,7 @@ using static System.Windows.Forms.AxHost;
|
||||
using CustomizePlus.Profiles.Data;
|
||||
using CustomizePlus.Configuration.Data;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using CustomizePlus.GameData.Extensions;
|
||||
|
||||
namespace CustomizePlus.Core.Services;
|
||||
|
||||
@@ -182,10 +183,10 @@ public class CommandService : IDisposable
|
||||
if (!isTurningOffAllProfiles)
|
||||
{
|
||||
profileName = subArgumentList[1].Trim();
|
||||
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.Name == profileName && x.CharacterName == characterName);
|
||||
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.Name == profileName && x.Character.ToNameWithoutOwnerName() == characterName);
|
||||
}
|
||||
else
|
||||
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.CharacterName == characterName && x.Enabled);
|
||||
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.Character.ToNameWithoutOwnerName() == characterName && x.Enabled);
|
||||
|
||||
if (targetProfile == null)
|
||||
{
|
||||
@@ -224,7 +225,7 @@ public class CommandService : IDisposable
|
||||
.AddText(" was successfully ")
|
||||
.AddBlue(state != null ? ((bool)state ? "enabled" : "disabled") : "toggled")
|
||||
.AddText(" for ")
|
||||
.AddRed(targetProfile.CharacterName).BuiltString);
|
||||
.AddRed(targetProfile.Character.ToNameWithoutOwnerName()).BuiltString);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
using CustomizePlus.Armatures.Services;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using CustomizePlus.Armatures.Services;
|
||||
using CustomizePlus.Configuration.Data;
|
||||
using CustomizePlus.Core.Data;
|
||||
using CustomizePlus.Core.Extensions;
|
||||
using CustomizePlus.Profiles;
|
||||
using CustomizePlus.Templates;
|
||||
using Dalamud.Plugin;
|
||||
using OtterGui.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CustomizePlus.Core.Services;
|
||||
|
||||
@@ -72,7 +68,7 @@ public class SupportLogBuilderService
|
||||
sb.Append($"> > **`{profile.ToString(),-32}`*\n");
|
||||
sb.Append($"> > **`Name: `** {profile.Name.Text.Incognify()}\n");
|
||||
sb.Append($"> > **`Type: `** {profile.ProfileType} \n");
|
||||
sb.Append($"> > **`Character name: `** {profile.CharacterName.Text.Incognify()}\n");
|
||||
sb.Append($"> > **`Character name: `** {profile.Character.Incognito(null)}\n");
|
||||
sb.Append($"> > **`Templates:`**\n");
|
||||
sb.Append($"> > > **`Count: `** {profile.Templates.Count}\n");
|
||||
foreach (var template in profile.Templates)
|
||||
|
||||
@@ -29,8 +29,8 @@ public sealed class Profile : ISavable
|
||||
|
||||
public List<Armature> Armatures = new();
|
||||
|
||||
[Obsolete("To be removed in the future versions")]
|
||||
public LowerString CharacterName { get; set; } = LowerString.Empty;
|
||||
/* [Obsolete("To be removed in the future versions")]
|
||||
public LowerString CharacterName { get; set; } = LowerString.Empty;*/
|
||||
|
||||
public ActorIdentifier Character { get; set; } = ActorIdentifier.Invalid;
|
||||
|
||||
@@ -101,7 +101,6 @@ public sealed class Profile : ISavable
|
||||
["UniqueId"] = UniqueId,
|
||||
["CreationDate"] = CreationDate,
|
||||
["ModifiedDate"] = ModifiedDate,
|
||||
["CharacterName"] = CharacterName.Text,
|
||||
["Character"] = Character.ToJson(),
|
||||
["Name"] = Name.Text,
|
||||
["Enabled"] = Enabled,
|
||||
|
||||
@@ -11,6 +11,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using Penumbra.String;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
using Penumbra.GameData.Gui;
|
||||
|
||||
namespace CustomizePlus.Profiles;
|
||||
|
||||
@@ -91,7 +93,39 @@ public partial class ProfileManager : IDisposable
|
||||
{
|
||||
var profile = LoadProfileV4V5(obj);
|
||||
|
||||
profile.CharacterName = new LowerString(obj["CharacterName"]?.ToObject<string>()?.Trim() ?? throw new ArgumentNullException("CharacterName"));
|
||||
var characterName = obj["CharacterName"]?.ToObject<string>()?.Trim() ?? throw new ArgumentNullException("CharacterName");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(characterName))
|
||||
return profile;
|
||||
|
||||
var nameWordsCnt = characterName.Split(' ').Length;
|
||||
if (nameWordsCnt == 2)
|
||||
profile.Character = _actorManager.CreatePlayer(ByteString.FromStringUnsafe(characterName, false), WorldId.AnyWorld);
|
||||
else if (_reverseNameDicts.TryGetID(ObjectKind.EventNpc, characterName, out var id))
|
||||
profile.Character = _actorManager.CreateNpc(ObjectKind.EventNpc, new NpcId(id));
|
||||
else if (_reverseNameDicts.TryGetID(ObjectKind.BattleNpc, characterName, out id))
|
||||
profile.Character = _actorManager.CreateNpc(ObjectKind.BattleNpc, new NpcId(id));
|
||||
else if (_reverseNameDicts.TryGetID(ObjectKind.MountType, characterName, out id))
|
||||
{
|
||||
var currentPlayer = _actorManager.GetCurrentPlayer();
|
||||
profile.Character = _actorManager.CreateOwned(currentPlayer.PlayerName, currentPlayer.HomeWorld, ObjectKind.MountType, new NpcId(id));
|
||||
}
|
||||
else if (_reverseNameDicts.TryGetID(ObjectKind.Companion, characterName, out id))
|
||||
{
|
||||
var currentPlayer = _actorManager.GetCurrentPlayer();
|
||||
profile.Character = _actorManager.CreateOwned(currentPlayer.PlayerName, currentPlayer.HomeWorld, ObjectKind.Companion, new NpcId(id));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warning($"Unable to automatically migrate \"{profile.Name}\" to V5, unknown character name: {characterName}");
|
||||
_messageService.NotificationMessage($"Unable to detect character type for profile \"{profile.Name}\", please set character for this profile manually.", Dalamud.Interface.ImGuiNotification.NotificationType.Error);
|
||||
}
|
||||
|
||||
if (profile.Character.IsValid)
|
||||
{
|
||||
_logger.Debug($"Upgraded profile \"{profile.Name}\" to V5: {characterName} -> {profile.Character}. Save queued.");
|
||||
_saveService.QueueSave(profile);
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
@@ -103,7 +137,6 @@ public partial class ProfileManager : IDisposable
|
||||
var character = _actorManager.FromJson(obj["Character"] as JObject);
|
||||
|
||||
profile.Character = character;
|
||||
profile.CharacterName = new LowerString(obj["CharacterName"]?.ToObject<string>()?.Trim() ?? throw new ArgumentNullException("CharacterName")); //temp
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ using Penumbra.GameData.Interop;
|
||||
using System.Runtime.Serialization;
|
||||
using CustomizePlus.Game.Services;
|
||||
using ObjectManager = CustomizePlus.GameData.Services.ObjectManager;
|
||||
using System.Threading.Tasks;
|
||||
using OtterGui.Classes;
|
||||
|
||||
namespace CustomizePlus.Profiles;
|
||||
|
||||
@@ -44,6 +46,8 @@ public partial class ProfileManager : IDisposable
|
||||
private readonly ActorManager _actorManager;
|
||||
private readonly GameObjectService _gameObjectService;
|
||||
private readonly ObjectManager _objectManager;
|
||||
private readonly ReverseNameDicts _reverseNameDicts;
|
||||
private readonly MessageService _messageService;
|
||||
private readonly ProfileChanged _event;
|
||||
private readonly TemplateChanged _templateChangedEvent;
|
||||
private readonly ReloadEvent _reloadEvent;
|
||||
@@ -63,6 +67,8 @@ public partial class ProfileManager : IDisposable
|
||||
ActorManager actorManager,
|
||||
GameObjectService gameObjectService,
|
||||
ObjectManager objectManager,
|
||||
ReverseNameDicts reverseNameDicts,
|
||||
MessageService messageService,
|
||||
ProfileChanged @event,
|
||||
TemplateChanged templateChangedEvent,
|
||||
ReloadEvent reloadEvent,
|
||||
@@ -76,6 +82,8 @@ public partial class ProfileManager : IDisposable
|
||||
_actorManager = actorManager;
|
||||
_gameObjectService = gameObjectService;
|
||||
_objectManager = objectManager;
|
||||
_reverseNameDicts = reverseNameDicts;
|
||||
_messageService = messageService;
|
||||
_event = @event;
|
||||
_templateChangedEvent = templateChangedEvent;
|
||||
_templateChangedEvent.Subscribe(OnTemplateChange, TemplateChanged.Priority.ProfileManager);
|
||||
@@ -86,7 +94,7 @@ public partial class ProfileManager : IDisposable
|
||||
|
||||
CreateProfileFolder(saveService);
|
||||
|
||||
LoadProfiles();
|
||||
_reverseNameDicts.Awaiter.ContinueWith(_ => LoadProfiles(), TaskScheduler.Default);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -467,7 +475,7 @@ public partial class ProfileManager : IDisposable
|
||||
if (actorIdentifier.Type == IdentifierType.Owned && !actorIdentifier.IsOwnedByLocalPlayer())
|
||||
return false;
|
||||
|
||||
return profile.CharacterName.Text == name || profile.Character.MatchesIgnoringOwnership(actorIdentifier);
|
||||
return profile.Character.MatchesIgnoringOwnership(actorIdentifier);
|
||||
}
|
||||
|
||||
if (_templateEditorManager.IsEditorActive && _templateEditorManager.EditorProfile.Enabled && IsProfileAppliesToCurrentActor(_templateEditorManager.EditorProfile))
|
||||
@@ -475,21 +483,9 @@ public partial class ProfileManager : IDisposable
|
||||
|
||||
foreach (var profile in Profiles)
|
||||
{
|
||||
if(IsProfileAppliesToCurrentActor(profile))
|
||||
{
|
||||
//todo: temp for migrations to v5
|
||||
//todo: make sure this works for minions and stuff
|
||||
if (!profile.Character.IsValid)
|
||||
{
|
||||
_logger.Warning($"No character for profile {profile}, but character has been found as: {actorIdentifier}, will set.");
|
||||
profile.Character = actorIdentifier;
|
||||
_saveService.QueueSave(profile);
|
||||
}
|
||||
|
||||
if (profile.Enabled)
|
||||
if(profile.Enabled && IsProfileAppliesToCurrentActor(profile))
|
||||
yield return profile;
|
||||
}
|
||||
}
|
||||
|
||||
if (DefaultLocalPlayerProfile != null && DefaultLocalPlayerProfile.Enabled)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,8 @@ public class StateMonitoringTab
|
||||
private void DrawSingleProfile(string prefix, Profile profile)
|
||||
{
|
||||
string name = profile.Name;
|
||||
string characterName = profile.CharacterName;
|
||||
string characterName = profile.Character.Type == Penumbra.GameData.Enums.IdentifierType.Owned ?
|
||||
profile.Character.ToNameWithoutOwnerName() : profile.Character.ToString();
|
||||
|
||||
#if INCOGNIFY_STRINGS
|
||||
name = name.Incognify();
|
||||
|
||||
@@ -210,7 +210,7 @@ public class ProfilePanel
|
||||
ImGuiUtil.DrawFrameColumn("Character");
|
||||
ImGui.TableNextColumn();
|
||||
width = new Vector2(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize("Limit to my creatures").X - 68, 0);
|
||||
//name = _newCharacterName ?? _selector.Selected!.CharacterName;
|
||||
|
||||
ImGui.SetNextItemWidth(width.X);
|
||||
|
||||
if (!_selector.IncognitoMode)
|
||||
@@ -220,7 +220,7 @@ public class ProfilePanel
|
||||
{
|
||||
ImGui.Text(_selector.Selected!.Character.IsValid ? $"Applies to {(_selector.Selected?.Character.Type == Penumbra.GameData.Enums.IdentifierType.Owned ?
|
||||
_selector.Selected?.Character.ToNameWithoutOwnerName() : _selector.Selected?.Character.ToString())}" : "No valid character selected for the profile");
|
||||
ImGui.Text($"Legacy: {_selector.Selected!.CharacterName.Text ?? "None"}");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
_actorAssignmentUi.DrawWorldCombo(width.X / 2);
|
||||
|
||||
Reference in New Issue
Block a user