From fe27d8c46bfa387366079eae853542ed29f20313 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Sat, 18 Feb 2023 11:59:42 -0800 Subject: [PATCH 1/6] Add 0x4000_0002 Duty Completed Flytext Shown even to DutyState.cs --- Dalamud/Game/DutyState/DutyState.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Dalamud/Game/DutyState/DutyState.cs b/Dalamud/Game/DutyState/DutyState.cs index f828edad8..11eeff9f3 100644 --- a/Dalamud/Game/DutyState/DutyState.cs +++ b/Dalamud/Game/DutyState/DutyState.cs @@ -121,8 +121,15 @@ public unsafe class DutyState : IDisposable, IServiceType this.DutyRecommenced.InvokeSafely(this, this.clientState.TerritoryType); break; + // Duty Completed Flytext Shown + case 0x4000_0002 when !this.CompletedThisTerritory: + this.IsDutyStarted = false; + this.CompletedThisTerritory = true; + this.DutyCompleted.InvokeSafely(this, this.clientState.TerritoryType); + break; + // Duty Completed - case 0x4000_0003: + case 0x4000_0003 when !this.CompletedThisTerritory: this.IsDutyStarted = false; this.CompletedThisTerritory = true; this.DutyCompleted.InvokeSafely(this, this.clientState.TerritoryType); From 20b3a75fc65f44fb835684e3ff52c4f2247c1ca3 Mon Sep 17 00:00:00 2001 From: karashiiro <49822414+karashiiro@users.noreply.github.com> Date: Sun, 19 Feb 2023 08:12:23 -0800 Subject: [PATCH 2/6] fix(network): Ensure correct MB history packets are being bundled This injects the start packet into the history observable to use it for validating the item ID in the history packets. Also adds back some other validation as a safeguard. --- .../Game/Network/Internal/NetworkHandlers.cs | 81 ++++++++++++++----- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 9d552b519..ef8090d1c 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reactive.Linq; -using System.Reactive.Subjects; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -62,10 +62,7 @@ internal class NetworkHandlers : IDisposable, IServiceType } gameNetwork.NetworkMessage += Observe; - return () => - { - gameNetwork.NetworkMessage -= Observe; - }; + return () => { gameNetwork.NetworkMessage -= Observe; }; }); this.handleMarketBoardItemRequest = this.HandleMarketBoardItemRequest(); @@ -174,17 +171,8 @@ internal class NetworkHandlers : IDisposable, IServiceType private IObservable> OnMarketBoardListingsBatch( IObservable start) { - var startShared = start.Publish().RefCount(); var offeringsObservable = this.OnMarketBoardOfferings().Publish().RefCount(); - void LogStartObserved(MarketBoardItemRequest request) - { - Log.Verbose( - "Observed start of request for item#{CatalogId} with {NumListings} expected listings", - request.CatalogId, - request.AmountToArrive); - } - void LogEndObserved(MarketBoardCurrentOfferings offerings) { Log.Verbose( @@ -204,6 +192,7 @@ internal class NetworkHandlers : IDisposable, IServiceType { var totalPackets = Convert.ToInt32(Math.Ceiling((double)request.AmountToArrive / 10)); return offeringsObservable + .Where(offerings => offerings.ItemListings.All(l => l.CatalogId == request.CatalogId)) .Skip(totalPackets - 1) .Do(LogEndObserved); } @@ -213,7 +202,7 @@ internal class NetworkHandlers : IDisposable, IServiceType // packets, and then flatten them to the listings themselves. return offeringsObservable .Do(LogOfferingsObserved) - .Window(startShared.Where(request => request.Ok).Do(LogStartObserved), UntilBatchEnd) + .Window(start, UntilBatchEnd) .SelectMany( o => o.Aggregate( new List(), @@ -224,17 +213,59 @@ internal class NetworkHandlers : IDisposable, IServiceType })); } - private IObservable> OnMarketBoardSalesBatch() + private IObservable> OnMarketBoardSalesBatch( + IObservable start) { - return this.OnMarketBoardHistory().Select(history => history.HistoryListings); + var historyObservable = this.OnMarketBoardHistory().Publish().RefCount(); + + void LogHistoryObserved(MarketBoardHistory history) + { + Log.Verbose( + "Observed history for item {CatalogId} with {NumSales} sales", + history.CatalogId, + history.HistoryListings.Count); + } + + IObservable UntilBatchEnd(MarketBoardItemRequest request) + { + return historyObservable + .Where(history => history.CatalogId == request.CatalogId) + .Take(1); + } + + // When a start packet is observed, begin observing a window of history packets. + // We should only get one packet, which the window closing function ensures. + // This packet is flattened to its sale entries and emitted. + return historyObservable + .Do(LogHistoryObserved) + .Window(start, UntilBatchEnd) + .SelectMany( + o => o.Aggregate( + new List(), + (agg, next) => + { + agg.AddRange(next.HistoryListings); + return agg; + })); } private IDisposable HandleMarketBoardItemRequest() { - var startObservable = this.OnMarketBoardItemRequestStart(); + void LogStartObserved(MarketBoardItemRequest request) + { + Log.Verbose( + "Observed start of request for item#{CatalogId} with {NumListings} expected listings", + request.CatalogId, + request.AmountToArrive); + } + + var startObservable = this.OnMarketBoardItemRequestStart() + .Where(request => request.Ok).Do(LogStartObserved) + .Publish() + .RefCount(); return Observable.When( startObservable - .And(this.OnMarketBoardSalesBatch()) + .And(this.OnMarketBoardSalesBatch(startObservable)) .And(this.OnMarketBoardListingsBatch(startObservable)) .Then((request, sales, listings) => (request, sales, listings))) .Where(this.ShouldUpload) @@ -252,6 +283,18 @@ internal class NetworkHandlers : IDisposable, IServiceType ICollection sales, ICollection listings) { + if (listings.Count != request.AmountToArrive) + { + Log.Error("Wrong number of Market Board listings received for request: {ListingsCount} != {RequestAmountToArrive} item#{RequestCatalogId}", listings.Count, request.AmountToArrive, request.CatalogId); + return; + } + + if (listings.Any(listing => listing.CatalogId != request.CatalogId)) + { + Log.Error("Received listings with mismatched item IDs for item#{RequestCatalogId}", request.CatalogId); + return; + } + Log.Verbose( "Market Board request resolved, starting upload: item#{CatalogId} listings#{ListingsObserved} sales#{SalesObserved}", request.CatalogId, From a7ff558ed71d713a0ac4c2ab93dcefb56595611a Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Sun, 19 Feb 2023 19:06:17 +0100 Subject: [PATCH 3/6] build: 7.4.5.4 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index f23a3c06f..c24ff1a55 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 7.4.5.3 + 7.4.5.4 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion) From 3b891e9e8d327b205cefd83d4b06828f40d55204 Mon Sep 17 00:00:00 2001 From: karashiiro <49822414+karashiiro@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:16:33 -0800 Subject: [PATCH 4/6] feat: Run network callbacks on the ThreadPool --- Dalamud/Game/Network/Internal/NetworkHandlers.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index ef8090d1c..de323f0ba 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -269,6 +270,7 @@ internal class NetworkHandlers : IDisposable, IServiceType .And(this.OnMarketBoardListingsBatch(startObservable)) .Then((request, sales, listings) => (request, sales, listings))) .Where(this.ShouldUpload) + .SubscribeOn(ThreadPoolScheduler.Instance) .Subscribe( data => { @@ -314,6 +316,7 @@ internal class NetworkHandlers : IDisposable, IServiceType { return this.OnMarketTaxRates() .Where(this.ShouldUpload) + .SubscribeOn(ThreadPoolScheduler.Instance) .Subscribe( taxes => { @@ -340,6 +343,7 @@ internal class NetworkHandlers : IDisposable, IServiceType return this.OnMarketBoardPurchaseHandler() .Zip(this.OnMarketBoardPurchase()) .Where(this.ShouldUpload) + .SubscribeOn(ThreadPoolScheduler.Instance) .Subscribe( data => { @@ -370,6 +374,7 @@ internal class NetworkHandlers : IDisposable, IServiceType private unsafe IDisposable HandleCfPop() { return this.OnCfNotifyPop() + .SubscribeOn(ThreadPoolScheduler.Instance) .Subscribe( message => { From 0db156a468b0da79579bcdf4118323166ef71bd6 Mon Sep 17 00:00:00 2001 From: Aireil <33433913+Aireil@users.noreply.github.com> Date: Mon, 20 Feb 2023 18:20:50 +0100 Subject: [PATCH 5/6] fix: exceptions in stat window --- .../Internal/Windows/PluginStatWindow.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs index 21b32a68a..c83df2a4c 100644 --- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs @@ -160,7 +160,7 @@ internal class PluginStatWindow : Window var statsHistory = Framework.StatsHistory.ToArray(); var totalLast = statsHistory.Sum(stats => stats.Value.LastOrDefault()); - var totalAverage = statsHistory.Sum(stats => stats.Value.Average()); + var totalAverage = statsHistory.Sum(stats => stats.Value.DefaultIfEmpty().Average()); ImGuiComponents.TextWithLabel("Total Last", $"{totalLast:F4}ms", "All last update times added together"); ImGui.SameLine(); @@ -193,16 +193,21 @@ internal class PluginStatWindow : Window ? statsHistory.OrderBy(handler => handler.Key).ToArray() : statsHistory.OrderByDescending(handler => handler.Key).ToArray(), 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? statsHistory.OrderBy(handler => handler.Value.Max()).ToArray() - : statsHistory.OrderByDescending(handler => handler.Value.Max()).ToArray(), + ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Max()).ToArray() + : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Max()).ToArray(), 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? statsHistory.OrderBy(handler => handler.Value.Average()).ToArray() - : statsHistory.OrderByDescending(handler => handler.Value.Average()).ToArray(), + ? statsHistory.OrderBy(handler => handler.Value.DefaultIfEmpty().Average()).ToArray() + : statsHistory.OrderByDescending(handler => handler.Value.DefaultIfEmpty().Average()).ToArray(), _ => statsHistory, }; foreach (var handlerHistory in statsHistory) { + if (!handlerHistory.Value.Any()) + { + continue; + } + ImGui.TableNextRow(); ImGui.TableNextColumn(); From dd3ae16d026aa34fc2ed21fcee9ae02c50bd1491 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Mon, 20 Feb 2023 18:41:53 +0100 Subject: [PATCH 6/6] build: 7.4.5.5 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index c24ff1a55..11d69b829 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 7.4.5.4 + 7.4.5.5 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion)