Merge pull request #680 from daemitus/http

This commit is contained in:
goaaats 2021-11-11 03:04:14 +01:00 committed by GitHub
commit 4cff810d1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 214 additions and 193 deletions

View file

@ -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.
/// </summary>
/// <param name="item">The item request data being uploaded.</param>
void Upload(MarketBoardItemRequest item);
/// <returns>An async task.</returns>
Task Upload(MarketBoardItemRequest item);
/// <summary>
/// Upload tax rate data.
/// </summary>
/// <param name="taxRates">The tax rate data being uploaded.</param>
void UploadTax(MarketTaxRates taxRates);
/// <returns>An async task.</returns>
Task UploadTax(MarketTaxRates taxRates);
/// <summary>
/// Upload information about a purchase this client has made.
/// </summary>
/// <param name="purchaseHandler">The purchase handler data associated with the sale.</param>
void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler);
/// <returns>An async task.</returns>
Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler);
}
}

View file

@ -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
/// </summary>
internal class MarketBoardItemRequest
{
/// <summary>
/// Gets or sets the catalog ID.
/// </summary>
public uint CatalogId { get; set; }
private MarketBoardItemRequest()
{
}
/// <summary>
/// Gets or sets the amount to arrive.
/// Gets the catalog ID.
/// </summary>
public byte AmountToArrive { get; set; }
public uint CatalogId { get; private set; }
/// <summary>
/// Gets or sets the offered item listings.
/// Gets the amount to arrive.
/// </summary>
public List<MarketBoardCurrentOfferings.MarketBoardItemListing> Listings { get; set; }
public byte AmountToArrive { get; private set; }
/// <summary>
/// Gets or sets the historical item listings.
/// Gets the offered item listings.
/// </summary>
public List<MarketBoardHistory.MarketBoardHistoryListing> History { get; set; }
public List<MarketBoardCurrentOfferings.MarketBoardItemListing> Listings { get; } = new();
/// <summary>
/// Gets the historical item listings.
/// </summary>
public List<MarketBoardHistory.MarketBoardHistoryListing> History { get; } = new();
/// <summary>
/// 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.
/// </summary>
public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0;
/// <summary>
/// Read a packet off the wire.
/// </summary>
/// <param name="dataPtr">Packet data.</param>
/// <returns>An object representing the data read.</returns>
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;
}
}
}

View file

@ -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
}
/// <inheritdoc/>
public void Upload(MarketBoardItemRequest request)
public async Task Upload(MarketBoardItemRequest request)
{
var clientState = Service<ClientState.ClientState>.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
}
/// <inheritdoc/>
public void UploadTax(MarketTaxRates taxRates)
public async Task UploadTax(MarketTaxRates taxRates)
{
var clientState = Service<ClientState.ClientState>.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.
/// </remarks>
public void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler)
public async Task UploadPurchase(MarketBoardPurchaseHandler purchaseHandler)
{
var clientState = Service<ClientState.ClientState>.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,12 @@ 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");
var message = new HttpRequestMessage(HttpMethod.Post, $"{ApiBase}{deletePath}");
message.Headers.Add("Authorization", ApiKey);
message.Content = content;
await Util.HttpClient.SendAsync(message);
// ====================================================================================

View file

@ -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<DataManager>.Get().ClientOpCodes["MarketBoardPurchaseHandler"])
if (opCode == dataManager.ClientOpCodes["MarketBoardPurchaseHandler"])
{
this.marketBoardPurchaseHandler = MarketBoardPurchaseHandler.Read(dataPtr);
return;
}
}
@ -69,53 +72,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<ContentFinderCondition>().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<NativeFunctions.FlashWindowInfo>(),
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<ChatGui>.Get().Print("Duty pop: " + cfcName);
}
this.CfPop?.Invoke(this, contentFinderCondition);
});
this.HandleCfPop(dataPtr);
return;
}
@ -123,18 +80,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<MarketBoardCurrentOfferings.MarketBoardItemListing>(),
History = new List<MarketBoardHistory.MarketBoardHistoryListing>(),
});
Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
Log.Verbose($"NEW MB REQUEST START: item#{data.CatalogId} amount#{data.AmountToArrive}");
return;
}
@ -191,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;
@ -230,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);
}
}
@ -261,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"])
@ -278,19 +213,81 @@ 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)
{
var dataManager = Service<DataManager>.Get();
var configuration = Service<DalamudConfiguration>.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<ContentFinderCondition>()!;
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<NativeFunctions.FlashWindowInfo>(),
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<ChatGui>.Get().Print($"Duty pop: {cfcName}");
}
this.CfPop?.Invoke(this, cfCondition);
}).ContinueWith((task) => Log.Error(task.Exception, "CfPop.Invoke failed."), TaskContinuationOptions.OnlyOnFaulted);
}
}
}

View file

