Compare commits
No commits in common. "main" and "6c83ebab4dd833190301563369da4b399f3d9bf3" have entirely different histories.
main
...
6c83ebab4d
2
MdXaml
2
MdXaml
|
@ -1 +1 @@
|
|||
Subproject commit 83f36237847a7e3cb444bd1e2ad598c314e43a5f
|
||||
Subproject commit e2b314e3ab37d7ba492d65653538f5e622380da1
|
File diff suppressed because it is too large
Load Diff
|
@ -51,23 +51,23 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.5"/>
|
||||
<PackageReference Include="Fody" Version="6.6.3">
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.6.4"/>
|
||||
<PackageReference Include="Fody" Version="6.5.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0"/>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2"/>
|
||||
<PackageReference Include="ModernWpfUI" Version="0.9.6"/>
|
||||
<PackageReference Include="ModernWpfUI.MahApps" Version="0.9.5"/>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.0.2"/>
|
||||
<PackageReference Include="ModernWpfUI" Version="0.9.4"/>
|
||||
<PackageReference Include="ModernWpfUI.MahApps" Version="0.9.4"/>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="3.4.1">
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Sentry" Version="3.20.1"/>
|
||||
<PackageReference Include="Sodium.Core" Version="1.3.1"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="6.0.0"/>
|
||||
<PackageReference Include="WpfWindowPlacement" Version="4.0.2"/>
|
||||
<PackageReference Include="Sentry" Version="3.4.0"/>
|
||||
<PackageReference Include="Sodium.Core" Version="1.2.3"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.2"/>
|
||||
<PackageReference Include="WpfWindowPlacement" Version="3.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -26,9 +26,6 @@ namespace XIVChatCommon.Message.Client {
|
|||
|
||||
[Preference(typeof(bool))]
|
||||
TargetingListSupport = 1,
|
||||
|
||||
[Preference(typeof(bool))]
|
||||
HousingLocationSupport = 2,
|
||||
}
|
||||
|
||||
public static class ClientPreferencesExtension {
|
||||
|
|
|
@ -33,4 +33,4 @@ namespace XIVChatCommon.Message.Server {
|
|||
return MessagePackSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,14 +6,10 @@ namespace XIVChatCommon.Message.Server {
|
|||
[Key(0)]
|
||||
public readonly ServerMessage[] messages;
|
||||
|
||||
[Key(1)]
|
||||
public readonly uint sequence;
|
||||
|
||||
protected override byte Code => (byte)ServerOperation.Backlog;
|
||||
|
||||
public ServerBacklog(ServerMessage[] messages, uint sequence) {
|
||||
public ServerBacklog(ServerMessage[] messages) {
|
||||
this.messages = messages;
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
public static ServerBacklog Decode(byte[] bytes) {
|
||||
|
@ -24,4 +20,4 @@ namespace XIVChatCommon.Message.Server {
|
|||
return MessagePackSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
using MessagePack;
|
||||
|
||||
namespace XIVChatCommon.Message.Server {
|
||||
[MessagePackObject]
|
||||
public class ServerHousingLocation : Encodable {
|
||||
[Key(0)]
|
||||
public readonly ushort? ward;
|
||||
|
||||
[Key(1)]
|
||||
public readonly ushort? plot;
|
||||
|
||||
[Key(2)]
|
||||
public readonly bool plotExterior;
|
||||
|
||||
[Key(3)]
|
||||
public readonly byte? apartmentWing;
|
||||
|
||||
public ServerHousingLocation(ushort? ward, ushort? plot, bool plotExterior, byte? apartmentWing) {
|
||||
this.ward = ward;
|
||||
this.plot = plot;
|
||||
this.plotExterior = plotExterior;
|
||||
this.apartmentWing = apartmentWing;
|
||||
}
|
||||
|
||||
[IgnoreMember]
|
||||
protected override byte Code => (byte) ServerOperation.HousingLocation;
|
||||
|
||||
public static ServerHousingLocation Decode(byte[] bytes) {
|
||||
return MessagePackSerializer.Deserialize<ServerHousingLocation>(bytes);
|
||||
}
|
||||
|
||||
protected override byte[] PayloadEncode() {
|
||||
return MessagePackSerializer.Serialize(this);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) {
|
||||
if (obj is not ServerHousingLocation other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.ward == other.ward
|
||||
&& this.plot == other.plot
|
||||
&& this.plotExterior == other.plotExterior
|
||||
&& this.apartmentWing == other.apartmentWing;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
var hashCode = this.ward.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ this.plot.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ this.plotExterior.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ this.apartmentWing.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,6 @@
|
|||
Backlog = 7,
|
||||
PlayerList = 8,
|
||||
LinkshellList = 9,
|
||||
HousingLocation = 10,
|
||||
TargetingList = 10,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<AssemblyVersion>1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0</FileVersion>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net48;net5.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MessagePack" Version="2.4.59" />
|
||||
<PackageReference Include="Sodium.Core" Version="1.3.2" />
|
||||
<PackageReference Include="MessagePack" Version="2.2.85"/>
|
||||
<PackageReference Include="Sodium.Core" Version="1.2.3"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,20 +7,20 @@ using System.Linq;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Memory;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||
using XIVChatCommon.Message;
|
||||
using XIVChatCommon.Message.Server;
|
||||
|
||||
namespace XIVChatPlugin {
|
||||
internal unsafe class GameFunctions : IDisposable {
|
||||
internal class GameFunctions : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string GetUiModule = "E8 ?? ?? ?? ?? 48 83 7F ?? 00 48 8B F0";
|
||||
internal const string ProcessChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9";
|
||||
internal const string Input = "80 B9 ?? ?? ?? ?? ?? 0F 9C C0";
|
||||
internal const string InputAfk = "E8 ?? ?? ?? ?? 0F 28 74 24 ?? 0F B6 F0";
|
||||
internal const string FriendList = "40 53 48 81 EC 80 0F 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B D9 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ?? 44 0F B6 43 ?? 33 C9";
|
||||
internal const string Format = "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 8B 6C 24";
|
||||
internal const string Format = "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 48 8B 6C 24";
|
||||
internal const string ReceiveChunk = "48 89 5C 24 ?? 56 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 8B F2";
|
||||
|
||||
internal const string GetColour = "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B F2 48 8D B9";
|
||||
|
@ -30,12 +30,14 @@ namespace XIVChatPlugin {
|
|||
internal const string ChannelNameChange = "E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 8D 4D B0 48 8B F8 E8 ?? ?? ?? ?? 41 8B D6";
|
||||
internal const string XivStringCtor = "E8 ?? ?? ?? ?? 44 2B F7";
|
||||
internal const string XivStringDtor = "E8 ?? ?? ?? ?? B0 6E";
|
||||
internal const string UiModule = "48 8B 0D ?? ?? ?? ?? 48 8D 54 24 ?? 48 83 C1 10 E8";
|
||||
internal const string ColourHandler = "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 85 C9 0F 84 ?? ?? ?? ?? 66 85 DB 0F 94 C2 E8 ?? ?? ?? ?? E9";
|
||||
internal const string ColourLookup = "48 8D 0D ?? ?? ?? ?? 8B 14 ?? 85 D2 7E ?? 48 8B 0D ?? ?? ?? ?? 48 83 C1 10 E8 ?? ?? ?? ?? 8B 70 ?? 41 8D 4D";
|
||||
}
|
||||
|
||||
private Plugin Plugin { get; }
|
||||
|
||||
#region Delegates
|
||||
private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr);
|
||||
|
||||
private delegate void EasierProcessChatBoxDelegate(IntPtr uiModule, IntPtr message, IntPtr unused, byte a4);
|
||||
|
||||
|
@ -61,59 +63,21 @@ namespace XIVChatPlugin {
|
|||
|
||||
private delegate IntPtr XivStringDtorDelegate(IntPtr memory);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Hooks
|
||||
|
||||
[Signature(Signatures.Input, DetourName = nameof(IsInputDetour))]
|
||||
private readonly Hook<IsInputDelegate>? _isInputHook;
|
||||
|
||||
[Signature(Signatures.InputAfk, DetourName = nameof(IsInputAfkDetour))]
|
||||
private readonly Hook<IsInputAfkDelegate>? _isInputAfkHook;
|
||||
|
||||
[Signature(Signatures.FriendList, DetourName = nameof(OnRequestFriendList))]
|
||||
private readonly Hook<RequestFriendListDelegate>? _friendListHook;
|
||||
|
||||
[Signature(Signatures.Format, DetourName = nameof(OnFormatFriendList))]
|
||||
private readonly Hook<FormatFriendListNameDelegate>? _formatHook;
|
||||
|
||||
[Signature(Signatures.ReceiveChunk, DetourName = nameof(OnReceiveFriendList))]
|
||||
private readonly Hook<OnReceiveFriendListChunkDelegate>? _receiveChunkHook;
|
||||
|
||||
[Signature(Signatures.Channel, DetourName = nameof(ChangeChatChannelDetour))]
|
||||
private readonly Hook<ChatChannelChangeDelegate>? _chatChannelChangeHook;
|
||||
|
||||
[Signature(Signatures.ChannelNameChange, DetourName = nameof(ChangeChatChannelNameDetour))]
|
||||
private readonly Hook<ChatChannelChangeNameDelegate>? _chatChannelChangeNameHook;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
[Signature(Signatures.ProcessChat)]
|
||||
private readonly GetUiModuleDelegate? _getUiModule;
|
||||
private readonly EasierProcessChatBoxDelegate? _easierProcessChatBox;
|
||||
|
||||
[Signature(Signatures.GetColour)]
|
||||
private readonly GetColourInfoDelegate? _getColourInfo;
|
||||
|
||||
[Signature(Signatures.ChannelCommand)]
|
||||
private readonly ChannelChangeCommandDelegate? _channelChangeCommand;
|
||||
|
||||
[Signature(Signatures.XivStringCtor)]
|
||||
private readonly XivStringCtorDelegate? _xivStringCtor;
|
||||
|
||||
[Signature(Signatures.XivStringDtor)]
|
||||
private readonly XivStringDtorDelegate? _xivStringDtor;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pointers
|
||||
|
||||
[Signature(Signatures.ColourLookup, ScanType = ScanType.StaticAddress)]
|
||||
private IntPtr ColourLookup { get; init; }
|
||||
|
||||
#endregion
|
||||
|
||||
public ServerHousingLocation HousingLocation {
|
||||
get {
|
||||
var info = this.Plugin.Common.Functions.Housing.Location;
|
||||
|
@ -138,6 +102,9 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
|
||||
private InputSetters HadInput { get; set; } = InputSetters.None;
|
||||
private IntPtr UiModulePtr { get; }
|
||||
private IntPtr ColourHandler { get; }
|
||||
private IntPtr ColourLookup { get; }
|
||||
private IntPtr _friendListManager = IntPtr.Zero;
|
||||
private IntPtr _chatManager = IntPtr.Zero;
|
||||
private readonly IntPtr _emptyXivString = IntPtr.Zero;
|
||||
|
@ -153,7 +120,112 @@ namespace XIVChatPlugin {
|
|||
internal GameFunctions(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
|
||||
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
var getUiModulePtr = this.Plugin.ScanText(Signatures.GetUiModule);
|
||||
var easierProcessChatBoxPtr = this.Plugin.ScanText(Signatures.ProcessChat);
|
||||
var inputPtr = this.Plugin.ScanText(Signatures.Input);
|
||||
var inputAfkPtr = this.Plugin.ScanText(Signatures.InputAfk);
|
||||
var friendListPtr = this.Plugin.ScanText(Signatures.FriendList);
|
||||
var formatPtr = this.Plugin.ScanText(Signatures.Format);
|
||||
var recvChunkPtr = this.Plugin.ScanText(Signatures.ReceiveChunk);
|
||||
var getColourPtr = this.Plugin.ScanText(Signatures.GetColour);
|
||||
var channelPtr = this.Plugin.ScanText(Signatures.Channel);
|
||||
var channelNamePtr = this.Plugin.ScanText(Signatures.ChannelNameChange);
|
||||
var channelCommandPtr = this.Plugin.ScanText(Signatures.ChannelCommand);
|
||||
var xivStringCtorPtr = this.Plugin.ScanText(Signatures.XivStringCtor);
|
||||
var xivStringDtorPtr = this.Plugin.ScanText(Signatures.XivStringDtor);
|
||||
|
||||
this.UiModulePtr = this.Plugin.GetStaticAddressFromSig(Signatures.UiModule);
|
||||
if (this.UiModulePtr == IntPtr.Zero) {
|
||||
PluginLog.Warning("Static pointer was null: {0}", nameof(this.UiModulePtr));
|
||||
}
|
||||
|
||||
this.ColourHandler = this.Plugin.GetStaticAddressFromSig(Signatures.ColourHandler);
|
||||
if (this.ColourHandler == IntPtr.Zero) {
|
||||
PluginLog.Warning("Static pointer was null: {0}", nameof(this.ColourHandler));
|
||||
}
|
||||
|
||||
this.ColourLookup = this.Plugin.GetStaticAddressFromSig(Signatures.ColourLookup);
|
||||
if (this.ColourLookup == IntPtr.Zero) {
|
||||
PluginLog.Warning("Static pointer was null: {0}", nameof(this.ColourLookup));
|
||||
}
|
||||
|
||||
if (getUiModulePtr != IntPtr.Zero) {
|
||||
this._getUiModule = Marshal.GetDelegateForFunctionPointer<GetUiModuleDelegate>(getUiModulePtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(getUiModulePtr));
|
||||
}
|
||||
|
||||
if (easierProcessChatBoxPtr != IntPtr.Zero) {
|
||||
this._easierProcessChatBox = Marshal.GetDelegateForFunctionPointer<EasierProcessChatBoxDelegate>(easierProcessChatBoxPtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(easierProcessChatBoxPtr));
|
||||
}
|
||||
|
||||
if (getColourPtr != IntPtr.Zero) {
|
||||
this._getColourInfo = Marshal.GetDelegateForFunctionPointer<GetColourInfoDelegate>(getColourPtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(getColourPtr));
|
||||
}
|
||||
|
||||
if (channelCommandPtr != IntPtr.Zero) {
|
||||
this._channelChangeCommand = Marshal.GetDelegateForFunctionPointer<ChannelChangeCommandDelegate>(channelCommandPtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(channelCommandPtr));
|
||||
}
|
||||
|
||||
if (xivStringCtorPtr != IntPtr.Zero) {
|
||||
this._xivStringCtor = Marshal.GetDelegateForFunctionPointer<XivStringCtorDelegate>(xivStringCtorPtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(xivStringCtorPtr));
|
||||
}
|
||||
|
||||
if (xivStringDtorPtr != IntPtr.Zero) {
|
||||
this._xivStringDtor = Marshal.GetDelegateForFunctionPointer<XivStringDtorDelegate>(xivStringDtorPtr);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling function: {0}", nameof(xivStringDtorPtr));
|
||||
}
|
||||
|
||||
if (friendListPtr != IntPtr.Zero) {
|
||||
this._friendListHook = new Hook<RequestFriendListDelegate>(friendListPtr, this.OnRequestFriendList);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(friendListPtr));
|
||||
}
|
||||
|
||||
if (formatPtr != IntPtr.Zero) {
|
||||
this._formatHook = new Hook<FormatFriendListNameDelegate>(formatPtr, this.OnFormatFriendList);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(formatPtr));
|
||||
}
|
||||
|
||||
if (recvChunkPtr != IntPtr.Zero) {
|
||||
this._receiveChunkHook = new Hook<OnReceiveFriendListChunkDelegate>(recvChunkPtr, this.OnReceiveFriendList);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(recvChunkPtr));
|
||||
}
|
||||
|
||||
if (channelPtr != IntPtr.Zero) {
|
||||
this._chatChannelChangeHook = new Hook<ChatChannelChangeDelegate>(channelPtr, this.ChangeChatChannelDetour);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(channelPtr));
|
||||
}
|
||||
|
||||
if (channelNamePtr != IntPtr.Zero) {
|
||||
this._chatChannelChangeNameHook = new Hook<ChatChannelChangeNameDelegate>(channelNamePtr, this.ChangeChatChannelNameDetour);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(channelNamePtr));
|
||||
}
|
||||
|
||||
if (inputPtr != IntPtr.Zero) {
|
||||
this._isInputHook = new Hook<IsInputDelegate>(inputPtr, this.IsInputDetour);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(inputPtr));
|
||||
}
|
||||
|
||||
if (inputAfkPtr != IntPtr.Zero) {
|
||||
this._isInputAfkHook = new Hook<IsInputAfkDelegate>(inputAfkPtr, this.IsInputAfkDetour);
|
||||
} else {
|
||||
PluginLog.Warning("Pointer was null, disabling hook: {0}", nameof(inputAfkPtr));
|
||||
}
|
||||
|
||||
this._friendListHook?.Enable();
|
||||
this._formatHook?.Enable();
|
||||
|
@ -199,7 +271,7 @@ namespace XIVChatPlugin {
|
|||
//
|
||||
// If this function would ever return 0, it returns null instead.
|
||||
internal uint? GetChannelColour(ChatCode channel) {
|
||||
if (this._getColourInfo == null || this.ColourLookup == IntPtr.Zero) {
|
||||
if (this._getColourInfo == null || this.ColourLookup == IntPtr.Zero || this.ColourHandler == IntPtr.Zero) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -217,11 +289,9 @@ namespace XIVChatPlugin {
|
|||
return channel.DefaultColour();
|
||||
}
|
||||
|
||||
var framework = (IntPtr) Framework.Instance();
|
||||
|
||||
var lookupResult = *(uint*) (this.ColourLookup + (int) parent * 4);
|
||||
var info = this._getColourInfo(framework + 16, lookupResult);
|
||||
var rgb = *(uint*) (info + 32) & 0xFFFFFF;
|
||||
var lookupResult = (uint) Marshal.ReadInt32(this.ColourLookup, (int) parent * 4);
|
||||
var info = this._getColourInfo(Marshal.ReadIntPtr(this.ColourHandler) + 16, lookupResult);
|
||||
var rgb = (uint) Marshal.ReadInt32(info, 32) & 0xFFFFFF;
|
||||
|
||||
if (rgb == 0) {
|
||||
return null;
|
||||
|
@ -231,19 +301,23 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
|
||||
internal void ProcessChatBox(string message) {
|
||||
if (this._easierProcessChatBox == null) {
|
||||
if (this._easierProcessChatBox == null || this._getUiModule == null || this.UiModulePtr == IntPtr.Zero) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.HadInput = InputSetters.Normal | InputSetters.Afk;
|
||||
|
||||
var uiModule = Framework.Instance()->GetUiModule();
|
||||
var uiModule = this._getUiModule(Marshal.ReadIntPtr(this.UiModulePtr));
|
||||
|
||||
if (uiModule == IntPtr.Zero) {
|
||||
throw new ArgumentException("pointer was null", nameof(uiModule));
|
||||
}
|
||||
|
||||
using var payload = new ChatPayload(message);
|
||||
var mem1 = Marshal.AllocHGlobal(400);
|
||||
Marshal.StructureToPtr(payload, mem1, false);
|
||||
|
||||
this._easierProcessChatBox((IntPtr) uiModule, mem1, IntPtr.Zero, 0);
|
||||
this._easierProcessChatBox(uiModule, mem1, IntPtr.Zero, 0);
|
||||
|
||||
Marshal.FreeHGlobal(mem1);
|
||||
}
|
||||
|
@ -265,7 +339,7 @@ namespace XIVChatPlugin {
|
|||
return this._chatChannelChangeHook!.Original(a1, channel);
|
||||
}
|
||||
|
||||
private IntPtr ChangeChatChannelNameDetour(IntPtr a1) {
|
||||
private unsafe IntPtr ChangeChatChannelNameDetour(IntPtr a1) {
|
||||
// Last ShB patch
|
||||
// +0x40 = chat channel (byte or uint?)
|
||||
// channel is 17 (maybe 18?) for tells
|
||||
|
@ -372,7 +446,7 @@ namespace XIVChatPlugin {
|
|||
goto Return;
|
||||
}
|
||||
|
||||
if (*(byte*) (data + 0xc) != 2 || *(ushort*) (data + 0x8) != 0) {
|
||||
if (Marshal.ReadByte(data + 0xc) != 2 || Marshal.ReadInt16(data + 0x8) != 0) {
|
||||
goto Return;
|
||||
}
|
||||
|
||||
|
@ -416,7 +490,7 @@ namespace XIVChatPlugin {
|
|||
private readonly ulong unk2;
|
||||
|
||||
internal ChatPayload(string text) {
|
||||
var stringBytes = Encoding.UTF8.GetBytes(text);
|
||||
byte[] stringBytes = Encoding.UTF8.GetBytes(text);
|
||||
this.textPtr = Marshal.AllocHGlobal(stringBytes.Length + 30);
|
||||
Marshal.Copy(stringBytes, 0, this.textPtr, stringBytes.Length);
|
||||
Marshal.WriteByte(this.textPtr + stringBytes.Length, 0);
|
||||
|
@ -460,7 +534,7 @@ namespace XIVChatPlugin {
|
|||
private readonly byte[] fc;
|
||||
|
||||
private static string? HandleString(IEnumerable<byte> bytes) {
|
||||
var nonNull = bytes.TakeWhile(b => b != 0).ToArray();
|
||||
byte[] nonNull = bytes.TakeWhile(b => b != 0).ToArray();
|
||||
return nonNull.Length == 0 ? null : Encoding.UTF8.GetString(nonNull);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,12 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin.Services;
|
||||
using XivCommon;
|
||||
#if DEBUG
|
||||
using System.IO;
|
||||
|
@ -14,39 +17,33 @@ using System.IO;
|
|||
|
||||
namespace XIVChatPlugin {
|
||||
internal class Plugin : IDalamudPlugin {
|
||||
internal static string Name => "XIVChat";
|
||||
public string Name => "XIVChat";
|
||||
|
||||
private bool _disposedValue;
|
||||
|
||||
[PluginService]
|
||||
internal static IPluginLog Log { get; private set; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal DalamudPluginInterface Interface { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal IChatGui ChatGui { get; private init; } = null!;
|
||||
internal ChatGui ChatGui { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal IClientState ClientState { get; private init; } = null!;
|
||||
internal ClientState ClientState { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
private ICommandManager CommandManager { get; init; } = null!;
|
||||
private CommandManager CommandManager { get; init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal IDataManager DataManager { get; private init; } = null!;
|
||||
internal DataManager DataManager { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
private IFramework Framework { get; init; } = null!;
|
||||
private Framework Framework { get; init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal IObjectTable ObjectTable { get; private init; } = null!;
|
||||
internal ObjectTable ObjectTable { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
internal IGameInteropProvider GameInteropProvider { get; private init; } = null!;
|
||||
|
||||
[PluginService]
|
||||
private ISigScanner SigScanner { get; init; } = null!;
|
||||
private SigScanner SigScanner { get; init; } = null!;
|
||||
|
||||
internal XivCommonBase Common { get; }
|
||||
internal Configuration Config { get; }
|
||||
|
@ -69,13 +66,13 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
|
||||
public Plugin() {
|
||||
this.Common = new XivCommonBase(this.Interface);
|
||||
this.Common = new XivCommonBase();
|
||||
this.Events = new InternalEvents();
|
||||
|
||||
// load libsodium.so from debug location if in debug mode
|
||||
#if DEBUG
|
||||
string path = Environment.GetEnvironmentVariable("PATH")!;
|
||||
string newPath = Path.GetDirectoryName(this.Location)!;
|
||||
string newPath = Path.GetDirectoryName(this.DalamudPlugin.Location)!;
|
||||
Environment.SetEnvironmentVariable("PATH", $"{path};{newPath}");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ namespace XIVChatPlugin {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Begin(Plugin.Name, ref this._showSettings, ImGuiWindowFlags.AlwaysAutoResize)) {
|
||||
if (!Begin(this.Plugin.Name, ref this._showSettings, ImGuiWindowFlags.AlwaysAutoResize)) {
|
||||
ImGui.End();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Security.Authentication;
|
|||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Logging;
|
||||
using MessagePack;
|
||||
using WebSocketSharp;
|
||||
using XIVChatCommon.Message.Relay;
|
||||
|
@ -141,7 +142,7 @@ namespace XIVChatPlugin {
|
|||
ConnectionError = null;
|
||||
this.Status = ConnectionStatus.Connected;
|
||||
} else {
|
||||
Plugin.Log.Warning($"Relay: {success.Info}");
|
||||
PluginLog.LogWarning($"Relay: {success.Info}");
|
||||
ConnectionError = success.Info;
|
||||
this.Status = ConnectionStatus.Disconnected;
|
||||
this.Plugin.StopRelay();
|
||||
|
@ -194,7 +195,7 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
|
||||
private void OnError(object? sender, ErrorEventArgs args) {
|
||||
Plugin.Log.Error(args.Exception, $"Error in relay connection: {args.Message}");
|
||||
PluginLog.LogError(args.Exception, $"Error in relay connection: {args.Message}");
|
||||
this.Running = false;
|
||||
this.Status = ConnectionStatus.Disconnected;
|
||||
|
||||
|
|
|
@ -12,10 +12,11 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Logging;
|
||||
using XIVChatCommon;
|
||||
using XIVChatCommon.Message;
|
||||
using XIVChatCommon.Message.Client;
|
||||
|
@ -154,7 +155,7 @@ namespace XIVChatPlugin {
|
|||
await udp.SendAsync(payload, payload.Length, recv.RemoteEndPoint);
|
||||
}
|
||||
|
||||
Plugin.Log.Info("Scan response thread done");
|
||||
PluginLog.Log("Scan response thread done");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -180,7 +181,7 @@ namespace XIVChatPlugin {
|
|||
this._listener.Start();
|
||||
|
||||
this._running = true;
|
||||
Plugin.Log.Info("Running...");
|
||||
PluginLog.Log("Running...");
|
||||
this.SpawnPairingModeTask();
|
||||
while (!this._tokenSource.IsCancellationRequested) {
|
||||
var conn = await this._listener.GetTcpClient(this._tokenSource);
|
||||
|
@ -249,7 +250,7 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
internal void OnFrameworkUpdate(IFramework framework) {
|
||||
internal void OnFrameworkUpdate(Framework framework1) {
|
||||
var player = this._plugin.ClientState.LocalPlayer;
|
||||
if (player != null && this._sendPlayerData) {
|
||||
this.BroadcastPlayerData();
|
||||
|
@ -382,7 +383,7 @@ namespace XIVChatPlugin {
|
|||
this._tokenSource.Token
|
||||
);
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error($"Could not send message: {ex.Message}");
|
||||
PluginLog.LogError($"Could not send message: {ex.Message}");
|
||||
}
|
||||
|
||||
var listen = Task.Run(async () => {
|
||||
|
@ -393,7 +394,7 @@ namespace XIVChatPlugin {
|
|||
} catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut) {
|
||||
continue;
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error($"Could not read message: {ex.Message}");
|
||||
PluginLog.LogError($"Could not read message: {ex.Message}");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -408,7 +409,7 @@ namespace XIVChatPlugin {
|
|||
var msg = await client.Queue.Reader.ReadAsync(client.TokenSource.Token);
|
||||
await SecretMessage.SendSecretMessage(client, handshake.Keys.tx, msg, client.TokenSource.Token);
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error($"Could not send message: {ex.Message}");
|
||||
PluginLog.LogError($"Could not send message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +418,7 @@ namespace XIVChatPlugin {
|
|||
await listen;
|
||||
|
||||
this._clients.TryRemove(id, out _);
|
||||
Plugin.Log.Info($"Client thread ended: {id}");
|
||||
PluginLog.Log($"Client thread ended: {id}");
|
||||
}).ContinueWith(_ => {
|
||||
this.RemoveClient(id);
|
||||
});
|
||||
|
@ -442,7 +443,7 @@ namespace XIVChatPlugin {
|
|||
try {
|
||||
await client.Queue.Writer.WriteAsync(Pong.Instance);
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error($"Could not send message: {ex.Message}");
|
||||
PluginLog.LogError($"Could not send message: {ex.Message}");
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -501,7 +502,7 @@ namespace XIVChatPlugin {
|
|||
this._waitingForFriendList.Add(id);
|
||||
|
||||
if (!this._plugin.Functions.RequestingFriendList && !this._plugin.Functions.RequestFriendList()) {
|
||||
this._plugin.ChatGui.PrintError($"[{Plugin.Name}] Please open your friend list to enable friend list support. You should only need to do this on initial install or after updates.");
|
||||
this._plugin.ChatGui.PrintError($"[{this._plugin.Name}] Please open your friend list to enable friend list support. You should only need to do this on initial install or after updates.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -602,7 +603,7 @@ namespace XIVChatPlugin {
|
|||
try {
|
||||
await client.Queue.Writer.WriteAsync(resp);
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error($"Could not send backlog: {ex.Message}");
|
||||
PluginLog.LogError($"Could not send backlog: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,13 +686,8 @@ namespace XIVChatPlugin {
|
|||
case PayloadType.Unknown:
|
||||
var rawPayload = (RawPayload) payload;
|
||||
if (rawPayload.Data[1] == 0x13) {
|
||||
if (foreground.Count > 0) {
|
||||
foreground.Pop();
|
||||
}
|
||||
|
||||
if (glow.Count > 0) {
|
||||
glow.Pop();
|
||||
}
|
||||
foreground.Pop();
|
||||
glow.Pop();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -832,18 +828,18 @@ namespace XIVChatPlugin {
|
|||
this.BroadcastMessage(playerData);
|
||||
}
|
||||
|
||||
internal void OnLogIn() {
|
||||
internal void OnLogIn(object? sender, EventArgs e) {
|
||||
this.BroadcastAvailability(true);
|
||||
// send player data on next framework update
|
||||
this._sendPlayerData = true;
|
||||
}
|
||||
|
||||
internal void OnLogOut() {
|
||||
internal void OnLogOut(object? sender, EventArgs e) {
|
||||
this.BroadcastAvailability(false);
|
||||
this.BroadcastPlayerData();
|
||||
}
|
||||
|
||||
internal void OnTerritoryChange(ushort @ushort) => this._sendPlayerData = true;
|
||||
internal void OnTerritoryChange(object? sender, ushort territoryId) => this._sendPlayerData = true;
|
||||
|
||||
public void Dispose() {
|
||||
// stop accepting new clients
|
||||
|
|
|
@ -77,11 +77,11 @@ namespace XIVChatPlugin {
|
|||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
// Plugin.Log.Info($"start: {start.ToInt64():x}");
|
||||
|
||||
// PluginLog.Log($"start: {start.ToInt64():x}");
|
||||
|
||||
foreach (var offset in offsets) {
|
||||
start = Marshal.ReadIntPtr(start + offset);
|
||||
// Plugin.Log.Info($" + {offset}: {start.ToInt64():x}");
|
||||
// PluginLog.Log($" + {offset}: {start.ToInt64():x}");
|
||||
if (start == IntPtr.Zero) {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
author: Anna
|
||||
author: ascclemens
|
||||
name: XIVChat Server
|
||||
punchline: Use chat away from the game.
|
||||
description: |-
|
||||
XIVChat is a suite of software allowing you to use FFXIV's chat from
|
||||
different devices. This is the server component required to do so.
|
||||
|
|
|
@ -2,59 +2,43 @@
|
|||
<PropertyGroup>
|
||||
<RootNamespace>XIVChatPlugin</RootNamespace>
|
||||
<AssemblyName>XIVChat</AssemblyName>
|
||||
<TargetFramework>net7-windows</TargetFramework>
|
||||
<TargetFramework>net5-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Version>1.7.8</Version>
|
||||
<Version>1.7.1</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev</DalamudLibPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
|
||||
<DalamudLibPath>$(DALAMUD_HOME)</DalamudLibPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsCI)' == 'true'">
|
||||
<DalamudLibPath>$(HOME)/dalamud</DalamudLibPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Dalamud">
|
||||
<HintPath>$(DalamudLibPath)\Dalamud.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="FFXIVClientStructs">
|
||||
<HintPath>$(DalamudLibPath)\FFXIVClientStructs.dll</HintPath>
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="ImGui.NET">
|
||||
<HintPath>$(DalamudLibPath)\ImGui.NET.dll</HintPath>
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGui.NET.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Lumina">
|
||||
<HintPath>$(DalamudLibPath)\Lumina.dll</HintPath>
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Lumina.Excel">
|
||||
<HintPath>$(DalamudLibPath)\Lumina.Excel.dll</HintPath>
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="PeepingTom.Ipc">
|
||||
<HintPath>..\..\PeepingTom\Peeping Tom.Ipc\bin\Release\net7.0-windows\Peeping Tom.Ipc.dll</HintPath>
|
||||
<HintPath>..\..\PeepingTom\Peeping Tom.Ipc\bin\Release\net5.0-windows\Peeping Tom.Ipc.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DalamudPackager" Version="2.1.12"/>
|
||||
<PackageReference Include="MessagePack" Version="2.5.129"/>
|
||||
<PackageReference Include="PeepingTom.Ipc" Version="1.0.0"/>
|
||||
<PackageReference Include="Sodium.Core" Version="1.3.4"/>
|
||||
<PackageReference Include="System.Threading.Channels" Version="7.0.0"/>
|
||||
<PackageReference Include="DalamudLinter" Version="1.0.3"/>
|
||||
<PackageReference Include="DalamudPackager" Version="2.1.5"/>
|
||||
<PackageReference Include="MessagePack" Version="2.3.85"/>
|
||||
<PackageReference Include="Sodium.Core" Version="1.2.3"/>
|
||||
<PackageReference Include="System.Threading.Channels" Version="6.0.0"/>
|
||||
<PackageReference Include="WebSocketSharp-netstandard" Version="1.0.1"/>
|
||||
<PackageReference Include="XivCommon" Version="9.0.0"/>
|
||||
<PackageReference Include="XivCommon" Version="4.0.0-alpha.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\XIVChatCommon\XIVChatCommon.csproj"/>
|
||||
|
@ -63,4 +47,7 @@
|
|||
<Copy SourceFiles="Resources\lib\libsodium.dll" DestinationFolder="$(OutDir)"/>
|
||||
<Copy SourceFiles="Resources\lib\xivchat_native_tools.dll" DestinationFolder="$(OutDir)"/>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\icon.png" Link="images/icon.png" CopyToOutputDirectory="PreserveNewest" Visible="false"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net7.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.12, )",
|
||||
"resolved": "2.1.12",
|
||||
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
|
||||
},
|
||||
"MessagePack": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.5.129, )",
|
||||
"resolved": "2.5.129",
|
||||
"contentHash": "1jBW0Q3qvv+PJBwer8lQ2l26/fKptJIqFgVdyKfn4zW+LSYE8xEcvd4svfh0erI5f4d+rQRIAN229I2ARI/A5w==",
|
||||
"dependencies": {
|
||||
"MessagePack.Annotations": "2.5.129",
|
||||
"Microsoft.NET.StringTools": "17.6.3",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"PeepingTom.Ipc": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.0, )",
|
||||
"resolved": "1.0.0",
|
||||
"contentHash": "u6lb0mLBbqGdKvafYGyh4yqEO5rZulCBTAaVvfV2h5+OYX20bw44eUeIbVJTc2TinUXezE8dON/0igwFzYHAZw=="
|
||||
},
|
||||
"Sodium.Core": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.3.4, )",
|
||||
"resolved": "1.3.4",
|
||||
"contentHash": "BB0ni8tcIhGsz7yQElC6qdj6ez+XMuR98pz3o+pQ4ngF0QqFS7skKzaj1mhCwDMLqctinikhgvqMdXK4uCs2Fg==",
|
||||
"dependencies": {
|
||||
"libsodium": "1.0.19"
|
||||
}
|
||||
},
|
||||
"System.Threading.Channels": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.0.0, )",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "qmeeYNROMsONF6ndEZcIQ+VxR4Q/TX/7uIVLJqtwIWL7dDWeh0l1UIqgo4wYyjG//5lUNhwkLDSFl+pAWO6oiA=="
|
||||
},
|
||||
"WebSocketSharp-netstandard": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.1, )",
|
||||
"resolved": "1.0.1",
|
||||
"contentHash": "knoinAv31vbdxXdypnzN2MPX5hyntVLWceq6OdWRXkr9zzqp/RWbxSuLFGbkW8De1061URgNAN43BUTlgMx1CA=="
|
||||
},
|
||||
"XivCommon": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.0, )",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "avaBp3FmSCi/PiQhntCeBDYOHejdyTWmFtz4pRBVQQ8vHkmRx+YTk1la9dkYBMlXxRXKckEdH1iI1Fu61JlE7w=="
|
||||
},
|
||||
"libsodium": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.19",
|
||||
"contentHash": "tupm/HViwBN6Knd/gckR+cLaJGR39GLmiU4iDMM5hp/1BoczMr8fwJhSU+3/C2V4hi9nBK/4FICRKtTLU30TCA=="
|
||||
},
|
||||
"MessagePack.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.5.129",
|
||||
"contentHash": "wNJB3EaJKjq+5pti+0T8b444fEb2PRw3hFefp9+of/BvDdTWO0iIUWfYNZbKx5aAIrpFzhLEfMAEJnGWWq3OFQ=="
|
||||
},
|
||||
"Microsoft.NET.StringTools": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.6.3",
|
||||
"contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"xivchatcommon": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"MessagePack": "[2.4.59, )",
|
||||
"Sodium.Core": "[1.3.2, )"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue