Compare commits

..

No commits in common. "master" and "v0.3" have entirely different histories.
master ... v0.3

8 changed files with 348 additions and 465 deletions

@ -1 +1 @@
Subproject commit a63c8e7154e272374ffa03d5c801736d4229e38a Subproject commit 6f0aaa55bce6ec79fd4d72f84f21597b39e5445d

@ -1 +1 @@
Subproject commit 11fd2f06e1374e846e1aada06071da5fc7ef697a Subproject commit f11764e4654148c5d891273053ec02649a5ee9c5

View File

@ -8,7 +8,7 @@ using Dalamud.Game.Command;
using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Gui.Dtr;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
@ -25,7 +25,7 @@ internal sealed class CharacterSwitch : IDisposable
private readonly INotificationManager _notificationManager; private readonly INotificationManager _notificationManager;
private readonly ICondition _condition; private readonly ICondition _condition;
private readonly IPluginLog _pluginLog; private readonly IPluginLog _pluginLog;
private readonly IDtrBarEntry _dtrBarEntry; private readonly DtrBarEntry _dtrBarEntry;
public CharacterSwitch(AutoRetainerApi autoRetainerApi, ICommandManager commandManager, IClientState clientState, public CharacterSwitch(AutoRetainerApi autoRetainerApi, ICommandManager commandManager, IClientState clientState,
IChatGui chatGui, INotificationManager notificationManager, IDtrBar dtrBar, ICondition condition, IChatGui chatGui, INotificationManager notificationManager, IDtrBar dtrBar, ICondition condition,
@ -75,9 +75,7 @@ internal sealed class CharacterSwitch : IDisposable
UpdateDtrBar(); UpdateDtrBar();
} }
private Target? FindCharacter(int direction, bool showError = true) private Target? FindCharacter(int direction)
{
try
{ {
_pluginLog.Verbose($"Switching characters ({direction})"); _pluginLog.Verbose($"Switching characters ({direction})");
@ -85,7 +83,6 @@ internal sealed class CharacterSwitch : IDisposable
int index = characterIds.IndexOf(_clientState.LocalContentId); int index = characterIds.IndexOf(_clientState.LocalContentId);
if (index < 0) if (index < 0)
{ {
if (showError)
_chatGui.PrintError("[KitchenSink] Current character not known."); _chatGui.PrintError("[KitchenSink] Current character not known.");
return null; return null;
} }
@ -97,7 +94,6 @@ internal sealed class CharacterSwitch : IDisposable
target = _autoRetainerApi.GetOfflineCharacterData(characterIds[index]); target = _autoRetainerApi.GetOfflineCharacterData(characterIds[index]);
if (target?.CID == _clientState.LocalContentId) if (target?.CID == _clientState.LocalContentId)
{ {
if (showError)
_chatGui.PrintError("[KitchenSink] No character to switch to found."); _chatGui.PrintError("[KitchenSink] No character to switch to found.");
return null; return null;
} }
@ -108,12 +104,6 @@ internal sealed class CharacterSwitch : IDisposable
return new Target(target.Name, target.World); return new Target(target.Name, target.World);
} }
catch (IpcError)
{
_chatGui.PrintError("Could not switch character, AutoRetainer API isn't available.");
return null;
}
}
private void NextCharacter(string command, string arguments) => SwitchCharacter(FindCharacter(1)); private void NextCharacter(string command, string arguments) => SwitchCharacter(FindCharacter(1));
@ -127,8 +117,6 @@ internal sealed class CharacterSwitch : IDisposable
return; return;
} }
try
{
string[] args = arguments.Split(' ', 2); string[] args = arguments.Split(' ', 2);
if (args.Length < 2 || !int.TryParse(args[1], CultureInfo.InvariantCulture, out int index)) if (args.Length < 2 || !int.TryParse(args[1], CultureInfo.InvariantCulture, out int index))
index = 1; index = 1;
@ -138,8 +126,7 @@ internal sealed class CharacterSwitch : IDisposable
.Where(x => !x.ExcludeRetainer || !x.ExcludeWorkshop) .Where(x => !x.ExcludeRetainer || !x.ExcludeWorkshop)
.Select(x => new { x.Name, x.World }) .Select(x => new { x.Name, x.World })
.ToList(); .ToList();
var target = targets.Where(x => x.World.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)) var target = targets.Where(x => x.World.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)).Skip(index - 1)
.Skip(index - 1)
.FirstOrDefault() ?? .FirstOrDefault() ??
targets.FirstOrDefault(x => x.Name.Contains(arguments, StringComparison.OrdinalIgnoreCase)); targets.FirstOrDefault(x => x.Name.Contains(arguments, StringComparison.OrdinalIgnoreCase));
@ -151,11 +138,6 @@ internal sealed class CharacterSwitch : IDisposable
SwitchCharacter(new Target(target.Name, target.World)); SwitchCharacter(new Target(target.Name, target.World));
} }
catch (IpcError)
{
_chatGui.PrintError("Could not switch character, AutoRetainer API isn't available.");
}
}
private void SwitchCharacter(Target? target) private void SwitchCharacter(Target? target)
{ {
@ -190,11 +172,6 @@ internal sealed class CharacterSwitch : IDisposable
} }
private void UpdateDtrBar() private void UpdateDtrBar()
{
if (_dtrBarEntry.UserHidden)
return;
try
{ {
string? currentWorld = _clientState.LocalPlayer?.CurrentWorld.GameData?.Name?.ToString(); string? currentWorld = _clientState.LocalPlayer?.CurrentWorld.GameData?.Name?.ToString();
string? homeWorld = _clientState.LocalPlayer?.HomeWorld.GameData?.Name?.ToString(); string? homeWorld = _clientState.LocalPlayer?.HomeWorld.GameData?.Name?.ToString();
@ -207,14 +184,14 @@ internal sealed class CharacterSwitch : IDisposable
{ {
_dtrBarEntry.Text = seIconChar.ToIconString(); _dtrBarEntry.Text = seIconChar.ToIconString();
var previous = FindCharacter(-1, showError: false); var previous = FindCharacter(-1);
var next = FindCharacter(1, showError: false); var next = FindCharacter(1);
if (previous != null && next != null) if (previous != null && next != null)
_dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}\nNext: {next.ToString(homeWorld)}"; _dtrBarEntry.Tooltip = $"Prev: {previous.Name}\nNext: {next.Name}";
else if (previous != null) else if (previous != null)
_dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}"; _dtrBarEntry.Tooltip = $"Prev: {previous.Name}";
else if (next != null) else if (next != null)
_dtrBarEntry.Tooltip = $"Next: {next.ToString(homeWorld)}"; _dtrBarEntry.Tooltip = $"Next: {next.Name}";
else else
_dtrBarEntry.Tooltip = null; _dtrBarEntry.Tooltip = null;
} }
@ -223,20 +200,12 @@ internal sealed class CharacterSwitch : IDisposable
_dtrBarEntry.Text = $"{homeWorld} {seIconChar.ToIconString()}"; _dtrBarEntry.Text = $"{homeWorld} {seIconChar.ToIconString()}";
_dtrBarEntry.Tooltip = $"Return to {homeWorld}"; _dtrBarEntry.Tooltip = $"Return to {homeWorld}";
} }
if (!_dtrBarEntry.Shown)
_dtrBarEntry.Shown = true;
}
catch (IpcError)
{
_dtrBarEntry.Shown = false;
}
} }
public void Dispose() public void Dispose()
{ {
_clientState.Login -= UpdateDtrBar; _clientState.Login -= UpdateDtrBar;
_dtrBarEntry.Remove(); _dtrBarEntry.Dispose();
_commandManager.RemoveHandler("/ks"); _commandManager.RemoveHandler("/ks");
_commandManager.RemoveHandler("/k-"); _commandManager.RemoveHandler("/k-");
_commandManager.RemoveHandler("/k+"); _commandManager.RemoveHandler("/k+");
@ -245,10 +214,5 @@ internal sealed class CharacterSwitch : IDisposable
private sealed record Target(string Name, string World) private sealed record Target(string Name, string World)
{ {
public override string ToString() => $"{Name}@{World}"; public override string ToString() => $"{Name}@{World}";
public string ToString(string? currentWorld)
{
return currentWorld != World ? ToString() : Name;
}
} }
} }

View File

@ -1,22 +1,19 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using LLib; using LLib;
namespace KitchenSink.Commands; namespace KitchenSink.Commands
internal sealed class DropboxQueue : IDisposable
{ {
internal sealed class DropboxQueue : IDisposable
{
private static readonly InventoryType[] DefaultInventoryTypes = private static readonly InventoryType[] DefaultInventoryTypes =
[ [
InventoryType.Inventory1, InventoryType.Inventory1,
@ -25,130 +22,74 @@ internal sealed class DropboxQueue : IDisposable
InventoryType.Inventory4, InventoryType.Inventory4,
InventoryType.Crystals, InventoryType.Crystals,
InventoryType.Currency, InventoryType.Currency,
InventoryType.ArmoryMainHand,
InventoryType.ArmoryOffHand,
InventoryType.ArmoryHead,
InventoryType.ArmoryBody,
InventoryType.ArmoryHands,
InventoryType.ArmoryLegs,
InventoryType.ArmoryFeets,
InventoryType.ArmoryEar,
InventoryType.ArmoryNeck,
InventoryType.ArmoryWrist,
InventoryType.ArmoryRings,
]; ];
private readonly ICommandManager _commandManager; private readonly ICommandManager _commandManager;
private readonly IChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly DropboxApi _dropboxApi; private readonly DropboxApi _dropboxApi;
public DropboxQueue(IDalamudPluginInterface pluginInterface, public DropboxQueue(DalamudReflector reflector, ICommandManager commandManager, IChatGui chatGui,
DalamudReflector reflector,
ICommandManager commandManager,
IChatGui chatGui,
IPluginLog pluginLog) IPluginLog pluginLog)
{ {
_commandManager = commandManager; _commandManager = commandManager;
_chatGui = chatGui; _chatGui = chatGui;
_dropboxApi = new DropboxApi(pluginInterface, reflector, pluginLog); _dropboxApi = new DropboxApi(reflector, pluginLog);
_commandManager.AddHandler("/dbq", new CommandInfo(Queue) _commandManager.AddHandler("/dbq", new CommandInfo(Queue)
{ {
HelpMessage = HelpMessage =
$"Queue items to be imported into dropbox{Environment.NewLine}" + $"Queue items to be imported into dropbox{Environment.NewLine}\t/dbq item1:qty1 item2:qty2 [...] - queues items for the next trade (use * as quantity for 'all'){Environment.NewLine}\t/dbq clear - remove all items in the queue{Environment.NewLine}\t/dbq crystals - show the command to fill all shards & crystals to 9999"
$"\t/dbq item1:qty1 item2:qty2 [...] - queues items for the next trade (use * as quantity for 'all'){Environment.NewLine}" +
$"\t/dbq clear - remove all items in the queue{Environment.NewLine}" +
$"\t/dbq request item1:qty1 item2:qty2 [...] - show the command to fill your inventory with the specific item quantities{Environment.NewLine}" +
$"\t/dbq [shards/crystals/shards+crystals] - show the command to fill shards and/or crystals to 9999"
}); });
} }
private void Queue(string command, string arguments) private void Queue(string command, string arguments)
{ {
string[] parts = arguments.Split(" ", 2); if (arguments == "crystals")
switch (parts[0]) {
ShowCrystals();
}
else if (arguments == "clear")
{ {
case "*s":
case "shards":
BuildRequest(string.Join(" ", Enumerable.Range(2, 6).Select(x => $"{x}:9999")));
break;
case "*c":
case "crystals":
BuildRequest(string.Join(" ", Enumerable.Range(8, 6).Select(x => $"{x}:9999")));
break;
case "*x":
case "clusters":
BuildRequest(string.Join(" ", Enumerable.Range(14, 6).Select(x => $"{x}:9999")));
break;
case "*sc":
case "shards+crystals":
BuildRequest(string.Join(" ", Enumerable.Range(2, 12).Select(x => $"{x}:9999")));
break;
case "*cx":
case "crystals+clusters":
BuildRequest(string.Join(" ", Enumerable.Range(8, 12).Select(x => $"{x}:9999")));
break;
case "*scx":
case "shards+crystals+clusters":
BuildRequest(string.Join(" ", Enumerable.Range(2, 18).Select(x => $"{x}:9999")));
break;
case "request":
BuildRequest(parts.Length == 2 ? parts[1] : string.Empty);
break;
case "clear":
_dropboxApi.ClearQueue(); _dropboxApi.ClearQueue();
break;
default:
AddToQueue(arguments);
break;
} }
} else
private unsafe void BuildRequest(string arguments)
{ {
if (string.IsNullOrEmpty(arguments)) var parsedItems = arguments.Split(' ')
.Select(x => x.Split(':'))
.Select(x =>
{ {
_chatGui.PrintError("Usage: /dbq request item1:qty1 item2:qty2 [...]"); if (x.Length != 2)
} return ($"Unable to parse {string.Join(" ", x)}.", null);
InventoryManager* inventoryManger = InventoryManager.Instance(); if (!uint.TryParse(x[0], out uint itemId))
if (inventoryManger == null) return ($"Unable to parse item id {x[0]}.", null);
int needed;
if (x[1] == "*")
needed = int.MaxValue;
else if (!int.TryParse(x[1], out needed))
return ($"Unable to parse quantity {x[1]}.", null);
return (string.Empty, new NeededItem(itemId, needed));
}).ToList();
if (parsedItems.Count == 0)
return; return;
IReadOnlyList<NeededItem>? parsedItems = ParseArguments(arguments); var problematic = parsedItems.Where(x => !string.IsNullOrEmpty(x.Item1)).Select(x => x.Item1).ToList();
if (parsedItems == null) if (problematic.Count == 1)
return;
var missingItems = parsedItems
.Select(item => item with
{ {
Needed = item.Needed - DefaultInventoryTypes.Sum(y => _chatGui.PrintError($"dbq: {problematic.First()}");
inventoryManger->GetItemCountInContainer(item.ItemId, y) +
inventoryManger->GetItemCountInContainer(item.ItemId, y, true))
})
.Where(x => x.Needed > 0)
.ToList();
if (missingItems.Count == 0)
{
_chatGui.Print("No items need to be filled");
return;
} }
else if (problematic.Count >= 2)
_chatGui.Print(new SeStringBuilder().AddUiForeground("[KitchenSink] ", 504) {
.Append($"/dbq {string.Join(" ", missingItems)}").Build()); _chatGui.PrintError("dbq: Multiple errors occured:");
} foreach (string problem in problematic)
_chatGui.PrintError($" - {problem}");
private void AddToQueue(string arguments) }
else
{ {
IReadOnlyList<NeededItem>? parsedItems = ParseArguments(arguments);
if (parsedItems == null)
return;
Dictionary<uint, ItemCount> allItems = GetItemCounts(); Dictionary<uint, ItemCount> allItems = GetItemCounts();
foreach (var neededItem in parsedItems) foreach (var neededItem in parsedItems.Select(x => x.Item2).Cast<NeededItem>())
{ {
if (!allItems.TryGetValue(neededItem.ItemId, out ItemCount? itemCount)) if (!allItems.TryGetValue(neededItem.ItemId, out ItemCount? itemCount))
continue; continue;
@ -171,48 +112,8 @@ internal sealed class DropboxQueue : IDisposable
itemCount.HighQualityQuantity - highQualityQuantity); itemCount.HighQualityQuantity - highQualityQuantity);
} }
} }
_dropboxApi.BeginTrade();
} }
private ReadOnlyCollection<NeededItem>? ParseArguments(string arguments)
{
var parsedItems = arguments.Split(' ')
.Select(x => x.Split(':'))
.Select<string[], (string, NeededItem?)>(x =>
{
if (x.Length != 2)
return ($"Unable to parse {string.Join(" ", x)}.", null);
if (!uint.TryParse(x[0], out uint itemId))
return ($"Unable to parse item id {x[0]}.", null);
int needed;
if (x[1] == "*")
needed = int.MaxValue;
else if (!int.TryParse(x[1], out needed))
return ($"Unable to parse quantity {x[1]}.", null);
return (string.Empty, new NeededItem(itemId, needed));
}).ToList();
if (parsedItems.Count == 0)
return null;
var problematic = parsedItems.Where(x => !string.IsNullOrEmpty(x.Item1)).Select(x => x.Item1).ToList();
if (problematic.Count == 1)
{
_chatGui.PrintError($"dbq: {problematic.First()}");
return null;
} }
else if (problematic.Count >= 2)
{
_chatGui.PrintError("dbq: Multiple errors occured:");
foreach (string problem in problematic)
_chatGui.PrintError($" - {problem}");
return null;
}
else
return parsedItems.Select(x => x.Item2!).ToList().AsReadOnly();
} }
private unsafe Dictionary<uint, ItemCount> GetItemCounts() private unsafe Dictionary<uint, ItemCount> GetItemCounts()
@ -229,15 +130,15 @@ internal sealed class DropboxQueue : IDisposable
for (int i = 0; i < container->Size; ++i) for (int i = 0; i < container->Size; ++i)
{ {
var item = container->GetInventorySlot(i); var item = container->GetInventorySlot(i);
if (item != null && item->ItemId != 0) if (item != null && item->ItemID != 0)
{ {
if (item->Spiritbond > 0) if (item->Spiritbond > 0)
continue; continue;
if (!allItems.TryGetValue(item->ItemId, out ItemCount? itemCount)) if (!allItems.TryGetValue(item->ItemID, out ItemCount? itemCount))
itemCount = new(0, 0); itemCount = new(0, 0);
if (item->Flags.HasFlag(InventoryItem.ItemFlags.HighQuality)) if (item->Flags.HasFlag(InventoryItem.ItemFlags.HQ))
itemCount = itemCount with itemCount = itemCount with
{ {
HighQualityQuantity = itemCount.HighQualityQuantity + (int)item->Quantity HighQualityQuantity = itemCount.HighQualityQuantity + (int)item->Quantity
@ -248,7 +149,7 @@ internal sealed class DropboxQueue : IDisposable
NormalQualityQuantity = itemCount.NormalQualityQuantity + (int)item->Quantity NormalQualityQuantity = itemCount.NormalQualityQuantity + (int)item->Quantity
}; };
allItems[item->ItemId] = itemCount; allItems[item->ItemID] = itemCount;
} }
} }
} }
@ -256,6 +157,26 @@ internal sealed class DropboxQueue : IDisposable
return allItems; return allItems;
} }
private unsafe void ShowCrystals()
{
InventoryManager* inventoryManger = InventoryManager.Instance();
if (inventoryManger == null)
return;
var missingCrystals = Enumerable.Range(2, 12).Select(itemId => (uint)itemId)
.Select(itemId => new NeededItem(itemId,
9999 - inventoryManger->GetItemCountInContainer(itemId, InventoryType.Crystals)))
.Where(x => x.Needed > 0)
.ToList();
if (missingCrystals.Count == 0)
{
_chatGui.Print("No crystals need to be filled");
return;
}
_chatGui.Print($"Command: /dbq {string.Join(" ", missingCrystals)}");
}
public void Dispose() public void Dispose()
{ {
_commandManager.RemoveHandler("/dbq"); _commandManager.RemoveHandler("/dbq");
@ -272,35 +193,53 @@ internal sealed class DropboxQueue : IDisposable
{ {
private readonly DalamudReflector _reflector; private readonly DalamudReflector _reflector;
private readonly IPluginLog _pluginLog; private readonly IPluginLog _pluginLog;
private readonly ICallGateSubscriber<object> _beginTradingQueue;
private readonly ICallGateSubscriber<uint, bool, int> _getItemQuantity;
private readonly ICallGateSubscriber<uint, bool, int, object> _setItemQuantity;
public DropboxApi(IDalamudPluginInterface pluginInterface, DalamudReflector reflector, IPluginLog pluginLog) public DropboxApi(DalamudReflector reflector, IPluginLog pluginLog)
{ {
_reflector = reflector; _reflector = reflector;
_pluginLog = pluginLog; _pluginLog = pluginLog;
_beginTradingQueue = pluginInterface.GetIpcSubscriber<object>("Dropbox.BeginTradingQueue");
_getItemQuantity = pluginInterface.GetIpcSubscriber<uint, bool, int>("Dropbox.GetItemQuantity");
_setItemQuantity = pluginInterface.GetIpcSubscriber<uint, bool, int, object>("Dropbox.SetItemQuantity");
} }
public void BeginTrade() => _beginTradingQueue.InvokeAction(); [SuppressMessage("Performance", "CA2000", Justification = "Should not dispose other plugin")]
public void EnqueueItem(uint itemId, bool hq, int quantity) public void EnqueueItem(uint itemId, bool hq, int quantity)
{ {
_pluginLog.Verbose($"Preparing to queue {itemId}, {hq}, {quantity}"); _pluginLog.Verbose($"Preparing to queue {itemId}, {hq}, {quantity}");
if (quantity < 0) if (quantity < 0)
return; return;
int currentQuantity = _getItemQuantity.InvokeFunc(itemId, hq); if (!TryGetItemQuantities(out IDalamudPlugin? dropboxPlugin, out IDictionary? itemQuantities))
_setItemQuantity.InvokeAction(itemId, hq, quantity + currentQuantity); throw new InvalidOperationException("Could not retrieve item quantities");
uint[] tradeableItemIds = (uint[])dropboxPlugin.GetType()
.GetField("TradeableItems", BindingFlags.Public | BindingFlags.Instance)!
.GetValue(dropboxPlugin)!;
if (!tradeableItemIds.Contains(itemId))
{
_pluginLog.Warning($"Item {itemId} is untradable");
return;
}
var itemDescriptorType = itemQuantities.GetType().GetGenericArguments()[0];
var itemDescriptor = Activator.CreateInstance(itemDescriptorType, args: [itemId, hq])!;
var queuedQuantity = itemQuantities[itemDescriptor];
_pluginLog.Verbose($"Retrieved quantity: {queuedQuantity}");
if (queuedQuantity == null)
return;
var boxType = queuedQuantity.GetType();
var valueField = boxType.GetField("Value", BindingFlags.Public | BindingFlags.Instance)!;
_pluginLog.Information($"Adding {itemDescriptor} to queue");
valueField.SetValue(queuedQuantity, quantity);
} }
public void ClearQueue() public void ClearQueue()
{ {
if (TryGetItemQuantities(out _, out IDictionary? itemQuantities)) if (!TryGetItemQuantities(out IDalamudPlugin? _, out IDictionary? itemQuantities))
throw new InvalidOperationException("Could not retrieve item quantities");
itemQuantities.Clear(); itemQuantities.Clear();
} }
@ -320,4 +259,5 @@ internal sealed class DropboxQueue : IDisposable
return itemQuantities != null; return itemQuantities != null;
} }
} }
}
} }

