mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #453 from daemitus/GameNetwork
This commit is contained in:
commit
daf115b377
18 changed files with 375 additions and 117 deletions
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using Dalamud.Game.Network;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Dalamud.Game.Network.Structures;
|
using Dalamud.Game.Network.Structures;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface binding for the Universalis uploader.
|
/// An interface binding for the Universalis uploader.
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Dalamud.Game.Network.Structures;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This represents a submission to a marketboard aggregation website.
|
||||||
|
/// </summary>
|
||||||
|
internal class MarketBoardItemRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the catalog ID.
|
||||||
|
/// </summary>
|
||||||
|
public uint CatalogId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount to arrive.
|
||||||
|
/// </summary>
|
||||||
|
public byte AmountToArrive { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the offered item listings.
|
||||||
|
/// </summary>
|
||||||
|
public List<MarketBoardCurrentOfferings.MarketBoardItemListing> Listings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the historical item listings.
|
||||||
|
/// </summary>
|
||||||
|
public List<MarketBoardHistory.MarketBoardHistoryListing> History { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the listing request ID.
|
||||||
|
/// </summary>
|
||||||
|
public int ListingsRequestId { get; set; } = -1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the upload is complete.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request payload for market board purchases.
|
/// Request payload for market board purchases.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UniversalisItemListingDeleteRequest
|
internal class UniversalisItemListingDeleteRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the object ID of the retainer associated with the sale.
|
/// Gets or sets the object ID of the retainer associated with the sale.
|
||||||
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Universalis API structure.
|
/// A Universalis API structure.
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
using Dalamud.Game.Network.MarketBoardUploaders;
|
using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types;
|
||||||
using Dalamud.Game.Network.MarketBoardUploaders.Universalis;
|
|
||||||
using Dalamud.Game.Network.Structures;
|
using Dalamud.Game.Network.Structures;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an uploader for contributing data to Universalis.
|
/// This class represents an uploader for contributing data to Universalis.
|
||||||
|
|
@ -16,8 +17,8 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
internal class UniversalisMarketBoardUploader : IMarketBoardUploader
|
internal class UniversalisMarketBoardUploader : IMarketBoardUploader
|
||||||
{
|
{
|
||||||
private const string ApiBase = "https://universalis.app";
|
private const string ApiBase = "https://universalis.app";
|
||||||
|
|
||||||
// private const string ApiBase = "https://127.0.0.1:443";
|
// private const string ApiBase = "https://127.0.0.1:443";
|
||||||
|
|
||||||
private const string ApiKey = "GGD6RdSfGyRiHM5WDnAo0Nj9Nv7aC5NDhMj3BebT";
|
private const string ApiKey = "GGD6RdSfGyRiHM5WDnAo0Nj9Nv7aC5NDhMj3BebT";
|
||||||
|
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
|
|
@ -34,14 +35,14 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Upload(MarketBoardItemRequest request)
|
public void Upload(MarketBoardItemRequest request)
|
||||||
{
|
{
|
||||||
using var client = new WebClient();
|
using var client = new HttpClient();
|
||||||
|
|
||||||
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
|
|
||||||
|
|
||||||
Log.Verbose("Starting Universalis upload.");
|
Log.Verbose("Starting Universalis upload.");
|
||||||
var uploader = this.dalamud.ClientState.LocalContentId;
|
var uploader = this.dalamud.ClientState.LocalContentId;
|
||||||
|
|
||||||
var listingsRequestObject = new UniversalisItemListingsUploadRequest
|
// ====================================================================================
|
||||||
|
|
||||||
|
var listingsUploadObject = new UniversalisItemListingsUploadRequest
|
||||||
{
|
{
|
||||||
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
||||||
UploaderId = uploader.ToString(),
|
UploaderId = uploader.ToString(),
|
||||||
|
|
@ -76,14 +77,17 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
listingsRequestObject.Listings.Add(universalisListing);
|
listingsUploadObject.Listings.Add(universalisListing);
|
||||||
}
|
}
|
||||||
|
|
||||||
var upload = JsonConvert.SerializeObject(listingsRequestObject);
|
var listingPath = "/upload";
|
||||||
Log.Verbose(upload);
|
var listingUpload = JsonConvert.SerializeObject(listingsUploadObject);
|
||||||
client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", upload);
|
Log.Verbose($"{listingPath}: {listingUpload}");
|
||||||
|
client.PostAsync($"{ApiBase}{listingPath}/{ApiKey}", new StringContent(listingUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult();
|
||||||
|
|
||||||
var historyRequestObject = new UniversalisHistoryUploadRequest
|
// ====================================================================================
|
||||||
|
|
||||||
|
var historyUploadObject = new UniversalisHistoryUploadRequest
|
||||||
{
|
{
|
||||||
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
||||||
UploaderId = uploader.ToString(),
|
UploaderId = uploader.ToString(),
|
||||||
|
|
@ -93,7 +97,7 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
|
|
||||||
foreach (var marketBoardHistoryListing in request.History)
|
foreach (var marketBoardHistoryListing in request.History)
|
||||||
{
|
{
|
||||||
historyRequestObject.Entries.Add(new UniversalisHistoryEntry
|
historyUploadObject.Entries.Add(new UniversalisHistoryEntry
|
||||||
{
|
{
|
||||||
BuyerName = marketBoardHistoryListing.BuyerName,
|
BuyerName = marketBoardHistoryListing.BuyerName,
|
||||||
Hq = marketBoardHistoryListing.IsHq,
|
Hq = marketBoardHistoryListing.IsHq,
|
||||||
|
|
@ -104,11 +108,12 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
|
var historyPath = "/upload";
|
||||||
|
var historyUpload = JsonConvert.SerializeObject(historyUploadObject);
|
||||||
|
Log.Verbose($"{historyPath}: {historyUpload}");
|
||||||
|
client.PostAsync($"{ApiBase}{historyPath}/{ApiKey}", new StringContent(historyUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult();
|
||||||
|
|
||||||
var historyUpload = JsonConvert.SerializeObject(historyRequestObject);
|
// ====================================================================================
|
||||||
Log.Verbose(historyUpload);
|
|
||||||
client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
|
|
||||||
|
|
||||||
Log.Verbose("Universalis data upload for item#{0} completed.", request.CatalogId);
|
Log.Verbose("Universalis data upload for item#{0} completed.", request.CatalogId);
|
||||||
}
|
}
|
||||||
|
|
@ -116,9 +121,11 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void UploadTax(MarketTaxRates taxRates)
|
public void UploadTax(MarketTaxRates taxRates)
|
||||||
{
|
{
|
||||||
using var client = new WebClient();
|
using var client = new HttpClient();
|
||||||
|
|
||||||
var taxRatesRequest = new UniversalisTaxUploadRequest
|
// ====================================================================================
|
||||||
|
|
||||||
|
var taxUploadObject = new UniversalisTaxUploadRequest
|
||||||
{
|
{
|
||||||
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
||||||
UploaderId = this.dalamud.ClientState.LocalContentId.ToString(),
|
UploaderId = this.dalamud.ClientState.LocalContentId.ToString(),
|
||||||
|
|
@ -133,26 +140,35 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
|
var taxPath = "/upload";
|
||||||
|
var taxUpload = JsonConvert.SerializeObject(taxUploadObject);
|
||||||
|
Log.Verbose($"{taxPath}: {taxUpload}");
|
||||||
|
|
||||||
var historyUpload = JsonConvert.SerializeObject(taxRatesRequest);
|
client.PostAsync($"{ApiBase}{taxPath}/{ApiKey}", new StringContent(taxUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult();
|
||||||
Log.Verbose(historyUpload);
|
|
||||||
client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
|
// ====================================================================================
|
||||||
|
|
||||||
Log.Verbose("Universalis tax upload completed.");
|
Log.Verbose("Universalis tax upload completed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
/// <remarks>
|
||||||
|
/// It may seem backwards that an upload only performs a delete request, however this is not trying
|
||||||
|
/// 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.
|
||||||
|
/// </remarks>
|
||||||
public void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler)
|
public void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler)
|
||||||
{
|
{
|
||||||
using var client = new WebClient();
|
using var client = new HttpClient();
|
||||||
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
|
|
||||||
client.Headers.Add(HttpRequestHeader.Authorization, ApiKey);
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(ApiKey);
|
||||||
|
|
||||||
var itemId = purchaseHandler.CatalogId;
|
var itemId = purchaseHandler.CatalogId;
|
||||||
var worldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0;
|
var worldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0;
|
||||||
|
|
||||||
var purchaseRequest = new UniversalisItemListingDeleteRequest
|
// ====================================================================================
|
||||||
|
|
||||||
|
var deleteListingObject = new UniversalisItemListingDeleteRequest
|
||||||
{
|
{
|
||||||
PricePerUnit = purchaseHandler.PricePerUnit,
|
PricePerUnit = purchaseHandler.PricePerUnit,
|
||||||
Quantity = purchaseHandler.ItemQuantity,
|
Quantity = purchaseHandler.ItemQuantity,
|
||||||
|
|
@ -161,11 +177,13 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders
|
||||||
UploaderId = this.dalamud.ClientState.LocalContentId.ToString(),
|
UploaderId = this.dalamud.ClientState.LocalContentId.ToString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var requestPath = ApiBase + $"/api/{worldId}/{itemId}/delete";
|
var deletePath = $"/api/{worldId}/{itemId}/delete";
|
||||||
var purchaseUpload = JsonConvert.SerializeObject(purchaseRequest);
|
var deleteListing = JsonConvert.SerializeObject(deleteListingObject);
|
||||||
Log.Verbose($"Making request to {requestPath}");
|
Log.Verbose($"{deletePath}: {deleteListing}");
|
||||||
Log.Verbose(purchaseUpload);
|
|
||||||
client.UploadString(requestPath, "POST", purchaseUpload);
|
client.PostAsync($"{ApiBase}{deletePath}", new StringContent(deleteListing, Encoding.UTF8, "application/json")).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
// ====================================================================================
|
||||||
|
|
||||||
Log.Verbose("Universalis purchase upload completed.");
|
Log.Verbose("Universalis purchase upload completed.");
|
||||||
}
|
}
|
||||||
|
|
@ -5,14 +5,13 @@ using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Dalamud.Game.Internal.Network;
|
using Dalamud.Game.Network.Internal.MarketBoardUploaders;
|
||||||
using Dalamud.Game.Network.MarketBoardUploaders;
|
using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis;
|
||||||
using Dalamud.Game.Network.Structures;
|
using Dalamud.Game.Network.Structures;
|
||||||
using Dalamud.Game.Network.Universalis.MarketBoardUploaders;
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network
|
namespace Dalamud.Game.Network.Internal
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class handles network notifications and uploading market board data.
|
/// This class handles network notifications and uploading market board data.
|
||||||
|
|
@ -141,7 +140,7 @@ namespace Dalamud.Game.Network
|
||||||
|
|
||||||
var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);
|
var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);
|
||||||
|
|
||||||
if (request == null)
|
if (request == default)
|
||||||
{
|
{
|
||||||
Log.Error($"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
|
Log.Error($"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
|
||||||
return;
|
return;
|
||||||
|
|
@ -207,17 +206,15 @@ namespace Dalamud.Game.Network
|
||||||
|
|
||||||
var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);
|
var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);
|
||||||
|
|
||||||
if (request == null)
|
if (request == default)
|
||||||
{
|
{
|
||||||
Log.Error(
|
Log.Error($"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
|
||||||
$"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.ListingsRequestId != -1)
|
if (request.ListingsRequestId != -1)
|
||||||
{
|
{
|
||||||
Log.Error(
|
Log.Error($"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
|
||||||
$"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,6 +240,7 @@ namespace Dalamud.Game.Network
|
||||||
if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
|
if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
|
||||||
{
|
{
|
||||||
var category = (uint)Marshal.ReadInt32(dataPtr);
|
var category = (uint)Marshal.ReadInt32(dataPtr);
|
||||||
|
|
||||||
// Result dialog packet does not contain market tax rates
|
// Result dialog packet does not contain market tax rates
|
||||||
if (category != 720905)
|
if (category != 720905)
|
||||||
{
|
{
|
||||||
|
|
@ -279,9 +277,9 @@ namespace Dalamud.Game.Network
|
||||||
// Transaction succeeded
|
// Transaction succeeded
|
||||||
if (purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity
|
if (purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity
|
||||||
&& (purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId
|
&& (purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId
|
||||||
|| purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1000000))
|
|| purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1_000_000))
|
||||||
{ // HQ
|
{ // HQ
|
||||||
Log.Information("Bought " + purchase.ItemQuantity + "x " + this.marketBoardPurchaseHandler.CatalogId + " for " + (this.marketBoardPurchaseHandler.PricePerUnit * purchase.ItemQuantity) + " gils, listing id is " + this.marketBoardPurchaseHandler.ListingId);
|
Log.Verbose($"Bought {purchase.ItemQuantity}x {this.marketBoardPurchaseHandler.CatalogId} for {this.marketBoardPurchaseHandler.PricePerUnit * purchase.ItemQuantity} gils, listing id is {this.marketBoardPurchaseHandler.ListingId}");
|
||||||
var handler = this.marketBoardPurchaseHandler; // Capture the object so that we don't pass in a null one when the task starts.
|
var handler = this.marketBoardPurchaseHandler; // Capture the object so that we don't pass in a null one when the task starts.
|
||||||
Task.Run(() => this.uploader.UploadPurchase(handler));
|
Task.Run(() => this.uploader.UploadPurchase(handler));
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Dalamud.Game.Network.Structures;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.Network
|
|
||||||
{
|
|
||||||
internal class MarketBoardItemRequest
|
|
||||||
{
|
|
||||||
public uint CatalogId { get; set; }
|
|
||||||
|
|
||||||
public byte AmountToArrive { get; set; }
|
|
||||||
|
|
||||||
public List<MarketBoardCurrentOfferings.MarketBoardItemListing> Listings { get; set; }
|
|
||||||
|
|
||||||
public List<MarketBoardHistory.MarketBoardHistoryListing> History { get; set; }
|
|
||||||
|
|
||||||
public int ListingsRequestId { get; set; } = -1;
|
|
||||||
|
|
||||||
public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.Internal.Network
|
namespace Dalamud.Game.Network
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This represents the direction of a network message.
|
/// This represents the direction of a network message.
|
||||||
|
|
@ -5,14 +5,43 @@ using System.Text;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Structures
|
namespace Dalamud.Game.Network.Structures
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the current market board offerings from a game network packet.
|
||||||
|
/// </summary>
|
||||||
public class MarketBoardCurrentOfferings
|
public class MarketBoardCurrentOfferings
|
||||||
{
|
{
|
||||||
public List<MarketBoardItemListing> ItemListings;
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MarketBoardCurrentOfferings"/> class.
|
||||||
|
/// </summary>
|
||||||
|
internal MarketBoardCurrentOfferings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public int ListingIndexEnd;
|
/// <summary>
|
||||||
public int ListingIndexStart;
|
/// Gets the list of individual item listings.
|
||||||
public int RequestId;
|
/// </summary>
|
||||||
|
public List<MarketBoardItemListing> ItemListings { get; internal set; }
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// Read a <see cref="MarketBoardCurrentOfferings"/> object from memory.
|
||||||
|
/// </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(IntPtr dataPtr)
|
||||||
{
|
{
|
||||||
var output = new MarketBoardCurrentOfferings();
|
var output = new MarketBoardCurrentOfferings();
|
||||||
|
|
@ -80,32 +109,124 @@ namespace Dalamud.Game.Network.Structures
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the current market board offering of a single item from the <see cref="MarketBoardCurrentOfferings"/> network packet.
|
||||||
|
/// </summary>
|
||||||
public class MarketBoardItemListing
|
public class MarketBoardItemListing
|
||||||
{
|
{
|
||||||
public ulong ArtisanId;
|
/// <summary>
|
||||||
public uint CatalogId;
|
/// Initializes a new instance of the <see cref="MarketBoardItemListing"/> class.
|
||||||
public bool IsHq;
|
/// </summary>
|
||||||
public uint ItemQuantity;
|
internal MarketBoardItemListing()
|
||||||
public DateTime LastReviewTime;
|
{
|
||||||
public ulong ListingId;
|
}
|
||||||
|
|
||||||
public List<ItemMateria> Materia;
|
/// <summary>
|
||||||
public int MateriaCount;
|
/// Gets the artisan ID.
|
||||||
public bool OnMannequin;
|
/// </summary>
|
||||||
public string PlayerName;
|
public ulong ArtisanId { get; internal set; }
|
||||||
public uint PricePerUnit;
|
|
||||||
public int RetainerCityId;
|
|
||||||
public ulong RetainerId;
|
|
||||||
|
|
||||||
public string RetainerName;
|
/// <summary>
|
||||||
public ulong RetainerOwnerId;
|
/// Gets the catalog ID.
|
||||||
public int StainId;
|
/// </summary>
|
||||||
public uint TotalTax;
|
public uint CatalogId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the item is HQ.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsHq { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the item quantity.
|
||||||
|
/// </summary>
|
||||||
|
public uint ItemQuantity { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time this offering was last reviewed.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LastReviewTime { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the listing ID.
|
||||||
|
/// </summary>
|
||||||
|
public ulong ListingId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the list of materia attached to this item.
|
||||||
|
/// </summary>
|
||||||
|
public List<ItemMateria> Materia { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of attached materia.
|
||||||
|
/// </summary>
|
||||||
|
public int MateriaCount { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this item is on a mannequin.
|
||||||
|
/// </summary>
|
||||||
|
public bool OnMannequin { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the player name.
|
||||||
|
/// </summary>
|
||||||
|
public string PlayerName { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the price per unit.
|
||||||
|
/// </summary>
|
||||||
|
public uint PricePerUnit { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the city ID of the retainer selling the item.
|
||||||
|
/// </summary>
|
||||||
|
public int RetainerCityId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the retainer selling the item.
|
||||||
|
/// </summary>
|
||||||
|
public ulong RetainerId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the retainer.
|
||||||
|
/// </summary>
|
||||||
|
public string RetainerName { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the retainer's owner.
|
||||||
|
/// </summary>
|
||||||
|
public ulong RetainerOwnerId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stain or applied dye of the item.
|
||||||
|
/// </summary>
|
||||||
|
public int StainId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total tax.
|
||||||
|
/// </summary>
|
||||||
|
public uint TotalTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This represents the materia slotted to an <see cref="MarketBoardItemListing"/>.
|
||||||
|
/// </summary>
|
||||||
public class ItemMateria
|
public class ItemMateria
|
||||||
{
|
{
|
||||||
public int Index;
|
/// <summary>
|
||||||
public int MateriaId;
|
/// Initializes a new instance of the <see cref="ItemMateria"/> class.
|
||||||
|
/// </summary>
|
||||||
|
internal ItemMateria()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the materia index.
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the materia ID.
|
||||||
|
/// </summary>
|
||||||
|
public int MateriaId { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,38 @@ using System.Text;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Structures
|
namespace Dalamud.Game.Network.Structures
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the market board history from a game network packet.
|
||||||
|
/// </summary>
|
||||||
public class MarketBoardHistory
|
public class MarketBoardHistory
|
||||||
{
|
{
|
||||||
public uint CatalogId;
|
/// <summary>
|
||||||
public uint CatalogId2;
|
/// Initializes a new instance of the <see cref="MarketBoardHistory"/> class.
|
||||||
|
/// </summary>
|
||||||
|
internal MarketBoardHistory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public List<MarketBoardHistoryListing> HistoryListings;
|
/// <summary>
|
||||||
|
/// Gets the catalog ID.
|
||||||
|
/// </summary>
|
||||||
|
public uint CatalogId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the second catalog ID.
|
||||||
|
/// </summary>
|
||||||
|
public uint CatalogId2 { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the list of individual item history listings.
|
||||||
|
/// </summary>
|
||||||
|
public List<MarketBoardHistoryListing> HistoryListings { get; internal 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(IntPtr dataPtr)
|
||||||
{
|
{
|
||||||
var output = new MarketBoardHistory();
|
var output = new MarketBoardHistory();
|
||||||
|
|
@ -47,16 +72,52 @@ namespace Dalamud.Game.Network.Structures
|
||||||
return output;
|
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
|
public class MarketBoardHistoryListing
|
||||||
{
|
{
|
||||||
public string BuyerName;
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MarketBoardHistoryListing"/> class.
|
||||||
|
/// </summary>
|
||||||
|
internal MarketBoardHistoryListing()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public uint CatalogId;
|
/// <summary>
|
||||||
public bool IsHq;
|
/// Gets the buyer's name.
|
||||||
public bool OnMannequin;
|
/// </summary>
|
||||||
public DateTime PurchaseTime;
|
public string BuyerName { get; internal set; }
|
||||||
public uint Quantity;
|
|
||||||
public uint SalePrice;
|
/// <summary>
|
||||||
|
/// Gets the catalog ID.
|
||||||
|
/// </summary>
|
||||||
|
public uint CatalogId { 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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,53 @@ using System.IO;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Structures
|
namespace Dalamud.Game.Network.Structures
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the market tax rates from a game network packet.
|
||||||
|
/// </summary>
|
||||||
public class MarketTaxRates
|
public class MarketTaxRates
|
||||||
{
|
{
|
||||||
public uint LimsaLominsaTax;
|
/// <summary>
|
||||||
public uint GridaniaTax;
|
/// Initializes a new instance of the <see cref="MarketTaxRates"/> class.
|
||||||
public uint UldahTax;
|
/// </summary>
|
||||||
public uint IshgardTax;
|
internal MarketTaxRates()
|
||||||
public uint KuganeTax;
|
{
|
||||||
public uint CrystariumTax;
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in Limsa Lominsa.
|
||||||
|
/// </summary>
|
||||||
|
public uint LimsaLominsaTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in Gridania.
|
||||||
|
/// </summary>
|
||||||
|
public uint GridaniaTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in Ul'dah.
|
||||||
|
/// </summary>
|
||||||
|
public uint UldahTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in Ishgard.
|
||||||
|
/// </summary>
|
||||||
|
public uint IshgardTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in Kugane.
|
||||||
|
/// </summary>
|
||||||
|
public uint KuganeTax { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tax rate in the Crystarium.
|
||||||
|
/// </summary>
|
||||||
|
public uint CrystariumTax { get; internal 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(IntPtr dataPtr)
|
||||||
{
|
{
|
||||||
var output = new MarketTaxRates();
|
var output = new MarketTaxRates();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue