From 8b8d1ca74ce9addba75e65153e771111a6726b5b Mon Sep 17 00:00:00 2001
From: karashiiro <49822414+karashiiro@users.noreply.github.com>
Date: Wed, 23 Jun 2021 10:31:15 -0700
Subject: [PATCH] Implement market board purchase message reading Originally
from
https://github.com/Aireil/Dalamud/commit/d85146c0d9c911634228ee00bd2bf2eed9c8fb52
---
Dalamud/Game/Network/NetworkHandlers.cs | 40 +++++++++++--
.../Network/Structures/MarketBoardPurchase.cs | 40 +++++++++++++
.../Structures/MarketBoardPurchaseHandler.cs | 57 +++++++++++++++++++
3 files changed, 132 insertions(+), 5 deletions(-)
create mode 100644 Dalamud/Game/Network/Structures/MarketBoardPurchase.cs
create mode 100644 Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs
diff --git a/Dalamud/Game/Network/NetworkHandlers.cs b/Dalamud/Game/Network/NetworkHandlers.cs
index 790ed57d5..c918d8b83 100644
--- a/Dalamud/Game/Network/NetworkHandlers.cs
+++ b/Dalamud/Game/Network/NetworkHandlers.cs
@@ -15,7 +15,7 @@ using Serilog;
namespace Dalamud.Game.Network
{
///
- /// This class handles network notifications and uploading Marketboard data.
+ /// This class handles network notifications and uploading market board data.
///
public class NetworkHandlers
{
@@ -23,6 +23,8 @@ namespace Dalamud.Game.Network
private readonly List marketBoardRequests = new();
+ private MarketBoardPurchaseHandler marketBoardPurchaseHandler;
+
private readonly bool optOutMbUploads;
private readonly IMarketBoardUploader uploader;
@@ -30,7 +32,7 @@ namespace Dalamud.Game.Network
/// Initializes a new instance of the class.
///
/// The Dalamud instance.
- /// Whether the client should opt out of marketboard uploads.
+ /// Whether the client should opt out of market board uploads.
public NetworkHandlers(Dalamud dalamud, bool optOutMbUploads)
{
this.dalamud = dalamud;
@@ -48,12 +50,22 @@ namespace Dalamud.Game.Network
private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
{
- if (direction != NetworkMessageDirection.ZoneDown)
- return;
-
if (!this.dalamud.Data.IsDataReady)
return;
+ if (direction == NetworkMessageDirection.ZoneUp)
+ {
+ if (!this.optOutMbUploads)
+ {
+ if (opCode == this.dalamud.Data.ClientOpCodes["MarketBoardPurchaseHandler"])
+ {
+ this.marketBoardPurchaseHandler = MarketBoardPurchaseHandler.Read(dataPtr);
+ }
+ }
+
+ return;
+ }
+
if (opCode == this.dalamud.Data.ServerOpCodes["CfNotifyPop"])
{
var data = new byte[64];
@@ -256,6 +268,24 @@ namespace Dalamud.Game.Network
Log.Error(ex, "Market Board data upload failed.");
}
}
+
+ if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardPurchase"])
+ {
+ if (this.marketBoardPurchaseHandler == null)
+ return;
+
+ var purchase = MarketBoardPurchase.Read(dataPtr);
+
+ // Transaction succeeded
+ if (purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity
+ && (purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId
+ || purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1000000))
+ { // HQ
+ Log.Information("Bought " + purchase.ItemQuantity + "x " + this.marketBoardPurchaseHandler.CatalogId + " for " + (this.marketBoardPurchaseHandler.PricePerUnit * purchase.ItemQuantity) + " gils, listing id is " + this.marketBoardPurchaseHandler.ListingId);
+ }
+
+ this.marketBoardPurchaseHandler = null;
+ }
}
}
}
diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs
new file mode 100644
index 000000000..ed8051154
--- /dev/null
+++ b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs
@@ -0,0 +1,40 @@
+using System;
+using System.IO;
+
+namespace Dalamud.Game.Network.Structures
+{
+ ///
+ /// Represents market board purchase information. This message is received from the
+ /// server when a purchase is made at a market board.
+ ///
+ internal class MarketBoardPurchase
+ {
+ ///
+ /// Gets the item ID of the item that was purchased.
+ ///
+ public uint CatalogId { get; private set; }
+
+ ///
+ /// Gets the quantity of the item that was purchased.
+ ///
+ public uint ItemQuantity { get; private set; }
+
+ ///
+ /// Reads market board purchase information from the struct at the provided pointer.
+ ///
+ /// A pointer to a struct containing market board purchase information from the server.
+ /// An object representing the data read.
+ public static unsafe MarketBoardPurchase Read(IntPtr dataPtr)
+ {
+ var output = new MarketBoardPurchase();
+
+ using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
+ using var reader = new BinaryReader(stream);
+ output.CatalogId = reader.ReadUInt32();
+ stream.Position += 4;
+ output.ItemQuantity = reader.ReadUInt32();
+
+ return output;
+ }
+ }
+}
diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs
new file mode 100644
index 000000000..98d7007b0
--- /dev/null
+++ b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+
+namespace Dalamud.Game.Network.Structures
+{
+ ///
+ /// Represents market board purchase information. This message is sent from the
+ /// client when a purchase is made at a market board.
+ ///
+ internal class MarketBoardPurchaseHandler
+ {
+ ///
+ /// Gets the object ID of the retainer associated with the sale.
+ ///
+ public ulong RetainerId { get; private set; }
+
+ ///
+ /// Gets the object ID of the item listing.
+ ///
+ public ulong ListingId { get; private set; }
+
+ ///
+ /// Gets the item ID of the item that was purchased.
+ ///
+ public uint CatalogId { get; private set; }
+
+ ///
+ /// Gets the quantity of the item that was purchased.
+ ///
+ public uint ItemQuantity { get; private set; }
+
+ ///
+ /// Gets the unit price of the item.
+ ///
+ public uint PricePerUnit { get; private set; }
+
+ ///
+ /// Reads market board purchase information from the struct at the provided pointer.
+ ///
+ /// A pointer to a struct containing market board purchase information from the client.
+ /// An object representing the data read.
+ public static unsafe MarketBoardPurchaseHandler Read(IntPtr dataPtr)
+ {
+ var output = new MarketBoardPurchaseHandler();
+
+ using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544);
+ using var reader = new BinaryReader(stream);
+ output.RetainerId = reader.ReadUInt64();
+ output.ListingId = reader.ReadUInt64();
+ output.CatalogId = reader.ReadUInt32();
+ output.ItemQuantity = reader.ReadUInt32();
+ output.PricePerUnit = reader.ReadUInt32();
+
+ return output;
+ }
+ }
+}