mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
* Add MarketBoard service and associated interfaces, test and data widget * Dispose of events properly * Make listings readonly lists + provide internal list for internal use * Rename CatalogId to ItemId on interfaces, have kept CatalogId internally as it's technically correct * Removed RetainerOwnerId from the public interface * Removed NextCatalogId from the public interface * Updated test text * Null events in scoped service disposal
190 lines
5.4 KiB
C#
190 lines
5.4 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Dalamud.Game.Network.Structures;
|
|
|
|
/// <summary>
|
|
/// This class represents the market board history from a game network packet.
|
|
/// </summary>
|
|
public class MarketBoardHistory : IMarketBoardHistory
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MarketBoardHistory"/> class.
|
|
/// </summary>
|
|
internal MarketBoardHistory()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the catalog ID.
|
|
/// </summary>
|
|
public uint CatalogId { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the second catalog ID.
|
|
/// </summary>
|
|
public uint CatalogId2 { get; private set; }
|
|
|
|
public uint ItemId => this.CatalogId;
|
|
|
|
/// <summary>
|
|
/// Gets the list of individual item listings.
|
|
/// </summary>
|
|
IReadOnlyList<IMarketBoardHistoryListing> IMarketBoardHistory.HistoryListings => this.InternalHistoryListings;
|
|
|
|
/// <summary>
|
|
/// Gets or sets a list of individual item listings.
|
|
/// </summary>
|
|
internal List<MarketBoardHistoryListing> InternalHistoryListings { get; set; } = new List<MarketBoardHistoryListing>();
|
|
|
|
/// <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)
|
|
{
|
|
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 historyListings = new List<MarketBoardHistoryListing>();
|
|
for (var i = 0; i < 20; i++)
|
|
{
|
|
var listingEntry = new MarketBoardHistoryListing
|
|
{
|
|
SalePrice = reader.ReadUInt32(),
|
|
PurchaseTime = DateTimeOffset.FromUnixTimeSeconds(reader.ReadUInt32()).UtcDateTime,
|
|
Quantity = reader.ReadUInt32(),
|
|
IsHq = reader.ReadBoolean(),
|
|
};
|
|
|
|
reader.ReadBoolean();
|
|
|
|
listingEntry.OnMannequin = reader.ReadBoolean();
|
|
listingEntry.BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(33)).TrimEnd('\u0000');
|
|
listingEntry.NextCatalogId = reader.ReadUInt32();
|
|
|
|
historyListings.Add(listingEntry);
|
|
|
|
if (listingEntry.NextCatalogId == 0)
|
|
break;
|
|
}
|
|
|
|
output.InternalHistoryListings = historyListings;
|
|
|
|
return output;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This class represents the market board history of a single item from the <see cref="MarketBoardHistory"/> network packet.
|
|
/// </summary>
|
|
public class MarketBoardHistoryListing : IMarketBoardHistoryListing
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MarketBoardHistoryListing"/> class.
|
|
/// </summary>
|
|
internal MarketBoardHistoryListing()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the buyer's name.
|
|
/// </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>
|
|
public bool IsHq { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the item is on a mannequin.
|
|
/// </summary>
|
|
public bool OnMannequin { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// Gets the time of purchase.
|
|
/// </summary>
|
|
public DateTime PurchaseTime { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// Gets the quantity.
|
|
/// </summary>
|
|
public uint Quantity { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// Gets the sale price.
|
|
/// </summary>
|
|
public uint SalePrice { get; internal set; }
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An interface that represents the market board history from the game.
|
|
/// </summary>
|
|
public interface IMarketBoardHistory
|
|
{
|
|
/// <summary>
|
|
/// Gets the item ID.
|
|
/// </summary>
|
|
uint ItemId { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the list of individual item history listings.
|
|
/// </summary>
|
|
IReadOnlyList<IMarketBoardHistoryListing> HistoryListings { get; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// An interface that represents the market board history of a single item from <see cref="IMarketBoardHistory"/>.
|
|
/// </summary>
|
|
public interface IMarketBoardHistoryListing
|
|
{
|
|
/// <summary>
|
|
/// Gets the buyer's name.
|
|
/// </summary>
|
|
string BuyerName { get; }
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the item is HQ.
|
|
/// </summary>
|
|
bool IsHq { get; }
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the item is on a mannequin.
|
|
/// </summary>
|
|
bool OnMannequin { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the time of purchase.
|
|
/// </summary>
|
|
DateTime PurchaseTime { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the quantity.
|
|
/// </summary>
|
|
uint Quantity { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the sale price.
|
|
/// </summary>
|
|
uint SalePrice { get; }
|
|
}
|