mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #680 from daemitus/http
This commit is contained in:
commit
4cff810d1d
14 changed files with 214 additions and 193 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
// ====================================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue