Compare commits

...

No commits in common. "main" and "6c83ebab4dd833190301563369da4b399f3d9bf3" have entirely different histories.

18 changed files with 416 additions and 506 deletions

2
MdXaml

@ -1 +1 @@
Subproject commit 83f36237847a7e3cb444bd1e2ad598c314e43a5f
Subproject commit e2b314e3ab37d7ba492d65653538f5e622380da1

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -26,9 +26,6 @@ namespace XIVChatCommon.Message.Client {
[Preference(typeof(bool))]
TargetingListSupport = 1,
[Preference(typeof(bool))]
HousingLocationSupport = 2,
}
public static class ClientPreferencesExtension {

View File

@ -33,4 +33,4 @@ namespace XIVChatCommon.Message.Server {
return MessagePackSerializer.Serialize(this);
}
}
}
}

View File

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

View File

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

View File

@ -9,6 +9,6 @@
Backlog = 7,
PlayerList = 8,
LinkshellList = 9,
HousingLocation = 10,
TargetingList = 10,
}
}

View File

@ -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>

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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.

View File

@ -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>

View File

@ -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, )"
}
}
}
}
}