Update MarketBoard related packet structs (#1868)

* Update MarketBoardHistory

* Update MarketBoardCurrentOfferings

* small fix

* Update other structs & update widget

* Mark obsolete fields as internal
This commit is contained in:
Infi 2024-06-30 00:18:47 +02:00 committed by GitHub
parent 41e3803787
commit 3e950b09fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 187 additions and 147 deletions

View file

@ -12,20 +12,10 @@ public interface IMarketBoardCurrentOfferings
/// </summary>
IReadOnlyList<IMarketBoardItemListing> ItemListings { get; }
/// <summary>
/// Gets the listing end index.
/// </summary>
int ListingIndexEnd { get; }
/// <summary>
/// Gets the listing start index.
/// </summary>
int ListingIndexStart { get; }
/// <summary>
/// Gets the request ID.
/// </summary>
int RequestId { get; }
public int RequestId { get; }
}
/// <summary>
@ -36,82 +26,77 @@ public interface IMarketBoardItemListing
/// <summary>
/// Gets the artisan ID.
/// </summary>
ulong ArtisanId { get; }
public ulong ArtisanId { get; }
/// <summary>
/// Gets the item ID.
/// </summary>
uint ItemId { get; }
public uint ItemId { get; }
/// <summary>
/// Gets a value indicating whether the item is HQ.
/// </summary>
bool IsHq { get; }
public bool IsHq { get; }
/// <summary>
/// Gets the item quantity.
/// </summary>
uint ItemQuantity { get; }
/// <summary>
/// Gets the time this offering was last reviewed.
/// </summary>
DateTime LastReviewTime { get; }
public uint ItemQuantity { get; }
/// <summary>
/// Gets the listing ID.
/// </summary>
ulong ListingId { get; }
public ulong ListingId { get; }
/// <summary>
/// Gets the list of materia attached to this item.
/// </summary>
IReadOnlyList<IItemMateria> Materia { get; }
public IReadOnlyList<IItemMateria> Materia { get; }
/// <summary>
/// Gets the amount of attached materia.
/// </summary>
int MateriaCount { get; }
public int MateriaCount { get; }
/// <summary>
/// Gets a value indicating whether this item is on a mannequin.
/// </summary>
bool OnMannequin { get; }
/// <summary>
/// Gets the player name.
/// </summary>
string PlayerName { get; }
public bool OnMannequin { get; }
/// <summary>
/// Gets the price per unit.
/// </summary>
uint PricePerUnit { get; }
public uint PricePerUnit { get; }
/// <summary>
/// Gets the city ID of the retainer selling the item.
/// </summary>
int RetainerCityId { get; }
public int RetainerCityId { get; }
/// <summary>
/// Gets the ID of the retainer selling the item.
/// </summary>
ulong RetainerId { get; }
public ulong RetainerId { get; }
/// <summary>
/// Gets the name of the retainer.
/// </summary>
string RetainerName { get; }
public string RetainerName { get; }
/// <summary>
/// Gets the stain or applied dye of the item.
/// Gets the first stain or applied dye of the item.
/// </summary>
int StainId { get; }
public int Stain1Id { get; }
/// <summary>
/// Gets the second stain or applied dye of the item.
/// </summary>
public int Stain2Id { get; }
/// <summary>
/// Gets the total tax.
/// </summary>
uint TotalTax { get; }
public uint TotalTax { get; }
}
/// <summary>

View file

@ -10,12 +10,12 @@ public interface IMarketBoardHistory
/// <summary>
/// Gets the item ID.
/// </summary>
uint ItemId { get; }
public uint ItemId { get; }
/// <summary>
/// Gets the list of individual item history listings.
/// </summary>
IReadOnlyList<IMarketBoardHistoryListing> HistoryListings { get; }
public IReadOnlyList<IMarketBoardHistoryListing> HistoryListings { get; }
}
/// <summary>
@ -26,30 +26,30 @@ public interface IMarketBoardHistoryListing
/// <summary>
/// Gets the buyer's name.
/// </summary>
string BuyerName { get; }
public string BuyerName { get; }
/// <summary>
/// Gets a value indicating whether the item is HQ.
/// </summary>
bool IsHq { get; }
public bool IsHq { get; }
/// <summary>
/// Gets a value indicating whether the item is on a mannequin.
/// </summary>
bool OnMannequin { get; }
public bool OnMannequin { get; }
/// <summary>
/// Gets the time of purchase.
/// </summary>
DateTime PurchaseTime { get; }
public DateTime PurchaseTime { get; }
/// <summary>
/// Gets the quantity.
/// </summary>
uint Quantity { get; }
public uint Quantity { get; }
/// <summary>
/// Gets the sale price.
/// </summary>
uint SalePrice { get; }
public uint SalePrice { get; }
}

View file

@ -9,10 +9,10 @@ public interface IMarketBoardPurchase
/// <summary>
/// Gets the item ID of the item that was purchased.
/// </summary>
uint CatalogId { get; }
public uint CatalogId { get; }
/// <summary>
/// Gets the quantity of the item that was purchased.
/// </summary>
uint ItemQuantity { get; }
public uint ItemQuantity { get; }
}

View file

@ -9,25 +9,40 @@ public interface IMarketBoardPurchaseHandler
/// <summary>
/// Gets the object ID of the retainer associated with the sale.
/// </summary>
ulong RetainerId { get; }
public ulong RetainerId { get; }
/// <summary>
/// Gets the object ID of the item listing.
/// </summary>
ulong ListingId { get; }
public ulong ListingId { get; }
/// <summary>
/// Gets the item ID of the item that was purchased.
/// </summary>
uint CatalogId { get; }
public uint CatalogId { get; }
/// <summary>
/// Gets the quantity of the item that was purchased.
/// </summary>
uint ItemQuantity { get; }
public uint ItemQuantity { get; }
/// <summary>
/// Gets the unit price of the item.
/// </summary>
uint PricePerUnit { get; }
public uint PricePerUnit { get; }
/// <summary>
/// Gets a value indicating whether the item is HQ.
/// </summary>
public bool IsHq { get; }
/// <summary>
/// Gets the total tax.
/// </summary>
public uint TotalTax { get; }
/// <summary>
/// Gets the city ID of the retainer selling the item.
/// </summary>
public int RetainerCityId { get; }
}

View file

@ -8,40 +8,50 @@ public interface IMarketTaxRates
/// <summary>
/// Gets the category of this ResultDialog packet.
/// </summary>
uint Category { get; }
public uint Category { get; }
/// <summary>
/// Gets the tax rate in Limsa Lominsa.
/// </summary>
uint LimsaLominsaTax { get; }
public uint LimsaLominsaTax { get; }
/// <summary>
/// Gets the tax rate in Gridania.
/// </summary>
uint GridaniaTax { get; }
public uint GridaniaTax { get; }
/// <summary>
/// Gets the tax rate in Ul'dah.
/// </summary>
uint UldahTax { get; }
public uint UldahTax { get; }
/// <summary>
/// Gets the tax rate in Ishgard.
/// </summary>
uint IshgardTax { get; }
public uint IshgardTax { get; }
/// <summary>
/// Gets the tax rate in Kugane.
/// </summary>
uint KuganeTax { get; }
public uint KuganeTax { get; }
/// <summary>
/// Gets the tax rate in the Crystarium.
/// </summary>
uint CrystariumTax { get; }
public uint CrystariumTax { get; }
/// <summary>
/// Gets the tax rate in the Crystarium.
/// </summary>
uint SharlayanTax { get; }
public uint SharlayanTax { get; }
/// <summary>
/// Gets the tax rate in Tuliyollal.
/// </summary>
public uint TuliyollalTax { get; }
/// <summary>
/// Gets until when these values are valid.
/// </summary>
public DateTime ValidUntil { get; }
}

View file

