mirror of
https://github.com/redstrate/Auracite.git
synced 2025-06-30 09:37:45 +00:00
Add support for extracting inventory containers in Dalamud
This commit is contained in:
parent
aa7c38634d
commit
a6edfd903c
6 changed files with 227 additions and 44 deletions
|
@ -1,34 +0,0 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
|
||||||
|
|
||||||
namespace Auracite;
|
|
||||||
|
|
||||||
public class CurrencyStep : IStep
|
|
||||||
{
|
|
||||||
public event IStep.CompletedDelegate? Completed;
|
|
||||||
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
if (Plugin.ClientState.LocalPlayer != null)
|
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
Plugin.package.gil = InventoryManager.Instance()->GetGil();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Completed?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string StepName()
|
|
||||||
{
|
|
||||||
return "Currency";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string StepDescription()
|
|
||||||
{
|
|
||||||
return "No user action required.";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
80
dalamud/Auracite/InventoryStep.cs
Normal file
80
dalamud/Auracite/InventoryStep.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
|
|
||||||
|
namespace Auracite;
|
||||||
|
|
||||||
|
public class InventoryStep : IStep
|
||||||
|
{
|
||||||
|
public event IStep.CompletedDelegate? Completed;
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
if (Plugin.ClientState.LocalPlayer != null)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
var manager = InventoryManager.Instance();
|
||||||
|
Plugin.package.inventory1 = ProcessContainer(manager->GetInventoryContainer(InventoryType.Inventory1));
|
||||||
|
Plugin.package.inventory2 = ProcessContainer(manager->GetInventoryContainer(InventoryType.Inventory2));
|
||||||
|
Plugin.package.inventory3 = ProcessContainer(manager->GetInventoryContainer(InventoryType.Inventory3));
|
||||||
|
Plugin.package.inventory4 = ProcessContainer(manager->GetInventoryContainer(InventoryType.Inventory4));
|
||||||
|
|
||||||
|
Plugin.package.equipped_items = ProcessContainer(manager->GetInventoryContainer(InventoryType.EquippedItems));
|
||||||
|
|
||||||
|
Plugin.package.currency = ProcessContainer(manager->GetInventoryContainer(InventoryType.Currency));
|
||||||
|
|
||||||
|
Plugin.package.armory_off_hand = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryOffHand));
|
||||||
|
Plugin.package.armory_head = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryHead));
|
||||||
|
Plugin.package.armory_body = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryBody));
|
||||||
|
Plugin.package.armory_hands = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryHands));
|
||||||
|
Plugin.package.armory_waist = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryWaist));
|
||||||
|
Plugin.package.armory_legs = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryLegs));
|
||||||
|
Plugin.package.armory_ear = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryEar));
|
||||||
|
Plugin.package.armory_neck = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryNeck));
|
||||||
|
Plugin.package.armory_wrist = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryWrist));
|
||||||
|
Plugin.package.armory_rings = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryRings));
|
||||||
|
Plugin.package.armory_soul_crystal = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmorySoulCrystal));
|
||||||
|
Plugin.package.armory_main_hand = ProcessContainer(manager->GetInventoryContainer(InventoryType.ArmoryMainHand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Completed?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe Auracite.Plugin.InventoryContainer ProcessContainer(FFXIVClientStructs.FFXIV.Client.Game.InventoryContainer *container) {
|
||||||
|
var serializedContainer = new Auracite.Plugin.InventoryContainer();
|
||||||
|
serializedContainer.items = new System.Collections.Generic.List<Plugin.InventoryItem>(); // TODO: lol
|
||||||
|
|
||||||
|
for (int i = 0; i < container->Size; i++) {
|
||||||
|
var item = container->GetInventorySlot(i);
|
||||||
|
if (item != null) {
|
||||||
|
if (item->GetQuantity() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var serializedItem = new Auracite.Plugin.InventoryItem();
|
||||||
|
serializedItem.condition = item->GetCondition();
|
||||||
|
serializedItem.id = item->GetBaseItemId();
|
||||||
|
serializedItem.quantity = item->GetQuantity();
|
||||||
|
serializedItem.slot = item->GetSlot();
|
||||||
|
serializedItem.glamour_id = item->GetGlamourId();
|
||||||
|
|
||||||
|
serializedContainer.items.Add(serializedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return serializedContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StepName()
|
||||||
|
{
|
||||||
|
return "Currency";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StepDescription()
|
||||||
|
{
|
||||||
|
return "No user action required.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,17 +15,32 @@ public sealed class Plugin : IDalamudPlugin
|
||||||
private readonly WindowSystem WindowSystem = new("Auracite");
|
private readonly WindowSystem WindowSystem = new("Auracite");
|
||||||
|
|
||||||
private readonly List<Type> _steps =
|
private readonly List<Type> _steps =
|
||||||
[typeof(AppearanceStep), typeof(CurrencyStep), typeof(MiscStep), typeof(PlaytimeStep), typeof(AdventurerPlateStep), typeof(EndStep)];
|
[typeof(AppearanceStep), typeof(InventoryStep), typeof(MiscStep), typeof(PlaytimeStep), typeof(AdventurerPlateStep), typeof(EndStep)];
|
||||||
|
|
||||||
private int _stepIndex;
|
private int _stepIndex;
|
||||||
|
|
||||||
private readonly StepWindow StepWindow;
|
private readonly StepWindow StepWindow;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
public class InventoryItem
|
||||||
|
{
|
||||||
|
public int slot;
|
||||||
|
public uint quantity;
|
||||||
|
public int condition;
|
||||||
|
public uint id;
|
||||||
|
public uint glamour_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
public class InventoryContainer
|
||||||
|
{
|
||||||
|
public List<InventoryItem> items;
|
||||||
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
public class Package
|
public class Package
|
||||||
{
|
{
|
||||||
public string? playtime;
|
public string? playtime;
|
||||||
public uint gil;
|
|
||||||
public bool is_battle_mentor;
|
public bool is_battle_mentor;
|
||||||
public bool is_trade_mentor;
|
public bool is_trade_mentor;
|
||||||
public bool is_novice;
|
public bool is_novice;
|
||||||
|
@ -74,6 +89,29 @@ public sealed class Plugin : IDalamudPlugin
|
||||||
public string? plate_frame;
|
public string? plate_frame;
|
||||||
public string? accent;
|
public string? accent;
|
||||||
|
|
||||||
|
// inventory
|
||||||
|
public InventoryContainer inventory1;
|
||||||
|
public InventoryContainer inventory2;
|
||||||
|
public InventoryContainer inventory3;
|
||||||
|
public InventoryContainer inventory4;
|
||||||
|
|
||||||
|
public InventoryContainer equipped_items;
|
||||||
|
|
||||||
|
public InventoryContainer currency;
|
||||||
|
|
||||||
|
public InventoryContainer armory_off_hand;
|
||||||
|
public InventoryContainer armory_head;
|
||||||
|
public InventoryContainer armory_body;
|
||||||
|
public InventoryContainer armory_hands;
|
||||||
|
public InventoryContainer armory_waist;
|
||||||
|
public InventoryContainer armory_legs;
|
||||||
|
public InventoryContainer armory_ear;
|
||||||
|
public InventoryContainer armory_neck;
|
||||||
|
public InventoryContainer armory_wrist;
|
||||||
|
public InventoryContainer armory_rings;
|
||||||
|
public InventoryContainer armory_soul_crystal;
|
||||||
|
public InventoryContainer armory_main_hand;
|
||||||
|
|
||||||
public int voice;
|
public int voice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
src/data.rs
46
src/data.rs
|
@ -1,8 +1,11 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::value::{
|
use crate::{
|
||||||
|
package::InventoryContainer,
|
||||||
|
value::{
|
||||||
CityStateValue, ClassJobValue, GenderValue, GrandCompanyValue, GuardianValue, ItemValue,
|
CityStateValue, ClassJobValue, GenderValue, GrandCompanyValue, GuardianValue, ItemValue,
|
||||||
NamedayValue, RaceValue, TribeValue, WorldValue,
|
NamedayValue, RaceValue, TribeValue, WorldValue,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Serialize)]
|
#[derive(Default, Serialize)]
|
||||||
|
@ -120,4 +123,45 @@ pub struct CharacterData {
|
||||||
pub face_url: String,
|
pub face_url: String,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub portrait_url: String,
|
pub portrait_url: String,
|
||||||
|
|
||||||
|
// inventory
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub inventory1: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub inventory2: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub inventory3: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub inventory4: Option<InventoryContainer>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub equipped_items: Option<InventoryContainer>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub currency: Option<InventoryContainer>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_off_hand: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_head: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_body: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_hands: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_waist: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_legs: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_ear: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_neck: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_wrist: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_rings: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_soul_crystal: Option<InventoryContainer>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub armory_main_hand: Option<InventoryContainer>,
|
||||||
}
|
}
|
||||||
|
|
25
src/lib.rs
25
src/lib.rs
|
@ -226,10 +226,29 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
facepaint_color: package.facepaint_color,
|
facepaint_color: package.facepaint_color,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
char_data.inventory1 = Some(package.inventory1);
|
||||||
|
char_data.inventory2 = Some(package.inventory2);
|
||||||
|
char_data.inventory3 = Some(package.inventory3);
|
||||||
|
char_data.inventory4 = Some(package.inventory4);
|
||||||
|
|
||||||
|
char_data.equipped_items = Some(package.equipped_items);
|
||||||
|
|
||||||
|
char_data.currency = Some(package.currency);
|
||||||
|
|
||||||
|
char_data.armory_off_hand = Some(package.armory_off_hand);
|
||||||
|
char_data.armory_head = Some(package.armory_head);
|
||||||
|
char_data.armory_body = Some(package.armory_body);
|
||||||
|
char_data.armory_hands = Some(package.armory_hands);
|
||||||
|
char_data.armory_waist = Some(package.armory_waist);
|
||||||
|
char_data.armory_legs = Some(package.armory_legs);
|
||||||
|
char_data.armory_ear = Some(package.armory_ear);
|
||||||
|
char_data.armory_neck = Some(package.armory_neck);
|
||||||
|
char_data.armory_wrist = Some(package.armory_wrist);
|
||||||
|
char_data.armory_rings = Some(package.armory_rings);
|
||||||
|
char_data.armory_soul_crystal = Some(package.armory_soul_crystal);
|
||||||
|
char_data.armory_main_hand = Some(package.armory_main_hand);
|
||||||
|
|
||||||
char_data.playtime = Some(package.playtime.parse().unwrap());
|
char_data.playtime = Some(package.playtime.parse().unwrap());
|
||||||
char_data.currencies = Some(Currencies {
|
|
||||||
gil: package.gil, // TODO: also fetch from the lodestone
|
|
||||||
});
|
|
||||||
char_data.is_battle_mentor = Some(package.is_battle_mentor);
|
char_data.is_battle_mentor = Some(package.is_battle_mentor);
|
||||||
char_data.is_trade_mentor = Some(package.is_trade_mentor);
|
char_data.is_trade_mentor = Some(package.is_trade_mentor);
|
||||||
char_data.is_novice = Some(package.is_novice);
|
char_data.is_novice = Some(package.is_novice);
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct InventoryItem {
|
||||||
|
pub slot: i32,
|
||||||
|
pub quantity: u32,
|
||||||
|
pub condition: i32,
|
||||||
|
pub id: u32,
|
||||||
|
pub glamour_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct InventoryContainer {
|
||||||
|
pub items: Vec<InventoryItem>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Clone)]
|
#[derive(Default, Deserialize, Clone)]
|
||||||
pub struct Package {
|
pub struct Package {
|
||||||
pub playtime: String,
|
pub playtime: String,
|
||||||
pub gil: u32,
|
|
||||||
pub is_battle_mentor: bool,
|
pub is_battle_mentor: bool,
|
||||||
pub is_trade_mentor: bool,
|
pub is_trade_mentor: bool,
|
||||||
pub is_novice: bool,
|
pub is_novice: bool,
|
||||||
|
@ -52,4 +65,27 @@ pub struct Package {
|
||||||
pub bust_size: i32,
|
pub bust_size: i32,
|
||||||
pub facepaint: i32,
|
pub facepaint: i32,
|
||||||
pub facepaint_color: i32,
|
pub facepaint_color: i32,
|
||||||
|
|
||||||
|
// inventory
|
||||||
|
pub inventory1: InventoryContainer,
|
||||||
|
pub inventory2: InventoryContainer,
|
||||||
|
pub inventory3: InventoryContainer,
|
||||||
|
pub inventory4: InventoryContainer,
|
||||||
|
|
||||||
|
pub equipped_items: InventoryContainer,
|
||||||
|
|
||||||
|
pub currency: InventoryContainer,
|
||||||
|
|
||||||
|
pub armory_off_hand: InventoryContainer,
|
||||||
|
pub armory_head: InventoryContainer,
|
||||||
|
pub armory_body: InventoryContainer,
|
||||||
|
pub armory_hands: InventoryContainer,
|
||||||
|
pub armory_waist: InventoryContainer,
|
||||||
|
pub armory_legs: InventoryContainer,
|
||||||
|
pub armory_ear: InventoryContainer,
|
||||||
|
pub armory_neck: InventoryContainer,
|
||||||
|
pub armory_wrist: InventoryContainer,
|
||||||
|
pub armory_rings: InventoryContainer,
|
||||||
|
pub armory_soul_crystal: InventoryContainer,
|
||||||
|
pub armory_main_hand: InventoryContainer,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue