diff --git a/BetterPartyFinder/BetterPartyFinder.csproj b/BetterPartyFinder/BetterPartyFinder.csproj
index 0fe2f9d..23ad5d5 100755
--- a/BetterPartyFinder/BetterPartyFinder.csproj
+++ b/BetterPartyFinder/BetterPartyFinder.csproj
@@ -8,7 +8,7 @@
-
+
$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll
False
@@ -35,7 +35,7 @@
-
+
diff --git a/BetterPartyFinder/Configuration.cs b/BetterPartyFinder/Configuration.cs
index f97e178..0b8fbde 100755
--- a/BetterPartyFinder/Configuration.cs
+++ b/BetterPartyFinder/Configuration.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Dalamud.Configuration;
+using Dalamud.Game.Internal.Gui.Structs;
namespace BetterPartyFinder {
public class Configuration : IPluginConfiguration {
diff --git a/BetterPartyFinder/Filter.cs b/BetterPartyFinder/Filter.cs
index ab13c56..84e564d 100755
--- a/BetterPartyFinder/Filter.cs
+++ b/BetterPartyFinder/Filter.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Dalamud.Game.Internal.Gui;
+using Dalamud.Game.Internal.Gui.Structs;
namespace BetterPartyFinder {
public class Filter : IDisposable {
@@ -9,7 +11,11 @@ namespace BetterPartyFinder {
internal Filter(Plugin plugin) {
this.Plugin = plugin;
- this.Plugin.Functions.ReceivePartyFinderListing += this.ReceiveListing;
+ this.Plugin.Interface.Framework.Gui.PartyFinder.ReceiveListing += this.ReceiveListing;
+ }
+
+ public void Dispose() {
+ this.Plugin.Interface.Framework.Gui.PartyFinder.ReceiveListing -= this.ReceiveListing;
}
private void ReceiveListing(PartyFinderListing listing, PartyFinderListingEventArgs args) {
@@ -142,16 +148,12 @@ namespace BetterPartyFinder {
// filter based on player
if (filter.Players.Count > 0) {
- if (filter.Players.Any(info => info.Name == listing.Name && info.World == listing.HomeWorld.Value.RowId)) {
+ if (filter.Players.Any(info => info.Name == listing.Name.TextValue && info.World == listing.HomeWorld.Value.RowId)) {
return false;
}
}
return true;
}
-
- public void Dispose() {
- this.Plugin.Functions.ReceivePartyFinderListing -= this.ReceiveListing;
- }
}
}
diff --git a/BetterPartyFinder/GameFunctions.cs b/BetterPartyFinder/GameFunctions.cs
index 36e19e5..c05a971 100755
--- a/BetterPartyFinder/GameFunctions.cs
+++ b/BetterPartyFinder/GameFunctions.cs
@@ -1,7 +1,6 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Hooking;
-using Dalamud.Plugin;
namespace BetterPartyFinder {
public class GameFunctions : IDisposable {
@@ -14,18 +13,6 @@ namespace BetterPartyFinder {
#endregion
- #region PF Listings events
-
- internal delegate void PartyFinderListingEventDelegate(PartyFinderListing listing, PartyFinderListingEventArgs args);
-
- internal event PartyFinderListingEventDelegate? ReceivePartyFinderListing;
-
- private delegate void HandlePfPacketDelegate(IntPtr param1, IntPtr data);
-
- private readonly Hook _handlePacketHook;
-
- #endregion
-
private Plugin Plugin { get; }
private IntPtr PartyFinderAgent { get; set; } = IntPtr.Zero;
@@ -33,19 +20,14 @@ namespace BetterPartyFinder {
this.Plugin = plugin;
var requestPfPtr = this.Plugin.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 0F 10 81 ?? ?? ?? ??");
- var listingPtr = this.Plugin.Interface.TargetModuleScanner.ScanText("40 53 41 57 48 83 EC 28 48 8B D9");
this._requestPartyFinderListings = Marshal.GetDelegateForFunctionPointer(requestPfPtr);
this._requestPfListingsHook = new Hook(requestPfPtr, new RequestPartyFinderListingsDelegate(this.OnRequestPartyFinderListings));
this._requestPfListingsHook.Enable();
-
- this._handlePacketHook = new Hook(listingPtr, new HandlePfPacketDelegate(this.PacketDetour));
- this._handlePacketHook.Enable();
}
public void Dispose() {
this._requestPfListingsHook.Dispose();
- this._handlePacketHook.Dispose();
}
private byte OnRequestPartyFinderListings(IntPtr agent, byte categoryIdx) {
@@ -69,71 +51,5 @@ namespace BetterPartyFinder {
var categoryIdx = Marshal.ReadByte(this.PartyFinderAgent + categoryOffset);
this._requestPartyFinderListings(this.PartyFinderAgent, categoryIdx);
}
-
-
- private void PacketDetour(IntPtr param1, IntPtr data) {
- if (data == IntPtr.Zero) {
- goto Return;
- }
-
- try {
- this.OnPacket(data);
- } catch (Exception ex) {
- PluginLog.Error(ex, "Unhandled exception in PF packet detour");
- }
-
- Return:
- this._handlePacketHook!.Original(param1, data);
- }
-
- private void OnPacket(IntPtr data) {
- var dataPtr = data + 0x10;
-
- // parse the packet into a struct
- var packet = Marshal.PtrToStructure(dataPtr);
-
- var needToRewrite = false;
-
- for (var i = 0; i < packet.listings.Length; i++) {
- if (packet.listings[i].IsNull()) {
- continue;
- }
-
- // invoke event for each non-null listing
- var listing = new PartyFinderListing(packet.listings[i], this.Plugin.Interface.Data);
- var args = new PartyFinderListingEventArgs();
- this.ReceivePartyFinderListing?.Invoke(listing, args);
-
- if (args.Visible) {
- continue;
- }
-
- // zero the listing if it shouldn't be visible
- packet.listings[i] = new PfListing();
- needToRewrite = true;
- }
-
- if (!needToRewrite) {
- return;
- }
-
- // get some memory for writing to
- var newPacket = new byte[PacketInfo.PacketSize];
- var pinnedArray = GCHandle.Alloc(newPacket, GCHandleType.Pinned);
- var pointer = pinnedArray.AddrOfPinnedObject();
-
- // write our struct into the memory (doing this directly crashes the game)
- Marshal.StructureToPtr(packet, pointer, false);
-
- // copy our new memory over the game's
- Marshal.Copy(newPacket, 0, dataPtr, PacketInfo.PacketSize);
-
- // free memory
- pinnedArray.Free();
- }
- }
-
- internal class PartyFinderListingEventArgs {
- public bool Visible { get; set; } = true;
}
}
diff --git a/BetterPartyFinder/PartyFinder.cs b/BetterPartyFinder/PartyFinder.cs
deleted file mode 100755
index d768c6e..0000000
--- a/BetterPartyFinder/PartyFinder.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-using Dalamud.Data;
-using Lumina.Excel.GeneratedSheets;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace BetterPartyFinder {
- public class PartyFinderListing {
- public uint Id { get; }
- public string Name { get; }
- public string Description { get; }
- public Lazy World { get; }
- public Lazy HomeWorld { get; }
- public Lazy CurrentWorld { get; }
- public Category Category { get; }
- public ushort RawDuty { get; }
- public Lazy Duty { get; }
- public DutyType DutyType { get; }
- public bool BeginnersWelcome { get; }
- public ushort SecondsRemaining { get; }
- public ushort MinimumItemLevel { get; }
- public byte Parties { get; }
- public byte SlotsAvailable { get; }
- public IEnumerable Slots => this._slots;
-
- private readonly byte _objective;
- public ObjectiveFlags Objective => (ObjectiveFlags) this._objective;
-
- private readonly byte _conditions;
- public ConditionFlags Conditions => (ConditionFlags) this._conditions;
-
- private readonly byte _dutyFinderSettings;
- public DutyFinderSettingsFlags DutyFinderSettings => (DutyFinderSettingsFlags) this._dutyFinderSettings;
-
- private readonly byte _lootRules;
- public LootRuleFlags LootRules => (LootRuleFlags) this._lootRules;
-
- private readonly byte _searchArea;
- public SearchAreaFlags SearchArea => (SearchAreaFlags) this._searchArea;
-
- private readonly PartyFinderSlot[] _slots;
-
- private readonly byte[] _jobsPresent;
- internal IEnumerable RawJobsPresent => this._jobsPresent;
- internal IReadOnlyCollection> JobsPresent { get; }
-
- public bool this[ObjectiveFlags flag] => this._objective == 0 || (this._objective & (uint) flag) > 0;
-
-
- public bool this[ConditionFlags flag] => this._conditions == 0 || (this._conditions & (uint) flag) > 0;
-
- public bool this[DutyFinderSettingsFlags flag] => this._dutyFinderSettings == 0 || (this._dutyFinderSettings & (uint) flag) > 0;
-
- public bool this[LootRuleFlags flag] => this._lootRules == 0 || (this._lootRules & (uint) flag) > 0;
-
- public bool this[SearchAreaFlags flag] => this._searchArea == 0 || (this._searchArea & (uint) flag) > 0;
-
- internal PartyFinderListing(PfListing listing, DataManager dataManager) {
- this.Id = listing.id;
- this.Name = listing.Name();
- this.Description = listing.Description();
- this.World = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.world));
- this.HomeWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.homeWorld));
- this.CurrentWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.currentWorld));
- this.Category = (Category) listing.category;
- this.RawDuty = listing.duty;
- this.Duty = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.duty));
- this.DutyType = (DutyType) listing.dutyType;
- this.BeginnersWelcome = listing.beginnersWelcome == 1;
- this.SecondsRemaining = listing.secondsRemaining;
- this.MinimumItemLevel = listing.minimumItemLevel;
- this.Parties = listing.numParties;
- this.SlotsAvailable = listing.numSlots;
-
- this._objective = listing.objective;
- this._conditions = listing.conditions;
- this._dutyFinderSettings = listing.dutyFinderSettings;
- this._lootRules = listing.lootRules;
- this._searchArea = listing.searchArea;
-
- this._slots = listing.slots.Select(accepting => new PartyFinderSlot(accepting)).ToArray();
- this._jobsPresent = listing.jobsPresent;
- this.JobsPresent = this._jobsPresent
- .Select(id => new Lazy(() => id == 0
- ? null
- : dataManager.GetExcelSheet().GetRow(id)))
- .ToArray();
- }
- }
-
- public class PartyFinderSlot {
- private readonly uint _accepting;
- private JobFlags[]? _listAccepting;
-
- public IReadOnlyCollection Accepting {
- get {
- if (this._listAccepting != null) {
- return this._listAccepting;
- }
-
- this._listAccepting = Enum.GetValues(typeof(JobFlags))
- .Cast()
- .Where(flag => this[flag])
- .ToArray();
-
- return this._listAccepting;
- }
- }
-
- public bool this[JobFlags flag] => (this._accepting & (uint) flag) > 0;
-
- internal PartyFinderSlot(uint accepting) {
- this._accepting = accepting;
- }
- }
-
- [Flags]
- public enum SearchAreaFlags : uint {
- DataCentre = 1 << 0,
- Private = 1 << 1,
- AllianceRaid = 1 << 2,
- World = 1 << 3,
- OnePlayerPerJob = 1 << 5,
- }
-
- [Flags]
- public enum JobFlags {
- Gladiator = 1 << 1,
- Pugilist = 1 << 2,
- Marauder = 1 << 3,
- Lancer = 1 << 4,
- Archer = 1 << 5,
- Conjurer = 1 << 6,
- Thaumaturge = 1 << 7,
- Paladin = 1 << 8,
- Monk = 1 << 9,
- Warrior = 1 << 10,
- Dragoon = 1 << 11,
- Bard = 1 << 12,
- WhiteMage = 1 << 13,
- BlackMage = 1 << 14,
- Arcanist = 1 << 15,
- Summoner = 1 << 16,
- Scholar = 1 << 17,
- Rogue = 1 << 18,
- Ninja = 1 << 19,
- Machinist = 1 << 20,
- DarkKnight = 1 << 21,
- Astrologian = 1 << 22,
- Samurai = 1 << 23,
- RedMage = 1 << 24,
- BlueMage = 1 << 25,
- Gunbreaker = 1 << 26,
- Dancer = 1 << 27,
- }
-
- internal static class JobFlagsExt {
- internal static ClassJob? ClassJob(this JobFlags job, DataManager data) {
- var jobs = data.GetExcelSheet();
-
- uint? row = job switch {
- JobFlags.Gladiator => 1,
- JobFlags.Pugilist => 2,
- JobFlags.Marauder => 3,
- JobFlags.Lancer => 4,
- JobFlags.Archer => 5,
- JobFlags.Conjurer => 6,
- JobFlags.Thaumaturge => 7,
- JobFlags.Paladin => 19,
- JobFlags.Monk => 20,
- JobFlags.Warrior => 21,
- JobFlags.Dragoon => 22,
- JobFlags.Bard => 23,
- JobFlags.WhiteMage => 24,
- JobFlags.BlackMage => 25,
- JobFlags.Arcanist => 26,
- JobFlags.Summoner => 27,
- JobFlags.Scholar => 28,
- JobFlags.Rogue => 29,
- JobFlags.Ninja => 30,
- JobFlags.Machinist => 31,
- JobFlags.DarkKnight => 32,
- JobFlags.Astrologian => 33,
- JobFlags.Samurai => 34,
- JobFlags.RedMage => 35,
- JobFlags.BlueMage => 36,
- JobFlags.Gunbreaker => 37,
- JobFlags.Dancer => 38,
- _ => null,
- };
-
- return row == null ? null : jobs.GetRow((uint) row);
- }
- }
-
- [Flags]
- public enum ObjectiveFlags : uint {
- None = 0,
- DutyCompletion = 1,
- Practice = 2,
- Loot = 4,
- }
-
- [Flags]
- public enum ConditionFlags : uint {
- None = 1,
- DutyComplete = 2,
- DutyIncomplete = 4,
- }
-
- [Flags]
- public enum DutyFinderSettingsFlags : uint {
- None = 0,
- UndersizedParty = 1 << 0,
- MinimumItemLevel = 1 << 1,
- SilenceEcho = 1 << 2,
- }
-
- [Flags]
- public enum LootRuleFlags : uint {
- None = 0,
- GreedOnly = 1,
- Lootmaster = 2,
- }
-
- public enum Category {
- Duty = 0,
- QuestBattles = 1 << 0,
- Fates = 1 << 1,
- TreasureHunt = 1 << 2,
- TheHunt = 1 << 3,
- GatheringForays = 1 << 4,
- DeepDungeons = 1 << 5,
- AdventuringForays = 1 << 6,
- }
-
- public enum DutyType {
- Other = 0,
- Roulette = 1 << 0,
- Normal = 1 << 1,
- }
-}
diff --git a/BetterPartyFinder/PfPacket.cs b/BetterPartyFinder/PfPacket.cs
deleted file mode 100755
index 5f2df9c..0000000
--- a/BetterPartyFinder/PfPacket.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace BetterPartyFinder {
- public static class PacketInfo {
- public static readonly int PacketSize = Marshal.SizeOf();
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public readonly struct PfPacket {
- private readonly int unk0;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- private readonly byte[] padding1;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- public readonly PfListing[] listings;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public readonly struct PfListing {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- private readonly byte[] header1;
-
- internal readonly uint id;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- private readonly byte[] header2;
-
- private readonly uint unknownInt1;
- private readonly ushort unknownShort1;
- private readonly ushort unknownShort2;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
- private readonly byte[] header3;
-
- internal readonly byte category;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
- private readonly byte[] header4;
-
- internal readonly ushort duty;
- internal readonly byte dutyType;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
- private readonly byte[] header5;
-
- internal readonly ushort world;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- private readonly byte[] header6;
-
- internal readonly byte objective;
- internal readonly byte beginnersWelcome;
- internal readonly byte conditions;
- internal readonly byte dutyFinderSettings;
- internal readonly byte lootRules;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
- private readonly byte[] header7; // all zero in every pf I've examined
-
- private readonly uint lastPatchHotfixTimestamp; // last time the servers were restarted?
- internal readonly ushort secondsRemaining;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
- private readonly byte[] header8; // 00 00 01 00 00 00 in every pf I've examined
-
- internal readonly ushort minimumItemLevel;
- internal readonly ushort homeWorld;
- internal readonly ushort currentWorld;
-
- private readonly byte header9;
-
- internal readonly byte numSlots;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
- private readonly byte[] header10;
-
- internal readonly byte searchArea;
-
- private readonly byte header11;
-
- internal readonly byte numParties;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
- private readonly byte[] header12; // 00 00 00 always. maybe numParties is a u32?
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- internal readonly uint[] slots;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- internal readonly byte[] jobsPresent;
-
- // Note that ByValTStr will not work here because the strings are UTF-8 and there's only a CharSet for UTF-16 in C#.
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- private readonly byte[] name;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 192)]
- private readonly byte[] description;
-
- // 128 (0x80) before name and desc
- // 160 (0xA0) with name (32 bytes/0x20)
- // 352 (0x160) with both (192 bytes/0xC0)
-
- private static string HandleString(IEnumerable bytes) {
- var nonNull = bytes.TakeWhile(b => b != 0).ToArray();
- return Encoding.UTF8.GetString(nonNull);
- }
-
- internal string Name() {
- return HandleString(this.name);
- }
-
- internal string Description() {
- return HandleString(this.description);
- }
-
- internal bool IsNull() {
- // a valid party finder must have at least one slot set
- return this.slots.All(slot => slot == 0);
- }
- }
-}
diff --git a/BetterPartyFinder/PluginUi.cs b/BetterPartyFinder/PluginUi.cs
index dedae7b..33a018a 100755
--- a/BetterPartyFinder/PluginUi.cs
+++ b/BetterPartyFinder/PluginUi.cs
@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Data;
+using Dalamud.Game.Internal.Gui.Structs;
using Dalamud.Interface;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
+using Addon = Lumina.Excel.GeneratedSheets.Addon;
using GameAddon = Dalamud.Game.Internal.Gui.Addon.Addon;
namespace BetterPartyFinder {