@ -17,22 +17,12 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
/// Gets the list of individual item listings.
/// </summary>
IReadOnlyList<IMarketBoardItemListing> IMarketBoardCurrentOfferings.ItemListings => this.InternalItemListings;
/// <summary>
/// Gets the listing end index.
/// </summary>
public int ListingIndexEnd { get; internal set; }
/// <summary>
/// Gets the listing start index.
/// </summary>
public int ListingIndexStart { get; internal set; }
/// <summary>
/// Gets the request ID.
/// </summary>
public int RequestId { get; internal set; }
/// <summary>
/// Gets or sets the internal read-write list of marketboard item listings.
/// </summary>
@ -43,7 +33,7 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
/// </summary>
/// <param name="dataPtr">Address to read.</param>
/// <returns>A new <see cref="MarketBoardCurrentOfferings"/> object.</returns>
public static unsafe MarketBoardCurrentOfferings Read(IntPtr dataPtr)
public static unsafe MarketBoardCurrentOfferings Read(nint dataPtr)
{
var output = new MarketBoardCurrentOfferings();
@ -60,19 +50,17 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
listingEntry.RetainerId = reader.ReadUInt64();
listingEntry.RetainerOwnerId = reader.ReadUInt64();
listingEntry.ArtisanId = reader.ReadUInt64();
listingEntry.PricePerUnit = reader.ReadUInt32();
listingEntry.TotalTax = reader.ReadUInt32();
listingEntry.ItemQuantity = reader.ReadUInt32();
listingEntry.CatalogId = reader.ReadUInt32();
listingEntry.LastReviewTime = DateTimeOffset.UtcNow.AddSeconds(-reader.ReadUInt16()).DateTime;
reader.ReadUInt16(); // container
reader.ReadUInt32(); // slot
reader.ReadUInt16(); // durability
reader.ReadUInt16(); // spiritbond
reader.ReadUInt16(); // Slot
reader.ReadUInt16(); // Durability
reader.ReadUInt16(); // Spiritbond
var materiaList = new List<IItemMateria>();
for (var materiaIndex = 0; materiaIndex < 5; materiaIndex++)
{
var materiaVal = reader.ReadUInt16();
@ -88,27 +76,28 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
listingEntry.Materia = materiaList;
reader.ReadUInt16();
reader.ReadUInt32();
reader.ReadBytes(0x6); // Padding
listingEntry.RetainerName = Encoding.UTF8.GetString(reader.ReadBytes(0x20)).TrimEnd('\u0000');
reader.ReadBytes(0x20); // Empty Buffer, was PlayerName pre 7.0
listingEntry.RetainerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
listingEntry.PlayerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
listingEntry.IsHq = reader.ReadBoolean();
listingEntry.MateriaCount = reader.ReadByte();
listingEntry.OnMannequin = reader.ReadBoolean();
listingEntry.RetainerCityId = reader.ReadByte();
listingEntry.StainId = reader.ReadUInt16();
reader.ReadUInt16();
reader.ReadUInt32();
listingEntry.Stain1Id = reader.ReadByte();
listingEntry.Stain2Id = reader.ReadByte();
reader.ReadBytes(0x4); // Padding
if (listingEntry.CatalogId != 0)
listings.Add(listingEntry);
}
output.InternalItemListings = listings;
output.ListingIndexEnd = reader.ReadByte();
output.ListingIndexStart = reader.ReadByte();
reader.ReadByte(); // Was ListingIndexEnd
reader.ReadByte(); // Was ListingIndexStart
output.RequestId = reader.ReadUInt16();
return output;
@ -152,7 +141,8 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
/// <summary>
/// Gets the time this offering was last reviewed.
/// </summary>
public DateTime LastReviewTime { get; internal set; }
[Obsolete("Universalis Compatibility, contains a fake value", false)]
internal DateTime LastReviewTime { get; set; } = DateTime.UtcNow;
/// <summary>
/// Gets the listing ID.
@ -177,7 +167,8 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
/// <summary>
/// Gets the player name.
/// </summary>
public string PlayerName { get; internal set; }
[Obsolete("Universalis Compatibility, contains a fake value", false)]
internal string PlayerName { get; set; } = string.Empty;
/// <summary>
/// Gets the price per unit.
@ -207,7 +198,18 @@ public class MarketBoardCurrentOfferings : IMarketBoardCurrentOfferings
/// <summary>
/// Gets the stain or applied dye of the item.
/// </summary>
public int StainId { get; internal set; }
[Obsolete("Universalis Compatibility, use Stain1Id and Stain2Id", false)]
internal int StainId => (this.Stain2Id << 8) | this.Stain1Id;
/// <summary>
/// Gets the first stain or applied dye of the item.
/// </summary>
public int Stain1Id { get; internal set; }
/// <summary>
/// Gets the second stain or applied dye of the item.
/// </summary>
public int Stain2Id { get; internal set; }
/// <summary>
/// Gets the total tax.

View file

@ -21,11 +21,6 @@ public class MarketBoardHistory : IMarketBoardHistory
/// </summary>
public uint CatalogId { get; private set; }
/// <summary>
/// Gets the second catalog ID.
/// </summary>
public uint CatalogId2 { get; private set; }
/// <summary>
/// Gets the ID (for EXD) for the item being sold.
/// </summary>
@ -39,51 +34,44 @@ public class MarketBoardHistory : IMarketBoardHistory
/// <summary>
/// Gets or sets a list of individual item listings.
/// </summary>
internal List<MarketBoardHistoryListing> InternalHistoryListings { get; set; } = new List<MarketBoardHistoryListing>();
internal List<MarketBoardHistoryListing> InternalHistoryListings { get; set; } = [];
/// <summary>
/// Read a <see cref="MarketBoardHistory"/> object from memory.
/// </summary>
/// <param name="dataPtr">Address to read.</param>
/// <returns>A new <see cref="MarketBoardHistory"/> object.</returns>
public static unsafe MarketBoardHistory Read(IntPtr dataPtr)
public static unsafe MarketBoardHistory Read(nint dataPtr)
{
using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
using var reader = new BinaryReader(stream);
var output = new MarketBoardHistory
{
CatalogId = reader.ReadUInt32(),
CatalogId2 = reader.ReadUInt32(),
};
if (output.CatalogId2 == 0)
{
// No items found in the resulting packet - just return the empty history.
return output;
}
var output = new MarketBoardHistory { CatalogId = reader.ReadUInt32() };
var historyListings = new List<MarketBoardHistoryListing>();
for (var i = 0; i < 20; i++)
{
var price = reader.ReadUInt32();
if (price == 0)
{
// no price means we reached the end of available listings
break;
}
var listingEntry = new MarketBoardHistoryListing
{
SalePrice = reader.ReadUInt32(),
SalePrice = price,
PurchaseTime = DateTimeOffset.FromUnixTimeSeconds(reader.ReadUInt32()).UtcDateTime,
Quantity = reader.ReadUInt32(),
IsHq = reader.ReadBoolean(),
OnMannequin = reader.ReadBoolean(),
BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(0x20)).TrimEnd('\u0000'),
};
reader.ReadBoolean();
listingEntry.OnMannequin = reader.ReadBoolean();
listingEntry.BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(33)).TrimEnd('\u0000');
listingEntry.NextCatalogId = reader.ReadUInt32();
// Skip padding
reader.ReadBytes(0x2);
historyListings.Add(listingEntry);
if (listingEntry.NextCatalogId == 0)
break;
}
output.InternalHistoryListings = historyListings;
@ -108,11 +96,6 @@ public class MarketBoardHistory : IMarketBoardHistory
/// </summary>
public string BuyerName { get; internal set; }
/// <summary>
/// Gets the next entry's catalog ID.
/// </summary>
public uint NextCatalogId { get; internal set; }
/// <summary>
/// Gets a value indicating whether the item is HQ.
/// </summary>

View file

@ -27,7 +27,7 @@ public class MarketBoardPurchase : IMarketBoardPurchase
/// </summary>
/// <param name="dataPtr">A pointer to a struct containing market board purchase information from the server.</param>
/// <returns>An object representing the data read.</returns>
public static unsafe MarketBoardPurchase Read(IntPtr dataPtr)
public static unsafe MarketBoardPurchase Read(nint dataPtr)
{
using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
using var reader = new BinaryReader(stream);
@ -35,7 +35,7 @@ public class MarketBoardPurchase : IMarketBoardPurchase
var output = new MarketBoardPurchase();
output.CatalogId = reader.ReadUInt32();
stream.Position += 4;
reader.ReadBytes(0x4); // Padding
output.ItemQuantity = reader.ReadUInt32();
return output;

View file

@ -37,24 +37,45 @@ public class MarketBoardPurchaseHandler : IMarketBoardPurchaseHandler
/// </summary>
public uint PricePerUnit { get; private set; }
/// <summary>
/// Gets a value indicating whether the item is HQ.
/// </summary>
public bool IsHq { get; private set; }
/// <summary>
/// Gets the total tax.
/// </summary>
public uint TotalTax { get; private set; }
/// <summary>
/// Gets the city ID of the retainer selling the item.
/// </summary>
public int RetainerCityId { get; private set; }
/// <summary>
/// Reads market board purchase information from the struct at the provided pointer.
/// </summary>
/// <param name="dataPtr">A pointer to a struct containing market board purchase information from the client.</param>
/// <returns>An object representing the data read.</returns>
public static unsafe MarketBoardPurchaseHandler Read(IntPtr dataPtr)
public static unsafe MarketBoardPurchaseHandler Read(nint dataPtr)
{
using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
using var reader = new BinaryReader(stream);
var output = new MarketBoardPurchaseHandler
{
RetainerId = reader.ReadUInt64(),
ListingId = reader.ReadUInt64(),
CatalogId = reader.ReadUInt32(),
ItemQuantity = reader.ReadUInt32(),
PricePerUnit = reader.ReadUInt32(),
};
var output = new MarketBoardPurchaseHandler();
output.RetainerId = reader.ReadUInt64();
output.ListingId = reader.ReadUInt64();
output.CatalogId = reader.ReadUInt32();
output.ItemQuantity = reader.ReadUInt32();
output.PricePerUnit = reader.ReadUInt32();
output.TotalTax = reader.ReadUInt32();
reader.ReadUInt16(); // Slot
output.IsHq = reader.ReadBoolean();
output.RetainerCityId = reader.ReadByte();
return output;
}

View file

@ -48,16 +48,26 @@ public class MarketTaxRates : IMarketTaxRates
public uint CrystariumTax { get; private set; }
/// <summary>
/// Gets the tax rate in the Crystarium.
/// Gets the tax rate in Sharlayan.
/// </summary>
public uint SharlayanTax { get; private set; }
/// <summary>
/// Gets the tax rate in Tuliyollal.
/// </summary>
public uint TuliyollalTax { get; private set; }
/// <summary>
/// Gets until when these values are valid.
/// </summary>
public DateTime ValidUntil { get; private set; }
/// <summary>
/// Read a <see cref="MarketTaxRates"/> object from memory.
/// </summary>
/// <param name="dataPtr">Address to read.</param>
/// <returns>A new <see cref="MarketTaxRates"/> object.</returns>
public static unsafe MarketTaxRates Read(IntPtr dataPtr)
public static unsafe MarketTaxRates Read(nint dataPtr)
{
using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
using var reader = new BinaryReader(stream);
@ -73,23 +83,26 @@ public class MarketTaxRates : IMarketTaxRates
output.KuganeTax = reader.ReadUInt32();
output.CrystariumTax = reader.ReadUInt32();
output.SharlayanTax = reader.ReadUInt32();
output.TuliyollalTax = reader.ReadUInt32();
output.ValidUntil = DateTime.Now; // Dalamud never reads this packet, so setting it to Now just to be safe
return output;
}
/// <summary>
/// Generate a MarketTaxRates wrapper class from information located in a CustomTalk packet.
/// </summary>
/// <param name="dataPtr">The pointer to the relevant CustomTalk data.</param>
/// <returns>Returns a wrapped and ready-to-go MarketTaxRates record.</returns>
public static unsafe MarketTaxRates ReadFromCustomTalk(IntPtr dataPtr)
public static unsafe MarketTaxRates ReadFromCustomTalk(nint dataPtr)
{
using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
using var reader = new BinaryReader(stream);
return new MarketTaxRates
{
Category = 0xb0009, // shim
Category = 0xB0009, // shim
LimsaLominsaTax = reader.ReadUInt32(),
GridaniaTax = reader.ReadUInt32(),
UldahTax = reader.ReadUInt32(),
@ -97,6 +110,8 @@ public class MarketTaxRates : IMarketTaxRates
KuganeTax = reader.ReadUInt32(),
CrystariumTax = reader.ReadUInt32(),
SharlayanTax = reader.ReadUInt32(),
TuliyollalTax = reader.ReadUInt32(),
ValidUntil = DateTimeOffset.FromUnixTimeSeconds(reader.ReadUInt32()).UtcDateTime,
};
}
}

