Fix party finder packet layout (#1875)

Co-authored-by: goat <16760685+goaaats@users.noreply.github.com>
This commit is contained in:
Infi 2024-07-02 18:39:18 +02:00 committed by GitHub
parent 87de538bf7
commit 39296124b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 56 additions and 30 deletions

View file

@ -13,34 +13,36 @@ namespace Dalamud.Game.Gui.PartyFinder.Internal;
internal readonly struct PartyFinderPacketListing
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private readonly byte[] header1;
private readonly byte[] padding1;
internal readonly uint Id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private readonly byte[] header2;
private readonly byte[] padding2;
internal readonly uint ContentIdLower;
private readonly ushort unknownShort1;
private readonly ushort unknownShort2;
internal readonly uint PaddingId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private readonly byte[] padding3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
private readonly byte[] header3;
internal readonly ulong ContentId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private readonly byte[] padding4;
internal readonly byte Category;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly byte[] header4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
private readonly byte[] padding5;
internal readonly ushort Duty;
internal readonly byte DutyType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
private readonly byte[] header5;
private readonly byte[] padding6;
internal readonly ushort World;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
private readonly byte[] header6;
private readonly byte[] padding7;
internal readonly byte Objective;
internal readonly byte BeginnersWelcome;
@ -49,36 +51,36 @@ internal readonly struct PartyFinderPacketListing
internal readonly byte LootRules;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
private readonly byte[] header7; // all zero in every pf I've examined
private readonly byte[] padding8; // all zero in every pf I've examined
internal 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
private readonly byte[] padding9; // 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;
private readonly byte padding10;
internal readonly byte NumSlots;
internal readonly byte NumSlotsFilled;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly byte[] header10;
private readonly byte padding11;
internal readonly byte SearchArea;
private readonly byte header11;
private readonly byte padding12;
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 = 7)]
private readonly byte[] padding13; // 00 00 00 always. maybe numParties is a u32?
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
internal readonly uint[] Slots;
internal readonly ulong[] Slots;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
internal readonly byte[] JobsPresent;
@ -90,6 +92,9 @@ internal readonly struct PartyFinderPacketListing
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 192)]
internal readonly byte[] Description;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private readonly byte[] padding14;
internal bool IsNull()
{
// a valid party finder must have at least one slot set

View file

@ -18,7 +18,7 @@ namespace Dalamud.Game.Gui.PartyFinder;
internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderGui
{
private readonly PartyFinderAddressResolver address;
private readonly IntPtr memory;
private readonly nint memory;
private readonly Hook<ReceiveListingDelegate> receiveListingHook;
@ -39,7 +39,7 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void ReceiveListingDelegate(IntPtr managerPtr, IntPtr data);
private delegate void ReceiveListingDelegate(nint managerPtr, nint data);
/// <inheritdoc/>
public event IPartyFinderGui.PartyFinderListingEventDelegate? ReceiveListing;
@ -61,7 +61,7 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG
}
}
private void HandleReceiveListingDetour(IntPtr managerPtr, IntPtr data)
private void HandleReceiveListingDetour(nint managerPtr, nint data)
{
try
{
@ -75,7 +75,7 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG
this.receiveListingHook.Original(managerPtr, data);
}
private void HandleListingEvents(IntPtr data)
private void HandleListingEvents(nint data)
{
var dataPtr = data + 0x10;

View file

@ -150,4 +150,14 @@ public enum JobFlags
/// Sage (SGE).
/// </summary>
Sage = 1 << 29,
/// <summary>
/// Viper (VPR).
/// </summary>
Viper = 1 << 30,
/// <summary>
/// Pictomancer (PCT).
/// </summary>
Pictomancer = 1 << 31,
}

View file

@ -49,6 +49,8 @@ public static class JobFlagsExtensions
JobFlags.Dancer => 38,
JobFlags.Reaper => 39,
JobFlags.Sage => 40,
JobFlags.Viper => 41,
JobFlags.Pictomancer => 42,
_ => null,
};

View file

@ -58,7 +58,7 @@ public interface IPartyFinderListing
/// <summary>
/// Gets the lower bits of the player's content ID.
/// </summary>
uint ContentIdLower { get; }
ulong ContentId { get; }
/// <summary>
/// Gets the name of the player hosting this listing.
@ -131,6 +131,11 @@ public interface IPartyFinderListing
/// </summary>
byte SlotsAvailable { get; }
/// <summary>
/// Gets the number of player slots filled.
/// </summary>
byte SlotsFilled { get; }
/// <summary>
/// Gets the time at which the server this listings is on last restarted for a patch/hotfix.
/// Probably.
@ -208,7 +213,7 @@ internal class PartyFinderListing : IPartyFinderListing
this.jobsPresent = listing.JobsPresent;
this.Id = listing.Id;
this.ContentIdLower = listing.ContentIdLower;
this.ContentId = listing.ContentId;
this.Name = SeString.Parse(listing.Name.TakeWhile(b => b != 0).ToArray());
this.Description = SeString.Parse(listing.Description.TakeWhile(b => b != 0).ToArray());
this.World = new Lazy<World>(() => dataManager.GetExcelSheet<World>().GetRow(listing.World));
@ -223,6 +228,7 @@ internal class PartyFinderListing : IPartyFinderListing
this.MinimumItemLevel = listing.MinimumItemLevel;
this.Parties = listing.NumParties;
this.SlotsAvailable = listing.NumSlots;
this.SlotsFilled = listing.NumSlotsFilled;
this.LastPatchHotfixTimestamp = listing.LastPatchHotfixTimestamp;
this.JobsPresent = listing.JobsPresent
.Select(id => new Lazy<ClassJob>(
@ -236,7 +242,7 @@ internal class PartyFinderListing : IPartyFinderListing
public uint Id { get; }
/// <inheritdoc/>
public uint ContentIdLower { get; }
public ulong ContentId { get; }
/// <inheritdoc/>
public SeString Name { get; }
@ -280,6 +286,9 @@ internal class PartyFinderListing : IPartyFinderListing
/// <inheritdoc/>
public byte SlotsAvailable { get; }
/// <inheritdoc/>
public byte SlotsFilled { get; }
/// <inheritdoc/>
public uint LastPatchHotfixTimestamp { get; }
@ -325,5 +334,5 @@ internal class PartyFinderListing : IPartyFinderListing
public bool this[SearchAreaFlags flag] => this.searchArea == 0 || (this.searchArea & (uint)flag) > 0;
#endregion
}

View file

@ -8,14 +8,14 @@ namespace Dalamud.Game.Gui.PartyFinder.Types;
/// </summary>
public class PartyFinderSlot
{
private readonly uint accepting;
private readonly ulong accepting;
private JobFlags[] listAccepting;
/// <summary>
/// Initializes a new instance of the <see cref="PartyFinderSlot"/> class.
/// </summary>
/// <param name="accepting">The flag value of accepted jobs.</param>
internal PartyFinderSlot(uint accepting)
internal PartyFinderSlot(ulong accepting)
{
this.accepting = accepting;
}