From 321f39dc55c5f458716a7946b22a28ed0a48bf82 Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 11:56:39 -0500 Subject: [PATCH 1/7] Reuse httpclient, create in Util --- .../IMarketBoardUploader.cs | 11 +++++--- .../UniversalisMarketBoardUploader.cs | 25 +++++++++---------- .../Internal/Windows/PluginImageCache.cs | 6 ++--- Dalamud/Plugin/Internal/PluginManager.cs | 3 +-- Dalamud/Plugin/Internal/PluginRepository.cs | 4 +-- Dalamud/Support/BugBait.cs | 6 ++--- Dalamud/Utility/Util.cs | 7 ++++++ 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs index a867261f2..6ec2a997b 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs @@ -1,3 +1,5 @@ +using System.Threading.Tasks; + using Dalamud.Game.Network.Structures; namespace Dalamud.Game.Network.Internal.MarketBoardUploaders @@ -11,18 +13,21 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders /// Upload data about an item. /// /// The item request data being uploaded. - void Upload(MarketBoardItemRequest item); + /// An async task. + Task Upload(MarketBoardItemRequest item); /// /// Upload tax rate data. /// /// The tax rate data being uploaded. - void UploadTax(MarketTaxRates taxRates); + /// An async task. + Task UploadTax(MarketTaxRates taxRates); /// /// Upload information about a purchase this client has made. /// /// The purchase handler data associated with the sale. - void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler); + /// An async task. + Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler); } } diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs index 104faef36..17727dff9 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Net.Http.Headers; using System.Text; +using System.Threading.Tasks; using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types; using Dalamud.Game.Network.Structures; +using Dalamud.Utility; using Newtonsoft.Json; using Serilog; @@ -29,10 +30,9 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis } /// - public void Upload(MarketBoardItemRequest request) + public async Task Upload(MarketBoardItemRequest request) { var clientState = Service.Get(); - using var client = new HttpClient(); Log.Verbose("Starting Universalis upload."); var uploader = clientState.LocalContentId; @@ -80,7 +80,7 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis var listingPath = "/upload"; var listingUpload = JsonConvert.SerializeObject(listingsUploadObject); Log.Verbose($"{listingPath}: {listingUpload}"); - client.PostAsync($"{ApiBase}{listingPath}/{ApiKey}", new StringContent(listingUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); + await Util.HttpClient.PostAsync($"{ApiBase}{listingPath}/{ApiKey}", new StringContent(listingUpload, Encoding.UTF8, "application/json")); // ==================================================================================== @@ -108,7 +108,7 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis 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(); + await Util.HttpClient.PostAsync($"{ApiBase}{historyPath}/{ApiKey}", new StringContent(historyUpload, Encoding.UTF8, "application/json")); // ==================================================================================== @@ -116,10 +116,9 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis } /// - public void UploadTax(MarketTaxRates taxRates) + public async Task UploadTax(MarketTaxRates taxRates) { var clientState = Service.Get(); - using var client = new HttpClient(); // ==================================================================================== @@ -142,7 +141,7 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis var taxUpload = JsonConvert.SerializeObject(taxUploadObject); Log.Verbose($"{taxPath}: {taxUpload}"); - client.PostAsync($"{ApiBase}{taxPath}/{ApiKey}", new StringContent(taxUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); + await Util.HttpClient.PostAsync($"{ApiBase}{taxPath}/{ApiKey}", new StringContent(taxUpload, Encoding.UTF8, "application/json")); // ==================================================================================== @@ -155,12 +154,9 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis /// 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 void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler) + public async Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler) { var clientState = Service.Get(); - using var client = new HttpClient(); - - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(ApiKey); var itemId = purchaseHandler.CatalogId; var worldId = clientState.LocalPlayer?.CurrentWorld.Id ?? 0; @@ -180,7 +176,10 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis var deleteListing = JsonConvert.SerializeObject(deleteListingObject); Log.Verbose($"{deletePath}: {deleteListing}"); - client.PostAsync($"{ApiBase}{deletePath}", new StringContent(deleteListing, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); + var content = new StringContent(deleteListing, Encoding.UTF8, "application/json"); + content.Headers.Add("Authorization", ApiKey); + + await Util.HttpClient.PostAsync($"{ApiBase}{deletePath}", content); // ==================================================================================== diff --git a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs index 435d30e30..6313a1c43 100644 --- a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs +++ b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs @@ -44,8 +44,6 @@ namespace Dalamud.Interface.Internal.Windows // TODO: Change back to master after release private const string MainRepoImageUrl = "https://raw.githubusercontent.com/goatcorp/DalamudPlugins/api4/{0}/{1}/images/{2}"; - private readonly HttpClient httpClient = new(); - private BlockingCollection> downloadQueue = new(); private CancellationTokenSource downloadToken = new(); @@ -264,7 +262,7 @@ namespace Dalamud.Interface.Internal.Windows HttpResponseMessage data; try { - data = await this.httpClient.GetAsync(url); + data = await Util.HttpClient.GetAsync(url); } catch (InvalidOperationException) { @@ -381,7 +379,7 @@ namespace Dalamud.Interface.Internal.Windows HttpResponseMessage data; try { - data = await this.httpClient.GetAsync(url); + data = await Util.HttpClient.GetAsync(url); } catch (InvalidOperationException) { diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 532a0af2b..4eb06abaf 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -409,8 +409,7 @@ namespace Dalamud.Plugin.Internal var downloadUrl = useTesting ? repoManifest.DownloadLinkTesting : repoManifest.DownloadLinkInstall; var version = useTesting ? repoManifest.TestingAssemblyVersion : repoManifest.AssemblyVersion; - using var client = new HttpClient(); - var response = await client.GetAsync(downloadUrl); + var response = await Util.HttpClient.GetAsync(downloadUrl); response.EnsureSuccessStatusCode(); var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory.FullName, repoManifest.InternalName, version.ToString())); diff --git a/Dalamud/Plugin/Internal/PluginRepository.cs b/Dalamud/Plugin/Internal/PluginRepository.cs index cf579dce6..3e4e93fb2 100644 --- a/Dalamud/Plugin/Internal/PluginRepository.cs +++ b/Dalamud/Plugin/Internal/PluginRepository.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal.Types; +using Dalamud.Utility; using Newtonsoft.Json; namespace Dalamud.Plugin.Internal @@ -74,10 +75,9 @@ namespace Dalamud.Plugin.Internal try { Log.Information($"Fetching repo: {this.PluginMasterUrl}"); - using var client = new HttpClient(); // ?ticks causes a cache invalidation. Get a fresh repo every time. - using var response = await client.GetAsync(this.PluginMasterUrl + "?" + DateTime.Now.Ticks); + using var response = await Util.HttpClient.GetAsync(this.PluginMasterUrl + "?" + DateTime.Now.Ticks); response.EnsureSuccessStatusCode(); var data = await response.Content.ReadAsStringAsync(); diff --git a/Dalamud/Support/BugBait.cs b/Dalamud/Support/BugBait.cs index f72ea9945..9c5db6514 100644 --- a/Dalamud/Support/BugBait.cs +++ b/Dalamud/Support/BugBait.cs @@ -1,4 +1,4 @@ -using System.Net.Http; +using System.Net.Http; using System.Text; using System.Threading.Tasks; @@ -28,8 +28,6 @@ namespace Dalamud.Support if (content.IsNullOrWhitespace()) return; - using var client = new HttpClient(); - var model = new FeedbackModel { Content = content, @@ -45,7 +43,7 @@ namespace Dalamud.Support } var postContent = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"); - var response = await client.PostAsync(BugBaitUrl, postContent); + var response = await Util.HttpClient.PostAsync(BugBaitUrl, postContent); response.EnsureSuccessStatusCode(); } diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index a16eeb40b..b40a097a2 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; +using System.Net.Http; using System.Reflection; using System.Text; @@ -23,6 +24,12 @@ namespace Dalamud.Utility { private static string gitHashInternal; + /// + /// Gets an httpclient for usage. + /// Do NOT await this. + /// + public static HttpClient HttpClient { get; } = new(); + /// /// Gets the assembly version of Dalamud. /// From 6d9f7584d64bd71881e5868b82da01cf1f015da4 Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 11:56:54 -0500 Subject: [PATCH 2/7] Cleanup util --- Dalamud/Utility/Util.cs | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index b40a097a2..8a39b7aea 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -216,7 +216,7 @@ namespace Dalamud.Utility } /// - /// Compress a string using GZip. + /// Compress a string using GZip. /// /// The input string. /// The compressed output bytes. @@ -224,35 +224,29 @@ namespace Dalamud.Utility { var bytes = Encoding.UTF8.GetBytes(str); - using (var msi = new MemoryStream(bytes)) - using (var mso = new MemoryStream()) - { - using (var gs = new GZipStream(mso, CompressionMode.Compress)) - { - CopyTo(msi, gs); - } + using var msi = new MemoryStream(bytes); + using var mso = new MemoryStream(); + using var gs = new GZipStream(mso, CompressionMode.Compress); - return mso.ToArray(); - } + CopyTo(msi, gs); + + return mso.ToArray(); } /// - /// Decompress a string using GZip. + /// Decompress a string using GZip. /// /// The input bytes. /// The compressed output string. public static string DecompressString(byte[] bytes) { - using (var msi = new MemoryStream(bytes)) - using (var mso = new MemoryStream()) - { - using (var gs = new GZipStream(msi, CompressionMode.Decompress)) - { - CopyTo(gs, mso); - } + using var msi = new MemoryStream(bytes); + using var mso = new MemoryStream(); + using var gs = new GZipStream(msi, CompressionMode.Decompress); - return Encoding.UTF8.GetString(mso.ToArray()); - } + CopyTo(gs, mso); + + return Encoding.UTF8.GetString(mso.ToArray()); } /// @@ -269,9 +263,6 @@ namespace Dalamud.Utility while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) dest.Write(bytes, 0, cnt); } - // TODO: Someone implement GetUTF8String with some IntPtr overloads. - // while(Marshal.ReadByte(0, sz) != 0) { sz++; } - /// /// Heuristically determine if Dalamud is running on Linux/WINE. /// From 45520657fca3d57e5ed1bc85071e89f327629f81 Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 20:23:42 -0500 Subject: [PATCH 3/7] HandleCfPop --- .../Game/Network/Internal/NetworkHandlers.cs | 103 ++++++++++-------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 586c602f4..46b276f38 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -69,53 +69,7 @@ namespace Dalamud.Game.Network.Internal if (opCode == dataManager.ServerOpCodes["CfNotifyPop"]) { - var data = new byte[64]; - Marshal.Copy(dataPtr, data, 0, 64); - - var notifyType = data[0]; - var contentFinderConditionId = BitConverter.ToUInt16(data, 0x14); - - if (notifyType != 3) - return; - - var contentFinderCondition = dataManager.GetExcelSheet().GetRow(contentFinderConditionId); - - if (contentFinderCondition == null) - { - Log.Error("CFC key {0} not in lumina data.", contentFinderConditionId); - return; - } - - var cfcName = contentFinderCondition.Name.ToString(); - if (string.IsNullOrEmpty(contentFinderCondition.Name)) - { - cfcName = "Duty Roulette"; - contentFinderCondition.Image = 112324; - } - - if (configuration.DutyFinderTaskbarFlash && !NativeFunctions.ApplicationIsActivated()) - { - var flashInfo = new NativeFunctions.FlashWindowInfo - { - Size = (uint)Marshal.SizeOf(), - Count = uint.MaxValue, - Timeout = 0, - Flags = NativeFunctions.FlashWindow.All | NativeFunctions.FlashWindow.TimerNoFG, - Hwnd = Process.GetCurrentProcess().MainWindowHandle, - }; - NativeFunctions.FlashWindowEx(ref flashInfo); - } - - Task.Run(() => - { - if (configuration.DutyFinderChatMessage) - { - Service.Get().Print("Duty pop: " + cfcName); - } - - this.CfPop?.Invoke(this, contentFinderCondition); - }); - + this.HandleCfPop(dataPtr); return; } @@ -289,8 +243,61 @@ namespace Dalamud.Game.Network.Internal } this.marketBoardPurchaseHandler = null; - } + + private unsafe void HandleCfPop(IntPtr dataPtr) + { + var dataManager = Service.Get(); + var configuration = Service.Get(); + + using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 64); + using var reader = new BinaryReader(stream); + + var notifyType = reader.ReadByte(); + stream.Position += 0x13; + var conditionId = reader.ReadUInt16(); + + if (notifyType != 3) + return; + + var cfConditionSheet = dataManager.GetExcelSheet()!; + var cfCondition = cfConditionSheet.GetRow(conditionId); + + if (cfCondition == null) + { + Log.Error($"CFC key {conditionId} not in Lumina data."); + return; } + + var cfcName = cfCondition.Name.ToString(); + if (cfcName.IsNullOrEmpty()) + { + cfcName = "Duty Roulette"; + cfCondition.Image = 112324; + } + + // Flash window + if (configuration.DutyFinderTaskbarFlash && !NativeFunctions.ApplicationIsActivated()) + { + var flashInfo = new NativeFunctions.FlashWindowInfo + { + Size = (uint)Marshal.SizeOf(), + Count = uint.MaxValue, + Timeout = 0, + Flags = NativeFunctions.FlashWindow.All | NativeFunctions.FlashWindow.TimerNoFG, + Hwnd = Process.GetCurrentProcess().MainWindowHandle, + }; + NativeFunctions.FlashWindowEx(ref flashInfo); + } + + Task.Run(() => + { + if (configuration.DutyFinderChatMessage) + { + Service.Get().Print($"Duty pop: {cfcName}"); + } + + this.CfPop?.Invoke(this, cfCondition); + }).ContinueWith((task) => Log.Error(task.Exception, "CfPop.Invoke failed."), TaskContinuationOptions.OnlyOnFaulted); } } } From 6c1b50174ac6b99744216280150590ad41408d20 Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 20:24:07 -0500 Subject: [PATCH 4/7] Pull MBStart into a read method --- .../Game/Network/Internal/NetworkHandlers.cs | 14 +++--------- .../Structures/MarketBoardCurrentOfferings.cs | 22 +++++++------------ 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 46b276f38..5dfda2a8b 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -77,18 +77,10 @@ namespace Dalamud.Game.Network.Internal { if (opCode == dataManager.ServerOpCodes["MarketBoardItemRequestStart"]) { - var catalogId = (uint)Marshal.ReadInt32(dataPtr); - var amount = Marshal.ReadByte(dataPtr + 0xB); + var data = MarketBoardItemRequest.Read(dataPtr); + this.marketBoardRequests.Add(data); - this.marketBoardRequests.Add(new MarketBoardItemRequest - { - CatalogId = catalogId, - AmountToArrive = amount, - Listings = new List(), - History = new List(), - }); - - Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}"); + Log.Verbose($"NEW MB REQUEST START: item#{data.CatalogId} amount#{data.AmountToArrive}"); return; } diff --git a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs index ad19f48c5..364a21454 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs @@ -10,17 +10,14 @@ namespace Dalamud.Game.Network.Structures /// public class MarketBoardCurrentOfferings { - /// - /// Initializes a new instance of the class. - /// - internal MarketBoardCurrentOfferings() + private MarketBoardCurrentOfferings() { } /// /// Gets the list of individual item listings. /// - public List ItemListings { get; internal set; } + public List ItemListings { get; } = new(); /// /// Gets the listing end index. @@ -49,8 +46,6 @@ namespace Dalamud.Game.Network.Structures using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544); using var reader = new BinaryReader(stream); - output.ItemListings = new List(); - for (var i = 0; i < 10; i++) { var listingEntry = new MarketBoardItemListing(); @@ -70,15 +65,14 @@ namespace Dalamud.Game.Network.Structures reader.ReadUInt16(); // durability reader.ReadUInt16(); // spiritbond - listingEntry.Materia = new List(); - for (var materiaIndex = 0; materiaIndex < 5; materiaIndex++) { var materiaVal = reader.ReadUInt16(); - - var materiaEntry = new MarketBoardItemListing.ItemMateria(); - materiaEntry.MateriaId = (materiaVal & 0xFF0) >> 4; - materiaEntry.Index = materiaVal & 0xF; + var materiaEntry = new MarketBoardItemListing.ItemMateria() + { + MateriaId = (materiaVal & 0xFF0) >> 4, + Index = materiaVal & 0xF, + }; if (materiaEntry.MateriaId != 0) listingEntry.Materia.Add(materiaEntry); @@ -154,7 +148,7 @@ namespace Dalamud.Game.Network.Structures /// /// Gets the list of materia attached to this item. /// - public List Materia { get; internal set; } + public List Materia { get; } = new(); /// /// Gets the amount of attached materia. From 042558aa5e6fe68322ba59919e425b569bcc2539 Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 20:24:36 -0500 Subject: [PATCH 5/7] Cleanup, log with continuation tasks --- .../Game/Network/Internal/NetworkHandlers.cs | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 5dfda2a8b..4d7b7145e 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -11,6 +12,7 @@ using Dalamud.Game.Gui; using Dalamud.Game.Network.Internal.MarketBoardUploaders; using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis; using Dalamud.Game.Network.Structures; +using Dalamud.Utility; using Lumina.Excel.GeneratedSheets; using Serilog; @@ -58,9 +60,10 @@ namespace Dalamud.Game.Network.Internal { if (!this.optOutMbUploads) { - if (opCode == Service.Get().ClientOpCodes["MarketBoardPurchaseHandler"]) + if (opCode == dataManager.ClientOpCodes["MarketBoardPurchaseHandler"]) { this.marketBoardPurchaseHandler = MarketBoardPurchaseHandler.Read(dataPtr); + return; } } @@ -137,14 +140,9 @@ namespace Dalamud.Game.Network.Internal request.ListingsRequestId, request.CatalogId, request.AmountToArrive); - try - { - Task.Run(() => this.uploader.Upload(request)); - } - catch (Exception ex) - { - Log.Error(ex, "Market Board data upload failed."); - } + + Task.Run(() => this.uploader.Upload(request)) + .ContinueWith((task) => Log.Error(task.Exception, "Market Board offerings data upload failed."), TaskContinuationOptions.OnlyOnFaulted); } return; @@ -176,14 +174,8 @@ namespace Dalamud.Game.Network.Internal { Log.Verbose("Request had 0 amount, uploading now"); - try - { - Task.Run(() => this.uploader.Upload(request)); - } - catch (Exception ex) - { - Log.Error(ex, "Market Board data upload failed."); - } + Task.Run(() => this.uploader.Upload(request)) + .ContinueWith((task) => Log.Error(task.Exception, "Market Board history data upload failed."), TaskContinuationOptions.OnlyOnFaulted); } } @@ -207,14 +199,11 @@ namespace Dalamud.Game.Network.Internal taxes.IshgardTax, taxes.KuganeTax, taxes.CrystariumTax); - try - { - Task.Run(() => this.uploader.UploadTax(taxes)); - } - catch (Exception ex) - { - Log.Error(ex, "Market Board data upload failed."); - } + + Task.Run(() => this.uploader.UploadTax(taxes)) + .ContinueWith((task) => Log.Error(task.Exception, "Market Board tax data upload failed."), TaskContinuationOptions.OnlyOnFaulted); + + return; } if (opCode == dataManager.ServerOpCodes["MarketBoardPurchase"]) @@ -224,17 +213,26 @@ namespace Dalamud.Game.Network.Internal var purchase = MarketBoardPurchase.Read(dataPtr); + var sameQty = purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity; + var itemMatch = purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId; + var itemMatchHq = purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1_000_000; + // Transaction succeeded - if (purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity - && (purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId - || purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1_000_000)) - { // HQ + if (sameQty && (itemMatch || itemMatchHq)) + { 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. - Task.Run(() => this.uploader.UploadPurchase(handler)); + + Task.Run(() => this.uploader.UploadPurchase(handler)) + .ContinueWith((task) => Log.Error(task.Exception, "Market Board purchase data upload failed."), TaskContinuationOptions.OnlyOnFaulted); } this.marketBoardPurchaseHandler = null; + return; + } + } + } private unsafe void HandleCfPop(IntPtr dataPtr) { From d180ed005caaf333acf99906daacd55b442abb1e Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 20:25:20 -0500 Subject: [PATCH 6/7] More marketboard work, fix 10 instead of 20 history items --- .../MarketBoardItemRequest.cs | 45 ++++++++++++++----- .../Network/Structures/MarketBoardHistory.cs | 26 +++++------ .../Network/Structures/MarketBoardPurchase.cs | 9 +++- .../Structures/MarketBoardPurchaseHandler.cs | 9 +++- .../Game/Network/Structures/MarketTaxRates.cs | 22 ++++----- 5 files changed, 71 insertions(+), 40 deletions(-) diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs index 63d51f0e1..bdd07a8af 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.IO; using Dalamud.Game.Network.Structures; @@ -9,25 +11,29 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders /// internal class MarketBoardItemRequest { - /// - /// Gets or sets the catalog ID. - /// - public uint CatalogId { get; set; } + private MarketBoardItemRequest() + { + } /// - /// Gets or sets the amount to arrive. + /// Gets the catalog ID. /// - public byte AmountToArrive { get; set; } + public uint CatalogId { get; private set; } /// - /// Gets or sets the offered item listings. + /// Gets the amount to arrive. /// - public List Listings { get; set; } + public byte AmountToArrive { get; private set; } /// - /// Gets or sets the historical item listings. + /// Gets the offered item listings. /// - public List History { get; set; } + public List Listings { get; } = new(); + + /// + /// Gets the historical item listings. + /// + public List History { get; } = new(); /// /// Gets or sets the listing request ID. @@ -38,5 +44,24 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders /// Gets a value indicating whether the upload is complete. /// public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0; + + /// + /// Read a packet off the wire. + /// + /// Packet data. + /// An object representing the data read. + public static unsafe MarketBoardItemRequest Read(IntPtr dataPtr) + { + using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544); + using var reader = new BinaryReader(stream); + + var output = new MarketBoardItemRequest(); + + output.CatalogId = reader.ReadUInt32(); + stream.Position += 0x7; + output.AmountToArrive = reader.ReadByte(); + + return output; + } } } diff --git a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs index c73529da3..d753b0498 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs @@ -20,17 +20,17 @@ namespace Dalamud.Game.Network.Structures /// /// Gets the catalog ID. /// - public uint CatalogId { get; internal set; } + public uint CatalogId { get; private set; } /// /// Gets the second catalog ID. /// - public uint CatalogId2 { get; internal set; } + public uint CatalogId2 { get; private set; } /// /// Gets the list of individual item history listings. /// - public List HistoryListings { get; internal set; } + public List HistoryListings { get; } = new(); /// /// Read a object from memory. @@ -39,17 +39,15 @@ namespace Dalamud.Game.Network.Structures /// A new object. public static unsafe MarketBoardHistory Read(IntPtr dataPtr) { - var output = new MarketBoardHistory(); - using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544); using var reader = new BinaryReader(stream); + var output = new MarketBoardHistory(); + output.CatalogId = reader.ReadUInt32(); output.CatalogId2 = reader.ReadUInt32(); - output.HistoryListings = new List(); - - for (var i = 0; i < 10; i++) + for (var i = 0; i < 20; i++) { var listingEntry = new MarketBoardHistoryListing { @@ -63,10 +61,12 @@ namespace Dalamud.Game.Network.Structures listingEntry.OnMannequin = reader.ReadBoolean(); listingEntry.BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(33)).TrimEnd('\u0000'); - listingEntry.CatalogId = reader.ReadUInt32(); + listingEntry.NextCatalogId = reader.ReadUInt32(); - if (listingEntry.CatalogId != 0) - output.HistoryListings.Add(listingEntry); + output.HistoryListings.Add(listingEntry); + + if (listingEntry.NextCatalogId == 0) + break; } return output; @@ -90,9 +90,9 @@ namespace Dalamud.Game.Network.Structures public string BuyerName { get; internal set; } /// - /// Gets the catalog ID. + /// Gets the next entry's catalog ID. /// - public uint CatalogId { get; internal set; } + public uint NextCatalogId { get; internal set; } /// /// Gets a value indicating whether the item is HQ. diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs index ed8051154..5fc0de786 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs @@ -9,6 +9,10 @@ namespace Dalamud.Game.Network.Structures /// internal class MarketBoardPurchase { + private MarketBoardPurchase() + { + } + /// /// Gets the item ID of the item that was purchased. /// @@ -26,10 +30,11 @@ namespace Dalamud.Game.Network.Structures /// 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); + + var output = new MarketBoardPurchase(); + output.CatalogId = reader.ReadUInt32(); stream.Position += 4; output.ItemQuantity = reader.ReadUInt32(); diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs index 98d7007b0..0557b0e0d 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs @@ -9,6 +9,10 @@ namespace Dalamud.Game.Network.Structures /// internal class MarketBoardPurchaseHandler { + private MarketBoardPurchaseHandler() + { + } + /// /// Gets the object ID of the retainer associated with the sale. /// @@ -41,10 +45,11 @@ namespace Dalamud.Game.Network.Structures /// 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); + + var output = new MarketBoardPurchaseHandler(); + output.RetainerId = reader.ReadUInt64(); output.ListingId = reader.ReadUInt64(); output.CatalogId = reader.ReadUInt32(); diff --git a/Dalamud/Game/Network/Structures/MarketTaxRates.cs b/Dalamud/Game/Network/Structures/MarketTaxRates.cs index 5b27b9415..4fb6a2b13 100644 --- a/Dalamud/Game/Network/Structures/MarketTaxRates.cs +++ b/Dalamud/Game/Network/Structures/MarketTaxRates.cs @@ -8,42 +8,39 @@ namespace Dalamud.Game.Network.Structures /// public class MarketTaxRates { - /// - /// Initializes a new instance of the class. - /// - internal MarketTaxRates() + private MarketTaxRates() { } /// /// Gets the tax rate in Limsa Lominsa. /// - public uint LimsaLominsaTax { get; internal set; } + public uint LimsaLominsaTax { get; private set; } /// /// Gets the tax rate in Gridania. /// - public uint GridaniaTax { get; internal set; } + public uint GridaniaTax { get; private set; } /// /// Gets the tax rate in Ul'dah. /// - public uint UldahTax { get; internal set; } + public uint UldahTax { get; private set; } /// /// Gets the tax rate in Ishgard. /// - public uint IshgardTax { get; internal set; } + public uint IshgardTax { get; private set; } /// /// Gets the tax rate in Kugane. /// - public uint KuganeTax { get; internal set; } + public uint KuganeTax { get; private set; } /// /// Gets the tax rate in the Crystarium. /// - public uint CrystariumTax { get; internal set; } + public uint CrystariumTax { get; private set; } /// /// Read a object from memory. @@ -52,13 +49,12 @@ namespace Dalamud.Game.Network.Structures /// A new object. public static unsafe MarketTaxRates Read(IntPtr dataPtr) { - var output = new MarketTaxRates(); - using var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544); using var reader = new BinaryReader(stream); - stream.Position += 8; + var output = new MarketTaxRates(); + stream.Position += 8; output.LimsaLominsaTax = reader.ReadUInt32(); output.GridaniaTax = reader.ReadUInt32(); output.UldahTax = reader.ReadUInt32(); From 9b47cd327a71f6c75f7df4d5c5609e1714ef4afa Mon Sep 17 00:00:00 2001 From: Raymond Date: Wed, 10 Nov 2021 20:37:38 -0500 Subject: [PATCH 7/7] Fix delete path with auth header --- .../Universalis/UniversalisMarketBoardUploader.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs index 17727dff9..998502739 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs @@ -177,9 +177,11 @@ namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis Log.Verbose($"{deletePath}: {deleteListing}"); var content = new StringContent(deleteListing, Encoding.UTF8, "application/json"); - content.Headers.Add("Authorization", ApiKey); + var message = new HttpRequestMessage(HttpMethod.Post, $"{ApiBase}{deletePath}"); + message.Headers.Add("Authorization", ApiKey); + message.Content = content; - await Util.HttpClient.PostAsync($"{ApiBase}{deletePath}", content); + await Util.HttpClient.SendAsync(message); // ====================================================================================