View file

@ -54,7 +54,7 @@ internal class MarketBoardWidget : IDataWindowWidget
public void Load()
{
this.trackMarketBoard = false;
this.trackedEvents = 0;
this.trackedEvents = 1;
this.marketBoardHistoryQueue.Clear();
this.marketBoardPurchaseRequestsQueue.Clear();
this.marketBoardPurchasesQueue.Clear();
@ -114,7 +114,7 @@ internal class MarketBoardWidget : IDataWindowWidget
{
if (tabItem)
{
ImGuiTable.DrawTable(string.Empty, this.marketBoardCurrentOfferingsQueue, this.DrawMarketBoardCurrentOfferings, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Item ID", "Quantity", "Is HQ?", "Price Per Unit", "Buyer Name", "Retainer Name", "Last Review Time");
ImGuiTable.DrawTable(string.Empty, this.marketBoardCurrentOfferingsQueue, this.DrawMarketBoardCurrentOfferings, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Item ID", "Quantity", "Is HQ?", "Price Per Unit", "Retainer Name");
}
}
@ -130,7 +130,7 @@ internal class MarketBoardWidget : IDataWindowWidget
{
if (tabItem)
{
ImGuiTable.DrawTable(string.Empty, this.marketBoardPurchaseRequestsQueue, this.DrawMarketBoardPurchaseRequests, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Item ID", "Quantity", "Price Per Unit", "Listing ID", "Retainer ID");
ImGuiTable.DrawTable(string.Empty, this.marketBoardPurchaseRequestsQueue, this.DrawMarketBoardPurchaseRequests, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Item ID", "Is HQ?", "Quantity", "Price Per Unit", "Total Tax", "City ID", "Listing ID", "Retainer ID");
}
}
@ -138,7 +138,7 @@ internal class MarketBoardWidget : IDataWindowWidget
{
if (tabItem)
{
ImGuiTable.DrawTable(string.Empty, this.marketTaxRatesQueue, this.DrawMarketTaxRates, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Uldah", "Limsa Lominsa", "Gridania", "Ishgard", "Kugane", "Crystarium", "Sharlayan");
ImGuiTable.DrawTable(string.Empty, this.marketTaxRatesQueue, this.DrawMarketTaxRates, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Uldah", "Limsa Lominsa", "Gridania", "Ishgard", "Kugane", "Crystarium", "Sharlayan", "Tuliyollal", "Valid Until");
}
}
}
@ -236,14 +236,8 @@ internal class MarketBoardWidget : IDataWindowWidget
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.Listing.PricePerUnit.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.Listing.PlayerName);
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.Listing.RetainerName);
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.Listing.LastReviewTime.ToString(CultureInfo.InvariantCulture));
}
private void DrawMarketBoardPurchases(IMarketBoardPurchase data)
@ -260,12 +254,21 @@ internal class MarketBoardWidget : IDataWindowWidget
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.CatalogId.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.IsHq.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.ItemQuantity.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.PricePerUnit.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.TotalTax.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.RetainerCityId.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.ListingId.ToString());
@ -295,5 +298,11 @@ internal class MarketBoardWidget : IDataWindowWidget
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.SharlayanTax.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.TuliyollalTax.ToString());
ImGui.TableNextColumn();
ImGui.TextUnformatted(data.ValidUntil.ToString(CultureInfo.InvariantCulture));
}
}