diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs
index dadfef604..adf5f0228 100644
--- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs
+++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs
@@ -13,20 +13,26 @@ internal interface IMarketBoardUploader
/// Upload data about an item.
///
/// The item request data being uploaded.
+ /// The uploaders ContentId.
+ /// The uploaders WorldId.
/// An async task.
- Task Upload(MarketBoardItemRequest item);
+ Task Upload(MarketBoardItemRequest item, ulong uploaderId, uint worldId);
///
/// Upload tax rate data.
///
/// The tax rate data being uploaded.
+ /// The uploaders ContentId.
+ /// The uploaders WorldId.
/// An async task.
- Task UploadTax(MarketTaxRates taxRates);
+ Task UploadTax(MarketTaxRates taxRates, ulong uploaderId, uint worldId);
///
/// Upload information about a purchase this client has made.
///
/// The purchase handler data associated with the sale.
+ /// The uploaders ContentId.
+ /// The uploaders WorldId.
/// An async task.
- Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler);
+ Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler, ulong uploaderId, uint worldId);
}
diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
index f326c5ce0..7ecb9c397 100644
--- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
+++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
@@ -33,21 +32,16 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
this.httpClient = happyHttpClient.SharedHttpClient;
///
- public async Task Upload(MarketBoardItemRequest request)
+ public async Task Upload(MarketBoardItemRequest request, ulong uploaderId, uint worldId)
{
- var clientState = Service.GetNullable();
- if (clientState == null)
- return;
-
Log.Verbose("Starting Universalis upload");
- var uploader = clientState.LocalContentId;
// ====================================================================================
var uploadObject = new UniversalisItemUploadRequest
{
- WorldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0,
- UploaderId = uploader.ToString(),
+ WorldId = worldId,
+ UploaderId = uploaderId.ToString(),
ItemId = request.CatalogId,
Listings = [],
Sales = [],
@@ -117,18 +111,12 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
}
///
- public async Task UploadTax(MarketTaxRates taxRates)
+ public async Task UploadTax(MarketTaxRates taxRates, ulong uploaderId, uint worldId)
{
- var clientState = Service.GetNullable();
- if (clientState == null)
- return;
-
- // ====================================================================================
-
var taxUploadObject = new UniversalisTaxUploadRequest
{
- WorldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0,
- UploaderId = clientState.LocalContentId.ToString(),
+ WorldId = worldId,
+ UploaderId = uploaderId.ToString(),
TaxData = new UniversalisTaxData
{
LimsaLominsa = taxRates.LimsaLominsaTax,
@@ -159,14 +147,9 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
/// to track the available listings, that is done via the listings packet. All this does is remove
/// a listing, or delete it, when a purchase has been made.
///
- public async Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler)
+ public async Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler, ulong uploaderId, uint worldId)
{
- var clientState = Service.GetNullable();
- if (clientState == null)
- return;
-
var itemId = purchaseHandler.CatalogId;
- var worldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0;
// ====================================================================================
@@ -176,7 +159,7 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
Quantity = purchaseHandler.ItemQuantity,
ListingId = purchaseHandler.ListingId.ToString(),
RetainerId = purchaseHandler.RetainerId.ToString(),
- UploaderId = clientState.LocalContentId.ToString(),
+ UploaderId = uploaderId.ToString(),
};
var deletePath = $"/api/{worldId}/{itemId}/delete";
diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs
index a25444f10..2ba7f2587 100644
--- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs
+++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs
@@ -16,8 +16,11 @@ using Dalamud.Hooking;
using Dalamud.Networking.Http;
using Dalamud.Utility;
+using FFXIVClientStructs.FFXIV.Client.Game.Control;
using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent;
+using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.Network;
+using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Client.UI.Info;
using Lumina.Excel.Sheets;
using Serilog;
@@ -264,6 +267,33 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
this.cfPopHook.Dispose();
}
+ private static (ulong UploaderId, uint WorldId) GetUploaderInfo()
+ {
+ var agentLobby = AgentLobby.Instance();
+
+ var uploaderId = agentLobby->LobbyData.ContentId;
+ if (uploaderId == 0)
+ {
+ var playerState = PlayerState.Instance();
+ if (playerState->IsLoaded == 1)
+ {
+ uploaderId = playerState->ContentId;
+ }
+ }
+
+ var worldId = agentLobby->LobbyData.CurrentWorldId;
+ if (worldId == 0)
+ {
+ var localPlayer = Control.GetLocalPlayer();
+ if (localPlayer != null)
+ {
+ worldId = localPlayer->CurrentWorld;
+ }
+ }
+
+ return (uploaderId, worldId);
+ }
+
private unsafe nint CfPopDetour(PublicContentDirector.EnterContentInfoPacket* packetData)
{
var result = this.cfPopHook.OriginalDisposeSafe(packetData);
@@ -424,14 +454,14 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
startObservable
.And(this.OnMarketBoardSalesBatch(startObservable))
.And(this.OnMarketBoardListingsBatch(startObservable))
- .Then((request, sales, listings) => (request, sales, listings)))
+ .Then((request, sales, listings) => (request, sales, listings, GetUploaderInfo())))
.Where(this.ShouldUpload)
.SubscribeOn(ThreadPoolScheduler.Instance)
.Subscribe(
data =>
{
- var (request, sales, listings) = data;
- this.UploadMarketBoardData(request, sales, listings);
+ var (request, sales, listings, uploaderInfo) = data;
+ this.UploadMarketBoardData(request, sales, listings, uploaderInfo.UploaderId, uploaderInfo.WorldId);
},
ex => Log.Error(ex, "Failed to handle Market Board item request event"));
}
@@ -439,7 +469,9 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
private void UploadMarketBoardData(
MarketBoardItemRequest request,
(uint CatalogId, ICollection Sales) sales,
- ICollection listings)
+ ICollection listings,
+ ulong uploaderId,
+ uint worldId)
{
var catalogId = sales.CatalogId;
if (listings.Count != request.AmountToArrive)
@@ -460,7 +492,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
request.Listings.AddRange(listings);
request.History.AddRange(sales.Sales);
- Task.Run(() => this.uploader.Upload(request))
+ Task.Run(() => this.uploader.Upload(request, uploaderId, worldId))
.ContinueWith(
task => Log.Error(task.Exception, "Market Board offerings data upload failed"),
TaskContinuationOptions.OnlyOnFaulted);
@@ -469,11 +501,14 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
private IDisposable HandleMarketTaxRates()
{
return this.MbTaxesObservable
+ .Select((taxes) => (taxes, GetUploaderInfo()))
.Where(this.ShouldUpload)
.SubscribeOn(ThreadPoolScheduler.Instance)
.Subscribe(
- taxes =>
+ data =>
{
+ var (taxes, uploaderInfo) = data;
+
Log.Verbose(
"MarketTaxRates: limsa#{0} grid#{1} uldah#{2} ish#{3} kugane#{4} cr#{5} sh#{6}",
taxes.LimsaLominsaTax,
@@ -484,7 +519,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
taxes.CrystariumTax,
taxes.SharlayanTax);
- Task.Run(() => this.uploader.UploadTax(taxes))
+ Task.Run(() => this.uploader.UploadTax(taxes, uploaderInfo.UploaderId, uploaderInfo.WorldId))
.ContinueWith(
task => Log.Error(task.Exception, "Market Board tax data upload failed"),
TaskContinuationOptions.OnlyOnFaulted);
@@ -495,13 +530,13 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
private IDisposable HandleMarketBoardPurchaseHandler()
{
return this.MbPurchaseSentObservable
- .Zip(this.MbPurchaseObservable)
+ .Zip(this.MbPurchaseObservable, (handler, purchase) => (handler, purchase, GetUploaderInfo()))
.Where(this.ShouldUpload)
.SubscribeOn(ThreadPoolScheduler.Instance)
.Subscribe(
data =>
{
- var (handler, purchase) = data;
+ var (handler, purchase, uploaderInfo) = data;
var sameQty = purchase.ItemQuantity == handler.ItemQuantity;
var itemMatch = purchase.CatalogId == handler.CatalogId;
@@ -516,7 +551,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
handler.CatalogId,
handler.PricePerUnit * purchase.ItemQuantity,
handler.ListingId);
- Task.Run(() => this.uploader.UploadPurchase(handler))
+ Task.Run(() => this.uploader.UploadPurchase(handler, uploaderInfo.UploaderId, uploaderInfo.WorldId))
.ContinueWith(
task => Log.Error(task.Exception, "Market Board purchase data upload failed"),
TaskContinuationOptions.OnlyOnFaulted);