mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-20 06:27:43 +01:00
Add IPC to set single items.
This commit is contained in:
parent
03a0cb5514
commit
aae4141550
4 changed files with 151 additions and 7 deletions
92
Glamourer/Api/GlamourerIpc.Set.cs
Normal file
92
Glamourer/Api/GlamourerIpc.Set.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Glamourer.Events;
|
||||||
|
using Glamourer.Services;
|
||||||
|
using Penumbra.Api.Helpers;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
|
public partial class GlamourerIpc
|
||||||
|
{
|
||||||
|
public enum GlamourerErrorCode
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
ActorNotFound,
|
||||||
|
ActorNotHuman,
|
||||||
|
ItemInvalid,
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string LabelSetItem = "Glamourer.SetItem";
|
||||||
|
public const string LabelSetItemByActorName = "Glamourer.SetItemByActorName";
|
||||||
|
|
||||||
|
|
||||||
|
private readonly FuncProvider<Character?, byte, ulong, uint, int> _setItemProvider;
|
||||||
|
private readonly FuncProvider<string, byte, ulong, uint, int> _setItemByActorNameProvider;
|
||||||
|
|
||||||
|
public static FuncSubscriber<Character?, byte, ulong, uint, int> SetItemSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelSetItem);
|
||||||
|
|
||||||
|
public static FuncSubscriber<string, byte, ulong, uint, int> SetItemByActorNameSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelSetItemByActorName);
|
||||||
|
|
||||||
|
private GlamourerErrorCode SetItem(Character? character, EquipSlot slot, CustomItemId itemId, uint key)
|
||||||
|
{
|
||||||
|
if (itemId.Id == 0)
|
||||||
|
itemId = ItemManager.NothingId(slot);
|
||||||
|
|
||||||
|
var item = _items.Resolve(slot, itemId);
|
||||||
|
if (!item.Valid)
|
||||||
|
return GlamourerErrorCode.ItemInvalid;
|
||||||
|
|
||||||
|
var identifier = _actors.FromObject(character, false, false, false);
|
||||||
|
if (!identifier.IsValid)
|
||||||
|
return GlamourerErrorCode.ActorNotFound;
|
||||||
|
|
||||||
|
if (!_stateManager.TryGetValue(identifier, out var state))
|
||||||
|
{
|
||||||
|
_objects.Update();
|
||||||
|
var data = _objects[identifier];
|
||||||
|
if (!data.Valid || !_stateManager.GetOrCreate(identifier, data.Objects[0], out state))
|
||||||
|
return GlamourerErrorCode.ActorNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.ModelData.IsHuman)
|
||||||
|
return GlamourerErrorCode.ActorNotHuman;
|
||||||
|
|
||||||
|
_stateManager.ChangeItem(state, slot, item, StateChanged.Source.Ipc, key);
|
||||||
|
return GlamourerErrorCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GlamourerErrorCode SetItemByActorName(string name, EquipSlot slot, CustomItemId itemId, uint key)
|
||||||
|
{
|
||||||
|
if (itemId.Id == 0)
|
||||||
|
itemId = ItemManager.NothingId(slot);
|
||||||
|
|
||||||
|
var item = _items.Resolve(slot, itemId);
|
||||||
|
if (!item.Valid)
|
||||||
|
return GlamourerErrorCode.ItemInvalid;
|
||||||
|
|
||||||
|
var found = false;
|
||||||
|
_objects.Update();
|
||||||
|
foreach (var identifier in FindActorsRevert(name).Distinct())
|
||||||
|
{
|
||||||
|
if (!_stateManager.TryGetValue(identifier, out var state))
|
||||||
|
{
|
||||||
|
var data = _objects[identifier];
|
||||||
|
if (!data.Valid || !_stateManager.GetOrCreate(identifier, data.Objects[0], out state))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.ModelData.IsHuman)
|
||||||
|
return GlamourerErrorCode.ActorNotHuman;
|
||||||
|
|
||||||
|
_stateManager.ChangeItem(state, slot, item, StateChanged.Source.Ipc, key);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found ? GlamourerErrorCode.Success : GlamourerErrorCode.ActorNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ using Glamourer.Automation;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Penumbra.Api.Helpers;
|
using Penumbra.Api.Helpers;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
|
|
@ -15,7 +16,7 @@ using Penumbra.String;
|
||||||
|
|
||||||
namespace Glamourer.Api;
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
public partial class GlamourerIpc : IDisposable
|
public sealed partial class GlamourerIpc : IDisposable
|
||||||
{
|
{
|
||||||
public const int CurrentApiVersionMajor = 0;
|
public const int CurrentApiVersionMajor = 0;
|
||||||
public const int CurrentApiVersionMinor = 4;
|
public const int CurrentApiVersionMinor = 4;
|
||||||
|
|
@ -25,15 +26,18 @@ public partial class GlamourerIpc : IDisposable
|
||||||
private readonly ActorManager _actors;
|
private readonly ActorManager _actors;
|
||||||
private readonly DesignConverter _designConverter;
|
private readonly DesignConverter _designConverter;
|
||||||
private readonly AutoDesignApplier _autoDesignApplier;
|
private readonly AutoDesignApplier _autoDesignApplier;
|
||||||
|
private readonly ItemManager _items;
|
||||||
|
|
||||||
public GlamourerIpc(DalamudPluginInterface pi, StateManager stateManager, ObjectManager objects, ActorManager actors,
|
public GlamourerIpc(DalamudPluginInterface pi, StateManager stateManager, ObjectManager objects, ActorManager actors,
|
||||||
DesignConverter designConverter, StateChanged stateChangedEvent, GPoseService gPose, AutoDesignApplier autoDesignApplier)
|
DesignConverter designConverter, StateChanged stateChangedEvent, GPoseService gPose, AutoDesignApplier autoDesignApplier,
|
||||||
|
ItemManager items)
|
||||||
{
|
{
|
||||||
_stateManager = stateManager;
|
_stateManager = stateManager;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_actors = actors;
|
_actors = actors;
|
||||||
_designConverter = designConverter;
|
_designConverter = designConverter;
|
||||||
_autoDesignApplier = autoDesignApplier;
|
_autoDesignApplier = autoDesignApplier;
|
||||||
|
_items = items;
|
||||||
_gPose = gPose;
|
_gPose = gPose;
|
||||||
_stateChangedEvent = stateChangedEvent;
|
_stateChangedEvent = stateChangedEvent;
|
||||||
_apiVersionProvider = new FuncProvider<int>(pi, LabelApiVersion, ApiVersion);
|
_apiVersionProvider = new FuncProvider<int>(pi, LabelApiVersion, ApiVersion);
|
||||||
|
|
@ -76,6 +80,11 @@ public partial class GlamourerIpc : IDisposable
|
||||||
_stateChangedProvider = new EventProvider<StateChanged.Type, nint, Lazy<string>>(pi, LabelStateChanged);
|
_stateChangedProvider = new EventProvider<StateChanged.Type, nint, Lazy<string>>(pi, LabelStateChanged);
|
||||||
_gPoseChangedProvider = new EventProvider<bool>(pi, LabelGPoseChanged);
|
_gPoseChangedProvider = new EventProvider<bool>(pi, LabelGPoseChanged);
|
||||||
|
|
||||||
|
_setItemProvider = new FuncProvider<Character?, byte, ulong, uint, int>(pi, LabelSetItem,
|
||||||
|
(idx, slot, item, key) => (int)SetItem(idx, (EquipSlot)slot, item, key));
|
||||||
|
_setItemByActorNameProvider = new FuncProvider<string, byte, ulong, uint, int>(pi, LabelSetItemByActorName,
|
||||||
|
(name, slot, item, key) => (int)SetItemByActorName(name, (EquipSlot)slot, item, key));
|
||||||
|
|
||||||
_stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc);
|
_stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc);
|
||||||
_gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc);
|
_gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc);
|
||||||
}
|
}
|
||||||
|
|
@ -114,6 +123,9 @@ public partial class GlamourerIpc : IDisposable
|
||||||
_stateChangedProvider.Dispose();
|
_stateChangedProvider.Dispose();
|
||||||
_gPose.Unsubscribe(OnGPoseChanged);
|
_gPose.Unsubscribe(OnGPoseChanged);
|
||||||
_gPoseChangedProvider.Dispose();
|
_gPoseChangedProvider.Dispose();
|
||||||
|
|
||||||
|
_setItemProvider.Dispose();
|
||||||
|
_setItemByActorNameProvider.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ActorIdentifier> FindActors(string actorName)
|
private IEnumerable<ActorIdentifier> FindActors(string actorName)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Api;
|
using Glamourer.Api;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Gui;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
|
|
@ -16,15 +20,20 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
public bool Disabled
|
public bool Disabled
|
||||||
=> false;
|
=> false;
|
||||||
|
|
||||||
private int _gameObjectIndex;
|
private int _gameObjectIndex;
|
||||||
private string _gameObjectName = string.Empty;
|
private CustomItemId _customItemId;
|
||||||
private string _base64Apply = string.Empty;
|
private EquipSlot _slot = EquipSlot.Head;
|
||||||
|
private string _gameObjectName = string.Empty;
|
||||||
|
private string _base64Apply = string.Empty;
|
||||||
|
private GlamourerIpc.GlamourerErrorCode _setItemEc;
|
||||||
|
private GlamourerIpc.GlamourerErrorCode _setItemByActorNameEc;
|
||||||
|
|
||||||
public void Draw()
|
public unsafe void Draw()
|
||||||
{
|
{
|
||||||
ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0);
|
ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0);
|
||||||
ImGui.InputTextWithHint("##gameObject", "Character Name...", ref _gameObjectName, 64);
|
ImGui.InputTextWithHint("##gameObject", "Character Name...", ref _gameObjectName, 64);
|
||||||
ImGui.InputTextWithHint("##base64", "Design Base64...", ref _base64Apply, 2047);
|
ImGui.InputTextWithHint("##base64", "Design Base64...", ref _base64Apply, 2047);
|
||||||
|
DrawItemIdInput();
|
||||||
using var table = ImRaii.Table("##ipc", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
using var table = ImRaii.Table("##ipc", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
@ -104,5 +113,36 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
if (ImGui.Button("Revert##CustomizeCharacter"))
|
if (ImGui.Button("Revert##CustomizeCharacter"))
|
||||||
GlamourerIpc.RevertToAutomationCharacterSubscriber(_pluginInterface)
|
GlamourerIpc.RevertToAutomationCharacterSubscriber(_pluginInterface)
|
||||||
.Invoke(_objectManager.Objects[_gameObjectIndex] as Character, 1337);
|
.Invoke(_objectManager.Objects[_gameObjectIndex] as Character, 1337);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItem);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Set##SetItem"))
|
||||||
|
_setItemEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_objectManager.Objects[_gameObjectIndex] as Character, (byte)_slot, _customItemId.Id, 1337);
|
||||||
|
if (_setItemEc != GlamourerIpc.GlamourerErrorCode.Success)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(_setItemEc.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItemByActorName);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Set##SetItemByActorName"))
|
||||||
|
_setItemByActorNameEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemByActorNameSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_gameObjectName, (byte)_slot, _customItemId.Id, 1337);
|
||||||
|
if (_setItemByActorNameEc != GlamourerIpc.GlamourerErrorCode.Success)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(_setItemByActorNameEc.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe void DrawItemIdInput()
|
||||||
|
{
|
||||||
|
var tmp = _customItemId.Id;
|
||||||
|
if (ImGui.InputScalar("Custom Item ID", ImGuiDataType.U64, (nint)(&tmp), nint.Zero, nint.Zero))
|
||||||
|
_customItemId = (CustomItemId)tmp;
|
||||||
|
ImGui.SameLine();
|
||||||
|
EquipSlotCombo.Draw("Equip Slot", string.Empty, 200 * ImGuiHelpers.GlobalScale, ref _slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit ed37f83424c11a5a601e74f4660cd52ebd68a7b3
|
Subproject commit 4af8775f0925ff89e6900c8816b03e0ffeb73f6d
|
||||||
Loading…
Add table
Add a link
Reference in a new issue