View File

@ -1,15 +1,65 @@
<Project Sdk="Dalamud.NET.Sdk/9.0.2"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>1.2</Version> <TargetFramework>net8.0-windows</TargetFramework>
<Version>0.3</Version>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<OutputPath>dist</OutputPath> <OutputPath>dist</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<DebugType>portable</DebugType>
</PropertyGroup> </PropertyGroup>
<Import Project="..\LLib\LLib.targets"/> <PropertyGroup>
<Import Project="..\LLib\RenameZip.targets"/> <DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
<DalamudLibPath>$(DALAMUD_HOME)/</DalamudLibPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.12"/>
</ItemGroup>
<ItemGroup>
<Reference Include="Dalamud">
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ImGui.NET">
<HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina">
<HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina.Excel">
<HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\AutoRetainerAPI\AutoRetainerAPI\AutoRetainerAPI.csproj"/> <ProjectReference Include="..\AutoRetainerAPI\AutoRetainerAPI\AutoRetainerAPI.csproj"/>
<ProjectReference Include="..\ECommons\ECommons\ECommons.csproj"/> <ProjectReference Include="..\ECommons\ECommons\ECommons.csproj"/>
<ProjectReference Include="..\LLib\LLib.csproj" /> <ProjectReference Include="..\LLib\LLib.csproj" />
</ItemGroup> </ItemGroup>
<Target Name="RenameLatestZip" AfterTargets="PackagePlugin">
<Exec Command="rename $(OutDir)$(AssemblyName)\latest.zip $(AssemblyName)-$(Version).zip"/>
</Target>
</Project> </Project>

View File

@ -16,9 +16,9 @@ internal sealed class KitchenSinkPlugin : IDalamudPlugin
private readonly CharacterSwitch _characterSwitch; private readonly CharacterSwitch _characterSwitch;
private readonly DropboxQueue _dropboxQueue; private readonly DropboxQueue _dropboxQueue;
public KitchenSinkPlugin(IDalamudPluginInterface pluginInterface, ICommandManager commandManager, public KitchenSinkPlugin(DalamudPluginInterface pluginInterface, ICommandManager commandManager,
IClientState clientState, IChatGui chatGui, INotificationManager notificationManager, IDtrBar dtrBar, IClientState clientState, IChatGui chatGui, INotificationManager notificationManager, IDtrBar dtrBar,
ICondition condition, IFramework framework, IPluginLog pluginLog) ICondition condition, IPluginLog pluginLog, IFramework framework)
{ {
DalamudReflector reflector = new DalamudReflector(pluginInterface, framework, pluginLog); DalamudReflector reflector = new DalamudReflector(pluginInterface, framework, pluginLog);
@ -26,7 +26,7 @@ internal sealed class KitchenSinkPlugin : IDalamudPlugin
_autoRetainerApi = new AutoRetainerApi(); _autoRetainerApi = new AutoRetainerApi();
_characterSwitch = new CharacterSwitch(_autoRetainerApi, commandManager, clientState, chatGui, _characterSwitch = new CharacterSwitch(_autoRetainerApi, commandManager, clientState, chatGui,
notificationManager, dtrBar, condition, pluginLog); notificationManager, dtrBar, condition, pluginLog);
_dropboxQueue = new DropboxQueue(pluginInterface, reflector, commandManager, chatGui, pluginLog); _dropboxQueue = new DropboxQueue(reflector, commandManager, chatGui, pluginLog);
} }
public void Dispose() public void Dispose()

View File

@ -4,92 +4,21 @@
"net8.0-windows7.0": { "net8.0-windows7.0": {
"DalamudPackager": { "DalamudPackager": {
"type": "Direct", "type": "Direct",
"requested": "[2.1.13, )", "requested": "[2.1.12, )",
"resolved": "2.1.13", "resolved": "2.1.12",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ==" "contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
},
"DotNet.ReproducibleBuilds": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "+H2t/t34h6mhEoUvHi8yGXyuZ2GjSovcGYehJrS2MDm2XgmPfZL2Sdxg+uL2lKgZ4M6tTwKHIlxOob2bgh0NRQ==",
"dependencies": {
"Microsoft.SourceLink.AzureRepos.Git": "1.1.1",
"Microsoft.SourceLink.Bitbucket.Git": "1.1.1",
"Microsoft.SourceLink.GitHub": "1.1.1",
"Microsoft.SourceLink.GitLab": "1.1.1"
}
},
"Microsoft.SourceLink.Gitea": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "KOBodmDnlWGIqZt2hT47Q69TIoGhIApDVLCyyj9TT5ct8ju16AbHYcB4XeknoHX562wO1pMS/1DfBIZK+V+sxg==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.SourceLink.AzureRepos.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "qB5urvw9LO2bG3eVAkuL+2ughxz2rR7aYgm2iyrB8Rlk9cp2ndvGRCvehk3rNIhRuNtQaeKwctOl1KvWiklv5w==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Bitbucket.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "cDzxXwlyWpLWaH0em4Idj0H3AmVo3L/6xRXKssYemx+7W52iNskj/SQ4FOmfCb8YQt39otTDNMveCZzYtMoucQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.GitLab": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "tvsg47DDLqqedlPeYVE2lmiTpND8F0hkrealQ5hYltSmvruy/Gr5nHAKSsjyw5L3NeM/HLMI5ORv7on/M4qyZw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
}, },
"autoretainerapi": { "autoretainerapi": {
"type": "Project", "type": "Project",
"dependencies": { "dependencies": {
"ECommons": "[2.2.0.2, )" "ECommons": "[2.2.0.1, )"
} }
}, },
"ecommons": { "ecommons": {
"type": "Project" "type": "Project"
}, },
"llib": { "llib": {
"type": "Project", "type": "Project"
"dependencies": {
"DalamudPackager": "[2.1.13, )"
}
} }
} }
} }

2
LLib

@ -1 +1 @@
Subproject commit 93fac6efb01a1272192d929fd863328271512ea4 Subproject commit 3792244261a9f5426a7916f5a6dd1966238ba84a