@ -10,17 +10,14 @@ namespace Dalamud.Game.Network.Structures
/// </summary>
public class MarketBoardCurrentOfferings
{
/// <summary>
/// Initializes a new instance of the <see cref="MarketBoardCurrentOfferings"/> class.
/// </summary>
internal MarketBoardCurrentOfferings()
private MarketBoardCurrentOfferings()
{
}
/// <summary>
/// Gets the list of individual item listings.
/// </summary>
public List<MarketBoardItemListing> ItemListings { get; internal set; }
public List<MarketBoardItemListing> ItemListings { get; } = new();
/// <summary>
/// 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<MarketBoardItemListing>();
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<MarketBoardItemListing.ItemMateria>();
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
/// <summary>
/// Gets the list of materia attached to this item.
/// </summary>
public List<ItemMateria> Materia { get; internal set; }
public List<ItemMateria> Materia { get; } = new();
/// <summary>
/// Gets the amount of attached materia.

View file

@ -20,17 +20,17 @@ namespace Dalamud.Game.Network.Structures
/// <summary>
/// Gets the catalog ID.
/// </summary>
public uint CatalogId { get; internal set; }
public uint CatalogId { get; private set; }
/// <summary>
/// Gets the second catalog ID.
/// </summary>
public uint CatalogId2 { get; internal set; }
public uint CatalogId2 { get; private set; }
/// <summary>
/// Gets the list of individual item history listings.
/// </summary>
public List<MarketBoardHistoryListing> HistoryListings { get; internal set; }
public List<MarketBoardHistoryListing> HistoryListings { get; } = new();
/// <summary>
/// Read a <see cref="MarketBoardHistory"/> object from memory.
@ -39,17 +39,15 @@ namespace Dalamud.Game.Network.Structures
/// <returns>A new <see cref="MarketBoardHistory"/> object.</returns>
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<MarketBoardHistoryListing>();
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; }
/// <summary>
/// Gets the catalog ID.
/// Gets the next entry's catalog ID.
/// </summary>
public uint CatalogId { get; internal set; }
public uint NextCatalogId { get; internal set; }
/// <summary>
/// Gets a value indicating whether the item is HQ.

View file

@ -9,6 +9,10 @@ namespace Dalamud.Game.Network.Structures
/// </summary>
internal class MarketBoardPurchase
{
private MarketBoardPurchase()
{
}
/// <summary>
/// Gets the item ID of the item that was purchased.
/// </summary>
@ -26,10 +30,11 @@ namespace Dalamud.Game.Network.Structures
/// <returns>An object representing the data read.</returns>
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();

View file

@ -9,6 +9,10 @@ namespace Dalamud.Game.Network.Structures
/// </summary>
internal class MarketBoardPurchaseHandler
{
private MarketBoardPurchaseHandler()
{
}
/// <summary>
/// Gets the object ID of the retainer associated with the sale.
/// </summary>
@ -41,10 +45,11 @@ namespace Dalamud.Game.Network.Structures
/// <returns>An object representing the data read.</returns>
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();

View file

@ -8,42 +8,39 @@ namespace Dalamud.Game.Network.Structures
/// </summary>
public class MarketTaxRates
{
/// <summary>
/// Initializes a new instance of the <see cref="MarketTaxRates"/> class.
/// </summary>
internal MarketTaxRates()
private MarketTaxRates()
{
}
/// <summary>
/// Gets the tax rate in Limsa Lominsa.
/// </summary>
public uint LimsaLominsaTax { get; internal set; }
public uint LimsaLominsaTax { get; private set; }
/// <summary>
/// Gets the tax rate in Gridania.
/// </summary>
public uint GridaniaTax { get; internal set; }
public uint GridaniaTax { get; private set; }
/// <summary>
/// Gets the tax rate in Ul'dah.
/// </summary>
public uint UldahTax { get; internal set; }
public uint UldahTax { get; private set; }
/// <summary>
/// Gets the tax rate in Ishgard.
/// </summary>
public uint IshgardTax { get; internal set; }
public uint IshgardTax { get; private set; }
/// <summary>
/// Gets the tax rate in Kugane.
/// </summary>
public uint KuganeTax { get; internal set; }
public uint KuganeTax { get; private set; }
/// <summary>
/// Gets the tax rate in the Crystarium.
/// </summary>
public uint CrystariumTax { get; internal set; }
public uint CrystariumTax { get; private set; }
/// <summary>
/// Read a <see cref="MarketTaxRates"/> object from memory.
@ -52,13 +49,12 @@ namespace Dalamud.Game.Network.Structures
/// <returns>A new <see cref="MarketTaxRates"/> object.</returns>
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();

View file

@ -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<Func<Task>> 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)
{

View file

@ -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()));

View file

@ -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();

View file

@ -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();
}

View file

@ -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;
/// <summary>
/// Gets an httpclient for usage.
/// Do NOT await this.
/// </summary>
public static HttpClient HttpClient { get; } = new();
/// <summary>
/// Gets the assembly version of Dalamud.
/// </summary>
@ -209,7 +216,7 @@ namespace Dalamud.Utility
}
/// <summary>
/// Compress a string using GZip.
/// Compress a string using GZip.
/// </summary>
/// <param name="str">The input string.</param>
/// <returns>The compressed output bytes.</returns>
@ -217,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();
}
/// <summary>
/// Decompress a string using GZip.
/// Decompress a string using GZip.
/// </summary>
/// <param name="bytes">The input bytes.</param>
/// <returns>The compressed output string.</returns>
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());
}
/// <summary>
@ -262,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++; }
/// <summary>
/// Heuristically determine if Dalamud is running on Linux/WINE.
/// </summary>