Skip to content

Commit

Permalink
Misc ClientStructs changes
Browse files Browse the repository at this point in the history
- Update HotbarSlotTypes accordingly
- Crate translation layer between XIVDeck API names and CS names
- Use spans properly
  • Loading branch information
KazWolfe committed Oct 3, 2023
1 parent cf4796e commit a388fe0
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 20 deletions.
7 changes: 3 additions & 4 deletions FFXIVPlugin/ActionExecutor/Strategies/MinionStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@
using XIVDeck.FFXIVPlugin.Base;
using XIVDeck.FFXIVPlugin.Exceptions;
using XIVDeck.FFXIVPlugin.Game;
using XIVDeck.FFXIVPlugin.Game.Chat;
using XIVDeck.FFXIVPlugin.Game.Managers;
using XIVDeck.FFXIVPlugin.Resources.Localization;
using XIVDeck.FFXIVPlugin.Utils;

namespace XIVDeck.FFXIVPlugin.ActionExecutor.Strategies;

[ActionStrategy(HotbarSlotType.Minion)]
[ActionStrategy(HotbarSlotType.Companion)]
public class MinionStrategy : IActionStrategy {
private static ExecutableAction GetExecutableAction(Companion minion) {
return new ExecutableAction {
ActionId = (int) minion.RowId,
ActionName = minion.Singular.ToString(),
IconId = minion.Icon,
HotbarSlotType = HotbarSlotType.Minion,
HotbarSlotType = HotbarSlotType.Companion,
SortOrder = minion.Order
};
}
Expand Down Expand Up @@ -55,7 +54,7 @@ public void Execute(uint actionId, ActionPayload? _) {

Injections.PluginLog.Debug($"Executing hotbar slot: Minion#{actionId} ({minion.Singular.ToTitleCase()})");
Injections.Framework.RunOnFrameworkThread(delegate {
HotbarManager.ExecuteHotbarAction(HotbarSlotType.Minion, actionId);
HotbarManager.ExecuteHotbarAction(HotbarSlotType.Companion, actionId);
});
}

Expand Down
11 changes: 5 additions & 6 deletions FFXIVPlugin/ActionExecutor/Strategies/OrnamentStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
using XIVDeck.FFXIVPlugin.Base;
using XIVDeck.FFXIVPlugin.Exceptions;
using XIVDeck.FFXIVPlugin.Game;
using XIVDeck.FFXIVPlugin.Game.Chat;
using XIVDeck.FFXIVPlugin.Game.Managers;
using XIVDeck.FFXIVPlugin.Resources.Localization;
using XIVDeck.FFXIVPlugin.Utils;

namespace XIVDeck.FFXIVPlugin.ActionExecutor.Strategies;

[ActionStrategy(HotbarSlotType.FashionAccessory)]
[ActionStrategy(HotbarSlotType.Ornament)]
public class OrnamentStrategy : IActionStrategy {
private static ExecutableAction GetExecutableAction(Ornament ornament) {
return new ExecutableAction {
ActionId = (int) ornament.RowId,
ActionName = ornament.Singular.ToString(),
IconId = ornament.Icon,
HotbarSlotType = HotbarSlotType.FashionAccessory,
HotbarSlotType = HotbarSlotType.Ornament,
SortOrder = ornament.Order
};
}
Expand All @@ -45,16 +44,16 @@ public void Execute(uint actionId, ActionPayload? _) {
var ornament = GetOrnamentById(actionId);

if (ornament == null) {
throw new ActionNotFoundException(HotbarSlotType.FashionAccessory, actionId);
throw new ActionNotFoundException(HotbarSlotType.Ornament, actionId);
}

if (!ornament.IsUnlocked()) {
throw new ActionLockedException(string.Format(UIStrings.OrnamentStrategy_OrnamentLockedError, ornament.Singular));
}

Injections.PluginLog.Debug($"Executing hotbar slot: FashionAccessory#{ornament.RowId} ({ornament.Singular.ToTitleCase()})");
Injections.PluginLog.Debug($"Executing hotbar slot: Ornament#{ornament.RowId} ({ornament.Singular.ToTitleCase()})");
Injections.Framework.RunOnFrameworkThread(delegate {
HotbarManager.ExecuteHotbarAction(HotbarSlotType.FashionAccessory, ornament.RowId);
HotbarManager.ExecuteHotbarAction(HotbarSlotType.Ornament, ornament.RowId);
});
}

Expand Down
2 changes: 1 addition & 1 deletion FFXIVPlugin/Game/Managers/HotbarManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public static unsafe void CalcBForSlot(HotBarSlot* slot, out HotbarSlotType acti
// Take in default values, just in case GetSlotAppearance fails for some reason
var acType = slot->IconTypeB;
var acId = slot->IconB;
ushort actionCost = slot->UNK_0xCA;
ushort actionCost = slot->CostType;

RaptureHotbarModule.GetSlotAppearance(&acType, &acId, &actionCost, hotbarModule, slot);

Expand Down
4 changes: 2 additions & 2 deletions FFXIVPlugin/Game/Watchers/HotbarWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ private unsafe void OnGameUpdate(IFramework framework) {
List<MicroHotbarSlot> updatedSlots = new();

for (var hotbarId = 0; hotbarId < 17; hotbarId++) {
var hotbar = hotbarModule->HotBar[hotbarId];
ref var hotbar = ref hotbarModule->HotBarsSpan[hotbarId];

for (var slotId = 0; slotId < 16; slotId++) {
var gameSlot = hotbar->Slot[slotId];
var gameSlot = hotbar.GetHotbarSlot((uint) slotId);
var cachedSlot = this._hotbarCache[hotbarId, slotId];

// We calculate IconB first so that we know what "appearance" the slot has. This allows us to optimize
Expand Down
31 changes: 25 additions & 6 deletions FFXIVPlugin/Server/Controllers/ActionController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using EmbedIO;
Expand All @@ -18,23 +19,37 @@ namespace XIVDeck.FFXIVPlugin.Server.Controllers;

[ApiController("/action")]
public class ActionController : WebApiController {
/// <summary>
/// A lookup table of aliases for certain action types. Used for cases where an action type may have changed
/// names as a result of CS updates or similar.
/// </summary>
private static readonly Dictionary<string, HotbarSlotType> ActionTypeAliases = new() {
{ "Minion", HotbarSlotType.Companion },
{ "FashionAccessory", HotbarSlotType.Ornament }
};

private static readonly Dictionary<HotbarSlotType, string> SlotTypeNames = ActionTypeAliases.Reverse()
.ToDictionary(v => v.Value, k => k.Key);

[Route(HttpVerbs.Get, "/")]
public Dictionary<HotbarSlotType, List<ExecutableAction>> GetActions() {
Dictionary<HotbarSlotType, List<ExecutableAction>> actions = new();
public Dictionary<string, List<ExecutableAction>> GetActions() {
Dictionary<string, List<ExecutableAction>> actions = new();

foreach (var (type, strategy) in XIVDeckPlugin.Instance.ActionDispatcher.GetStrategies()) {
var allowedItems = strategy.GetAllowedItems();
if (allowedItems == null || allowedItems.Count == 0) continue;

actions[type] = allowedItems;
var typeName = SlotTypeNames.GetValueOrDefault(type, type.ToString());

actions[typeName] = allowedItems;
}

return actions;
}

[Route(HttpVerbs.Get, "/{type}")]
public List<ExecutableAction> GetActionsByType(string type) {
if (!Enum.TryParse<HotbarSlotType>(type, out var slotType)) {
if (!TryGetSlotTypeByName(type, out var slotType)) {
throw HttpException.NotFound(string.Format(UIStrings.ActionController_UnknownActionTypeError, type));
}

Expand All @@ -44,7 +59,7 @@ public List<ExecutableAction> GetActionsByType(string type) {

[Route(HttpVerbs.Get, "/{type}/{id}")]
public ExecutableAction GetAction(string type, int id) {
if (!Enum.TryParse<HotbarSlotType>(type, out var slotType)) {
if (!TryGetSlotTypeByName(type, out var slotType)) {
throw HttpException.NotFound(string.Format(UIStrings.ActionController_UnknownActionTypeError, type));
}

Expand All @@ -59,7 +74,7 @@ public ExecutableAction GetAction(string type, int id) {

[Route(HttpVerbs.Post, "/{type}/{id}/execute")]
public async Task ExecuteAction(string type, int id) {
if (!Enum.TryParse<HotbarSlotType>(type, out var slotType))
if (!TryGetSlotTypeByName(type, out var slotType))
throw HttpException.NotFound(string.Format(UIStrings.ActionController_UnknownActionTypeError, type));

if (!Injections.ClientState.IsLoggedIn)
Expand All @@ -79,4 +94,8 @@ public async Task ExecuteAction(string type, int id) {
GameUtils.ResetAFKTimer();
strategy.Execute((uint) id, payload);
}

private static bool TryGetSlotTypeByName(string typeName, out HotbarSlotType slotType) {
return ActionTypeAliases.TryGetValue(typeName, out slotType) || Enum.TryParse(typeName, out slotType);
}
}
2 changes: 1 addition & 1 deletion FFXIVPlugin/Server/Controllers/HotbarController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public unsafe SerializableHotbarSlot GetHotbarSlot(int hotbarId, int slotId) {
throw HttpException.BadRequest(ex.Message);
}

var hotbarItem = hotbarModule->HotBar[hotbarId]->Slot[slotId];
var hotbarItem = hotbarModule->HotBarsSpan[hotbarId].GetHotbarSlot((uint) slotId);
var iconId = HotbarManager.CalcIconForSlot(hotbarItem);

return new SerializableHotbarSlot {
Expand Down

0 comments on commit a388fe0

Please sign in to comment.