feat(plugin): add PeepingTom integration

This commit is contained in:
Anna 2021-07-04 21:09:38 -04:00
parent a3fcd576a7
commit c48a3ef0d8
12 changed files with 214 additions and 136 deletions

View File

@ -13,20 +13,20 @@ using XIVChatCommon.Message.Client;
using XIVChatCommon.Message.Relay; using XIVChatCommon.Message.Relay;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public abstract class BaseClient : Stream { internal abstract class BaseClient : Stream {
public virtual bool Connected { get; set; } internal virtual bool Connected { get; set; }
public HandshakeInfo? Handshake { get; set; } internal HandshakeInfo? Handshake { get; set; }
public ClientPreferences? Preferences { get; set; } internal ClientPreferences? Preferences { get; set; }
public IPAddress? Remote { get; set; } internal IPAddress? Remote { get; set; }
public CancellationTokenSource TokenSource { get; } = new(); internal CancellationTokenSource TokenSource { get; } = new();
public Channel<Encodable> Queue { get; } = Channel.CreateUnbounded<Encodable>(); internal Channel<Encodable> Queue { get; } = Channel.CreateUnbounded<Encodable>();
public void Disconnect() { internal void Disconnect() {
this.Connected = false; this.Connected = false;
this.TokenSource.Cancel(); this.TokenSource.Cancel();
@ -37,7 +37,7 @@ namespace XIVChatPlugin {
} }
} }
public T? GetPreference<T>(ClientPreference pref, T? def = default) { internal T? GetPreference<T>(ClientPreference pref, T? def = default) {
var prefs = this.Preferences; var prefs = this.Preferences;
if (prefs == null) { if (prefs == null) {
@ -48,12 +48,12 @@ namespace XIVChatPlugin {
} }
} }
public sealed class TcpConnected : BaseClient { internal sealed class TcpConnected : BaseClient {
private TcpClient Client { get; } private TcpClient Client { get; }
private readonly Stream _streamImplementation; private readonly Stream _streamImplementation;
private bool _connected; private bool _connected;
public override bool Connected { internal override bool Connected {
get { get {
var ret = this._connected; var ret = this._connected;
try { try {
@ -67,7 +67,7 @@ namespace XIVChatPlugin {
set => this._connected = value; set => this._connected = value;
} }
public TcpConnected(TcpClient client) { internal TcpConnected(TcpClient client) {
this.Client = client; this.Client = client;
this.Client.ReceiveTimeout = 5_000; this.Client.ReceiveTimeout = 5_000;
@ -126,7 +126,7 @@ namespace XIVChatPlugin {
} }
} }
public sealed class RelayConnected : BaseClient { internal sealed class RelayConnected : BaseClient {
internal byte[] PublicKey { get; } internal byte[] PublicKey { get; }
private ChannelWriter<IToRelay> ToRelay { get; } private ChannelWriter<IToRelay> ToRelay { get; }
@ -137,7 +137,7 @@ namespace XIVChatPlugin {
private List<byte> ReadBuffer { get; } = new(); private List<byte> ReadBuffer { get; } = new();
private List<byte> WriteBuffer { get; } = new(); private List<byte> WriteBuffer { get; } = new();
public RelayConnected(byte[] publicKey, IPAddress remote, ChannelWriter<IToRelay> toRelay, Channel<byte[]> fromRelay) { internal RelayConnected(byte[] publicKey, IPAddress remote, ChannelWriter<IToRelay> toRelay, Channel<byte[]> fromRelay) {
this.PublicKey = publicKey; this.PublicKey = publicKey;
this.Remote = remote; this.Remote = remote;
this.Connected = true; this.Connected = true;

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace XIVChatPlugin { namespace XIVChatPlugin {
[Serializable] [Serializable]
public class Configuration : IPluginConfiguration { internal class Configuration : IPluginConfiguration {
private Plugin? _plugin; private Plugin? _plugin;
public int Version { get; set; } = 1; public int Version { get; set; } = 1;
@ -28,11 +28,11 @@ namespace XIVChatPlugin {
public Dictionary<Guid, Tuple<string, byte[]>> TrustedKeys { get; set; } = new(); public Dictionary<Guid, Tuple<string, byte[]>> TrustedKeys { get; set; } = new();
public KeyPair? KeyPair { get; set; } public KeyPair? KeyPair { get; set; }
public void Initialise(Plugin plugin) { internal void Initialise(Plugin plugin) {
this._plugin = plugin; this._plugin = plugin;
} }
public void Save() { internal void Save() {
this._plugin?.Interface.SavePluginConfig(this); this._plugin?.Interface.SavePluginConfig(this);
} }
} }

View File

@ -0,0 +1,29 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Dalamud.Plugin;
namespace XIVChatPlugin {
// ReSharper disable once ClassNeverInstantiated.Global
public class DalamudPlugin : IDalamudPlugin {
public string Name => "XIVChat";
private Plugin? Plugin { get; set; }
// ReSharper disable once UnusedMember.Global
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local
internal string Location { get; private set; } = Assembly.GetExecutingAssembly().Location;
public void Initialize(DalamudPluginInterface pluginInterface) {
this.Plugin = new Plugin(this, pluginInterface);
}
public void Dispose() {
this.Plugin?.Dispose();
}
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private void SetLocation(string path) {
this.Location = path;
}
}
}

View File

@ -10,7 +10,7 @@ using Dalamud.Plugin;
using XIVChatCommon.Message; using XIVChatCommon.Message;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public class GameFunctions : IDisposable { internal class GameFunctions : IDisposable {
private Plugin Plugin { get; } private Plugin Plugin { get; }
private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr); private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr);
@ -66,15 +66,15 @@ namespace XIVChatPlugin {
private IntPtr _chatManager = IntPtr.Zero; private IntPtr _chatManager = IntPtr.Zero;
private readonly IntPtr _emptyXivString = IntPtr.Zero; private readonly IntPtr _emptyXivString = IntPtr.Zero;
public bool RequestingFriendList { get; private set; } internal bool RequestingFriendList { get; private set; }
private readonly List<Player> _friends = new(); private readonly List<Player> _friends = new();
public delegate void ReceiveFriendListHandler(List<Player> friends); internal delegate void ReceiveFriendListHandler(List<Player> friends);
public event ReceiveFriendListHandler? ReceiveFriendList; internal event ReceiveFriendListHandler? ReceiveFriendList;
public GameFunctions(Plugin plugin) { internal GameFunctions(Plugin plugin) {
this.Plugin = plugin; this.Plugin = plugin;
var getUiModulePtr = this.Plugin.ScanText("E8 ?? ?? ?? ?? 48 83 7F ?? 00 48 8B F0"); var getUiModulePtr = this.Plugin.ScanText("E8 ?? ?? ?? ?? 48 83 7F ?? 00 48 8B F0");
@ -208,7 +208,7 @@ namespace XIVChatPlugin {
return 1; return 1;
} }
public void ChangeChatChannel(InputChannel channel) { internal void ChangeChatChannel(InputChannel channel) {
if (this._chatManager == IntPtr.Zero || this._channelChangeCommand == null || this._emptyXivString == IntPtr.Zero) { if (this._chatManager == IntPtr.Zero || this._channelChangeCommand == null || this._emptyXivString == IntPtr.Zero) {
return; return;
} }
@ -219,7 +219,7 @@ namespace XIVChatPlugin {
// This function looks up a channel's user-defined colour. // This function looks up a channel's user-defined colour.
// //
// If this function would ever return 0, it returns null instead. // If this function would ever return 0, it returns null instead.
public uint? GetChannelColour(ChatCode channel) { internal uint? GetChannelColour(ChatCode channel) {
if (this.ColourLookup == IntPtr.Zero || this.ColourHandler == IntPtr.Zero) { if (this.ColourLookup == IntPtr.Zero || this.ColourHandler == IntPtr.Zero) {
return null; return null;
} }
@ -249,7 +249,7 @@ namespace XIVChatPlugin {
return 0xFF | (rgb << 8); return 0xFF | (rgb << 8);
} }
public void ProcessChatBox(string message) { internal void ProcessChatBox(string message) {
if (this._easierProcessChatBox == null || this.UiModulePtr == IntPtr.Zero) { if (this._easierProcessChatBox == null || this.UiModulePtr == IntPtr.Zero) {
return; return;
} }
@ -271,7 +271,7 @@ namespace XIVChatPlugin {
Marshal.FreeHGlobal(mem1); Marshal.FreeHGlobal(mem1);
} }
public bool RequestFriendList() { internal bool RequestFriendList() {
if (this._friendListManager == IntPtr.Zero || this._friendListHook == null) { if (this._friendListManager == IntPtr.Zero || this._friendListHook == null) {
return false; return false;
} }
@ -452,7 +452,7 @@ namespace XIVChatPlugin {
return nonNull.Length == 0 ? null : Encoding.UTF8.GetString(nonNull); return nonNull.Length == 0 ? null : Encoding.UTF8.GetString(nonNull);
} }
public string? Name() => HandleString(this.name); internal string? Name() => HandleString(this.name);
public string? FreeCompany() => HandleString(this.fc); internal string? FreeCompany() => HandleString(this.fc);
} }
} }

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using Dalamud.Game.ClientState.Actors.Types;
using Lumina.Excel.GeneratedSheets;
using XIVChatCommon.Message;
using XIVChatCommon.Message.Client;
using XIVChatCommon.Message.Server;
namespace XIVChatPlugin.Ipc {
internal class PeepingTom : IDisposable {
private Plugin Plugin { get; }
internal PeepingTom(Plugin plugin) {
this.Plugin = plugin;
#pragma warning disable 618
this.Plugin.Interface.Subscribe("PeepingTom", this.ReceiveTargeting);
#pragma warning restore 618
}
public void Dispose() {
#pragma warning disable 618
this.Plugin.Interface.Unsubscribe("PeepingTom");
#pragma warning restore 618
}
private void ReceiveTargeting(dynamic obj) {
List<ExpandoObject> list = obj.Targeting;
var players = list
.Select((dynamic player) => (uint) player.ActorId)
.Select(targeting => this.Plugin.Interface.ClientState.Actors.FirstOrDefault(actor => actor.ActorId == targeting))
.Where(actor => actor is PlayerCharacter)
.Cast<PlayerCharacter>()
.Select(chara => new Player {
Name = chara.Name,
FreeCompany = chara.CompanyTag,
Status = 0,
CurrentWorld = (ushort) chara.CurrentWorld.Id,
CurrentWorldName = chara.CurrentWorld.GameData.Name.ToString(),
HomeWorld = (ushort) chara.HomeWorld.Id,
HomeWorldName = chara.HomeWorld.GameData.Name.ToString(),
Territory = this.Plugin.Interface.ClientState.TerritoryType,
TerritoryName = this.Plugin.Interface.Data.GetExcelSheet<TerritoryType>().GetRow(this.Plugin.Interface.ClientState.TerritoryType)?.Name,
Job = (byte) chara.ClassJob.Id,
JobName = chara.ClassJob.GameData.Name.ToString(),
GrandCompany = 0,
GrandCompanyName = null,
Languages = 0,
MainLanguage = 0,
})
.ToArray();
foreach (var client in this.Plugin.Server.Clients.Values) {
if (!client.GetPreference(ClientPreference.TargetingListSupport, false)) {
continue;
}
client.Queue.Writer.TryWrite(new ServerPlayerList(PlayerListType.Targeting, players));
}
}
}
}

View File

@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public static unsafe class NativeTools { internal static unsafe class NativeTools {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private readonly struct RawVec { private readonly struct RawVec {
public readonly byte** pointer; public readonly byte** pointer;
@ -18,7 +18,7 @@ namespace XIVChatPlugin {
[DllImport("xivchat_native_tools.dll")] [DllImport("xivchat_native_tools.dll")]
private static extern void wrap_free(RawVec* raw); private static extern void wrap_free(RawVec* raw);
public static IEnumerable<string> Wrap(string input, uint width) { internal static IEnumerable<string> Wrap(string input, uint width) {
RawVec* raw; RawVec* raw;
fixed (byte* ptr = Encoding.UTF8.GetBytes(input).Terminate()) { fixed (byte* ptr = Encoding.UTF8.GetBytes(input).Terminate()) {
raw = wrap(ptr, width); raw = wrap(ptr, width);

View File

@ -2,42 +2,31 @@
using Dalamud.Plugin; using Dalamud.Plugin;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
#if DEBUG #if DEBUG
using System.IO; using System.IO;
#endif #endif
using System.Reflection;
namespace XIVChatPlugin { namespace XIVChatPlugin {
// ReSharper disable once ClassNeverInstantiated.Global internal class Plugin : IDisposable {
public class Plugin : IDalamudPlugin {
private bool _disposedValue; private bool _disposedValue;
public string Name => "XIVChat"; internal DalamudPluginInterface Interface { get; }
internal DalamudPlugin DalamudPlugin { get; }
internal Configuration Config { get; }
private PluginUi Ui { get; }
internal Server Server { get; private set; } = null!;
internal Relay? Relay { get; private set; }
internal GameFunctions Functions { get; }
private List<IDisposable> Ipcs { get; } = new();
// ReSharper disable once MemberCanBePrivate.Global internal Plugin(DalamudPlugin dalamudPlugin, DalamudPluginInterface pluginInterface) {
// ReSharper disable once UnusedAutoPropertyAccessor.Global this.Interface = pluginInterface;
internal string Location { get; private set; } = Assembly.GetExecutingAssembly().Location; this.DalamudPlugin = dalamudPlugin;
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private void SetLocation(string path) {
this.Location = path;
}
public DalamudPluginInterface Interface { get; private set; } = null!;
public Configuration Config { get; private set; } = null!;
private PluginUi Ui { get; set; } = null!;
public Server Server { get; private set; } = null!;
public Relay? Relay { get; private set; }
public GameFunctions Functions { get; private set; } = null!;
public void Initialize(DalamudPluginInterface pluginInterface) {
this.Interface = pluginInterface ?? throw new ArgumentNullException(nameof(pluginInterface), "DalamudPluginInterface cannot be null");
// load libsodium.so from debug location if in debug mode // load libsodium.so from debug location if in debug mode
#if DEBUG #if DEBUG
string path = Environment.GetEnvironmentVariable("PATH")!; string path = Environment.GetEnvironmentVariable("PATH")!;
string newPath = Path.GetDirectoryName(this.Location)!; string newPath = Path.GetDirectoryName(this.DalamudPlugin.Location)!;
Environment.SetEnvironmentVariable("PATH", $"{path};{newPath}"); Environment.SetEnvironmentVariable("PATH", $"{path};{newPath}");
#endif #endif
@ -64,6 +53,32 @@ namespace XIVChatPlugin {
this.Interface.CommandManager.AddHandler("/xivchat", new CommandInfo(this.OnCommand) { this.Interface.CommandManager.AddHandler("/xivchat", new CommandInfo(this.OnCommand) {
HelpMessage = "Opens the config for the XIVChat plugin", HelpMessage = "Opens the config for the XIVChat plugin",
}); });
this.Ipcs.Add(new Ipc.PeepingTom(this));
}
public void Dispose() {
if (this._disposedValue) {
return;
}
this._disposedValue = true;
this.Relay?.Dispose();
this.Server.Dispose();
this.Interface.UiBuilder.OnBuildUi -= this.Ui.Draw;
this.Interface.UiBuilder.OnOpenConfigUi -= this.Ui.OpenSettings;
this.Interface.Framework.OnUpdateEvent -= this.Server.OnFrameworkUpdate;
this.Interface.Framework.Gui.Chat.OnChatMessage -= this.Server.OnChat;
this.Interface.ClientState.OnLogin -= this.Server.OnLogIn;
this.Interface.ClientState.OnLogout -= this.Server.OnLogOut;
this.Interface.ClientState.TerritoryChanged -= this.Server.OnTerritoryChange;
this.Interface.CommandManager.RemoveHandler("/xivchat");
foreach (var ipc in this.Ipcs) {
ipc.Dispose();
}
} }
internal void StartRelay() { internal void StartRelay() {
@ -105,7 +120,7 @@ namespace XIVChatPlugin {
this.Server.Spawn(); this.Server.Spawn();
} }
public void RelaunchServer() { internal void RelaunchServer() {
this.Server.Dispose(); this.Server.Dispose();
this.LaunchServer(); this.LaunchServer();
} }
@ -113,34 +128,5 @@ namespace XIVChatPlugin {
private void OnCommand(string command, string args) { private void OnCommand(string command, string args) {
this.Ui.OpenSettings(null, null); this.Ui.OpenSettings(null, null);
} }
[SuppressMessage("ReSharper", "DelegateSubtraction")]
protected virtual void Dispose(bool disposing) {
if (this._disposedValue) {
return;
}
if (disposing) {
this.Relay?.Dispose();
this.Server.Dispose();
this.Interface.UiBuilder.OnBuildUi -= this.Ui.Draw;
this.Interface.UiBuilder.OnOpenConfigUi -= this.Ui.OpenSettings;
this.Interface.Framework.OnUpdateEvent -= this.Server.OnFrameworkUpdate;
this.Interface.Framework.Gui.Chat.OnChatMessage -= this.Server.OnChat;
this.Interface.ClientState.OnLogin -= this.Server.OnLogIn;
this.Interface.ClientState.OnLogout -= this.Server.OnLogOut;
this.Interface.ClientState.TerritoryChanged -= this.Server.OnTerritoryChange;
this.Interface.CommandManager.RemoveHandler("/xivchat");
}
this._disposedValue = true;
}
public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
this.Dispose(true);
GC.SuppressFinalize(this);
}
} }
} }

View File

@ -8,7 +8,7 @@ using System.Threading.Channels;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public class PluginUi { internal class PluginUi {
private Plugin Plugin { get; } private Plugin Plugin { get; }
private bool _showSettings; private bool _showSettings;
@ -21,23 +21,23 @@ namespace XIVChatPlugin {
private readonly Dictionary<Guid, Tuple<BaseClient, Channel<bool>>> _pending = new(); private readonly Dictionary<Guid, Tuple<BaseClient, Channel<bool>>> _pending = new();
private readonly Dictionary<Guid, string> _pendingNames = new(0); private readonly Dictionary<Guid, string> _pendingNames = new(0);
public PluginUi(Plugin plugin) { internal PluginUi(Plugin plugin) {
this.Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin), "Plugin cannot be null"); this.Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin), "Plugin cannot be null");
} }
private static class Colours { private static class Colours {
public static readonly Vector4 Primary = new(2 / 255f, 204 / 255f, 238 / 255f, 1.0f); internal static readonly Vector4 Primary = new(2 / 255f, 204 / 255f, 238 / 255f, 1.0f);
public static readonly Vector4 PrimaryDark = new(2 / 255f, 180 / 255f, 211 / 255f, 1.0f); internal static readonly Vector4 PrimaryDark = new(2 / 255f, 180 / 255f, 211 / 255f, 1.0f);
public static readonly Vector4 Background = new(46 / 255f, 46 / 255f, 46 / 255f, 1.0f); internal static readonly Vector4 Background = new(46 / 255f, 46 / 255f, 46 / 255f, 1.0f);
public static readonly Vector4 Text = new(190 / 255f, 190 / 255f, 190 / 255f, 1.0f); internal static readonly Vector4 Text = new(190 / 255f, 190 / 255f, 190 / 255f, 1.0f);
public static readonly Vector4 Button = new(90 / 255f, 89 / 255f, 90 / 255f, 1.0f); internal static readonly Vector4 Button = new(90 / 255f, 89 / 255f, 90 / 255f, 1.0f);
public static readonly Vector4 ButtonActive = new(123 / 255f, 122 / 255f, 124 / 255f, 1.0f); internal static readonly Vector4 ButtonActive = new(123 / 255f, 122 / 255f, 124 / 255f, 1.0f);
public static readonly Vector4 ButtonHovered = new(108 / 255f, 107 / 255f, 109 / 255f, 1.0f); internal static readonly Vector4 ButtonHovered = new(108 / 255f, 107 / 255f, 109 / 255f, 1.0f);
public static readonly Vector4 White = new(1f, 1f, 1f, 1f); internal static readonly Vector4 White = new(1f, 1f, 1f, 1f);
} }
public void Draw() { internal void Draw() {
ImGui.PushStyleColor(ImGuiCol.TitleBg, Colours.PrimaryDark); ImGui.PushStyleColor(ImGuiCol.TitleBg, Colours.PrimaryDark);
ImGui.PushStyleColor(ImGuiCol.TitleBgActive, Colours.Primary); ImGui.PushStyleColor(ImGuiCol.TitleBgActive, Colours.Primary);
ImGui.PushStyleColor(ImGuiCol.TitleBgCollapsed, Colours.PrimaryDark); ImGui.PushStyleColor(ImGuiCol.TitleBgCollapsed, Colours.PrimaryDark);
@ -102,7 +102,7 @@ namespace XIVChatPlugin {
} }
} }
if (!this.ShowSettings || !Begin(this.Plugin.Name, ref this._showSettings, ImGuiWindowFlags.AlwaysAutoResize)) { if (!this.ShowSettings || !Begin(this.Plugin.DalamudPlugin.Name, ref this._showSettings, ImGuiWindowFlags.AlwaysAutoResize)) {
return; return;
} }

View File

@ -10,21 +10,21 @@ using WebSocketSharp;
using XIVChatCommon.Message.Relay; using XIVChatCommon.Message.Relay;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public enum ConnectionStatus { internal enum ConnectionStatus {
Disconnected, Disconnected,
Connecting, Connecting,
Negotiating, Negotiating,
Connected, Connected,
} }
public class Relay : IDisposable { internal class Relay : IDisposable {
#if DEBUG #if DEBUG
private const string RelayUrl = "ws://localhost:14555/"; private const string RelayUrl = "ws://localhost:14555/";
#else #else
private const string RelayUrl = "wss://relay.xiv.chat/"; private const string RelayUrl = "wss://relay.xiv.chat/";
#endif #endif
public static string? ConnectionError { get; private set; } internal static string? ConnectionError { get; private set; }
private bool Disposed { get; set; } private bool Disposed { get; set; }
@ -34,7 +34,7 @@ namespace XIVChatPlugin {
private bool Running { get; set; } private bool Running { get; set; }
public ConnectionStatus Status { get; private set; } internal ConnectionStatus Status { get; private set; }
private Channel<IToRelay> ToRelay { get; } = Channel.CreateUnbounded<IToRelay>(); private Channel<IToRelay> ToRelay { get; } = Channel.CreateUnbounded<IToRelay>();

View File

@ -23,7 +23,7 @@ using XIVChatCommon.Message.Client;
using XIVChatCommon.Message.Server; using XIVChatCommon.Message.Server;
namespace XIVChatPlugin { namespace XIVChatPlugin {
public class Server : IDisposable { internal class Server : IDisposable {
private const int MaxMessageLength = 500; private const int MaxMessageLength = 500;
private static readonly string[] PublicPrefixes = { private static readonly string[] PublicPrefixes = {
@ -47,8 +47,8 @@ namespace XIVChatPlugin {
private readonly ConcurrentQueue<string> _toGame = new(); private readonly ConcurrentQueue<string> _toGame = new();
private readonly ConcurrentDictionary<Guid, BaseClient> _clients = new(); private readonly ConcurrentDictionary<Guid, BaseClient> _clients = new();
public IReadOnlyDictionary<Guid, BaseClient> Clients => this._clients; internal IReadOnlyDictionary<Guid, BaseClient> Clients => this._clients;
public readonly Channel<Tuple<BaseClient, Channel<bool>>> PendingClients = Channel.CreateUnbounded<Tuple<BaseClient, Channel<bool>>>(); internal readonly Channel<Tuple<BaseClient, Channel<bool>>> PendingClients = Channel.CreateUnbounded<Tuple<BaseClient, Channel<bool>>>();
private readonly HashSet<Guid> _waitingForFriendList = new(); private readonly HashSet<Guid> _waitingForFriendList = new();
@ -67,7 +67,7 @@ namespace XIVChatPlugin {
private const int MaxMessageSize = 128_000; private const int MaxMessageSize = 128_000;
public Server(Plugin plugin) { internal Server(Plugin plugin) {
this._plugin = plugin; this._plugin = plugin;
if (this._plugin.Config.KeyPair == null) { if (this._plugin.Config.KeyPair == null) {
this.RegenerateKeyPair(); this.RegenerateKeyPair();
@ -167,7 +167,7 @@ namespace XIVChatPlugin {
this._waitingForFriendList.Clear(); this._waitingForFriendList.Clear();
} }
public void Spawn() { internal void Spawn() {
var port = this._plugin.Config.Port; var port = this._plugin.Config.Port;
Task.Run(async () => { Task.Run(async () => {
@ -191,13 +191,12 @@ namespace XIVChatPlugin {
}); });
} }
public void RegenerateKeyPair() { internal void RegenerateKeyPair() {
this._plugin.Config.KeyPair = PublicKeyBox.GenerateKeyPair(); this._plugin.Config.KeyPair = PublicKeyBox.GenerateKeyPair();
this._plugin.Config.Save(); this._plugin.Config.Save();
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "delegate")] internal void OnChat(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) {
public void OnChat(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) {
if (isHandled) { if (isHandled) {
return; return;
} }
@ -245,8 +244,7 @@ namespace XIVChatPlugin {
} }
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "delegate")] internal void OnFrameworkUpdate(Framework framework) {
public void OnFrameworkUpdate(Framework framework) {
var player = this._plugin.Interface.ClientState.LocalPlayer; var player = this._plugin.Interface.ClientState.LocalPlayer;
if (player != null && this._sendPlayerData) { if (player != null && this._sendPlayerData) {
this.BroadcastPlayerData(); this.BroadcastPlayerData();
@ -482,7 +480,7 @@ namespace XIVChatPlugin {
this._waitingForFriendList.Add(id); this._waitingForFriendList.Add(id);
if (!this._plugin.Functions.RequestingFriendList && !this._plugin.Functions.RequestFriendList()) { if (!this._plugin.Functions.RequestingFriendList && !this._plugin.Functions.RequestFriendList()) {
this._plugin.Interface.Framework.Gui.Chat.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."); this._plugin.Interface.Framework.Gui.Chat.PrintError($"[{this._plugin.DalamudPlugin.Name}] Please open your friend list to enable friend list support. You should only need to do this on initial install or after updates.");
} }
} }
@ -500,18 +498,18 @@ namespace XIVChatPlugin {
} }
} }
public class NameFormatting { internal class NameFormatting {
public string Before { get; private set; } = string.Empty; internal string Before { get; private set; } = string.Empty;
public string After { get; private set; } = string.Empty; internal string After { get; private set; } = string.Empty;
public bool IsPresent { get; private set; } = true; internal bool IsPresent { get; private set; } = true;
public static NameFormatting Empty() { internal static NameFormatting Empty() {
return new() { return new() {
IsPresent = false, IsPresent = false,
}; };
} }
public static NameFormatting Of(string before, string after) { internal static NameFormatting Of(string before, string after) {
return new() { return new() {
Before = before, Before = before,
After = after, After = after,
@ -750,7 +748,7 @@ namespace XIVChatPlugin {
return this._plugin.Interface.Data.GetExcelSheet<LogFilter>().GetRow(rowId).Name; return this._plugin.Interface.Data.GetExcelSheet<LogFilter>().GetRow(rowId).Name;
} }
public void OnChatChannelChange(uint channel) { internal void OnChatChannelChange(uint channel) {
var inputChannel = (InputChannel) channel; var inputChannel = (InputChannel) channel;
this._currentChannel = inputChannel; this._currentChannel = inputChannel;
@ -785,18 +783,18 @@ namespace XIVChatPlugin {
this.BroadcastMessage(playerData); this.BroadcastMessage(playerData);
} }
public void OnLogIn(object sender, EventArgs e) { internal void OnLogIn(object sender, EventArgs e) {
this.BroadcastAvailability(true); this.BroadcastAvailability(true);
// send player data on next framework update // send player data on next framework update
this._sendPlayerData = true; this._sendPlayerData = true;
} }
public void OnLogOut(object sender, EventArgs e) { internal void OnLogOut(object sender, EventArgs e) {
this.BroadcastAvailability(false); this.BroadcastAvailability(false);
this.BroadcastPlayerData(); this.BroadcastPlayerData();
} }
public void OnTerritoryChange(object sender, ushort territoryId) => this._sendPlayerData = true; internal void OnTerritoryChange(object sender, ushort territoryId) => this._sendPlayerData = true;
public void Dispose() { public void Dispose() {
// stop accepting new clients // stop accepting new clients
@ -822,7 +820,7 @@ namespace XIVChatPlugin {
} }
internal static class TcpListenerExt { internal static class TcpListenerExt {
public static async Task<TcpClient?> GetTcpClient(this TcpListener listener, CancellationTokenSource source) { internal static async Task<TcpClient?> GetTcpClient(this TcpListener listener, CancellationTokenSource source) {
using (source.Token.Register(listener.Stop)) { using (source.Token.Register(listener.Stop)) {
try { try {
var client = await listener.AcceptTcpClientAsync().ConfigureAwait(false); var client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);

View File

@ -5,11 +5,11 @@ using System.Numerics;
namespace XIVChatPlugin { namespace XIVChatPlugin {
internal static class Util { internal static class Util {
public static string ToHexString(this IEnumerable<byte> bytes, bool upper = false, string separator = "") { internal static string ToHexString(this IEnumerable<byte> bytes, bool upper = false, string separator = "") {
return string.Join(separator, bytes.Select(b => b.ToString(upper ? "X2" : "x2"))); return string.Join(separator, bytes.Select(b => b.ToString(upper ? "X2" : "x2")));
} }
public static List<Vector4> ToColours(this byte[] bytes) { internal static List<Vector4> ToColours(this byte[] bytes) {
var colours = new List<Vector4>(); var colours = new List<Vector4>();
var colour = new Vector4(0f, 0f, 0f, 1f); var colour = new Vector4(0f, 0f, 0f, 1f);
@ -41,7 +41,7 @@ namespace XIVChatPlugin {
return colours; return colours;
} }
public static int IndexOfCount(this string source, char toFind, int position) { internal static int IndexOfCount(this string source, char toFind, int position) {
var index = -1; var index = -1;
for (var i = 0; i < position; i++) { for (var i = 0; i < position; i++) {
index = source.IndexOf(toFind, index + 1); index = source.IndexOf(toFind, index + 1);
@ -54,14 +54,14 @@ namespace XIVChatPlugin {
return index; return index;
} }
public static byte[] Terminate(this byte[] bytes) { internal static byte[] Terminate(this byte[] bytes) {
var terminated = new byte[bytes.Length + 1]; var terminated = new byte[bytes.Length + 1];
Array.Copy(bytes, terminated, bytes.Length); Array.Copy(bytes, terminated, bytes.Length);
terminated[terminated.Length - 1] = 0; terminated[terminated.Length - 1] = 0;
return terminated; return terminated;
} }
public static unsafe byte[] ReadTerminated(byte* mem) { internal static unsafe byte[] ReadTerminated(byte* mem) {
var bytes = new List<byte>(); var bytes = new List<byte>();
while (*mem != 0) { while (*mem != 0) {
bytes.Add(*mem); bytes.Add(*mem);

View File

@ -29,20 +29,21 @@
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="1.2.1"/> <PackageReference Include="DalamudPackager" Version="1.2.1" />
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.18.2"/> <PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.18.2" />
<PackageReference Include="MessagePack" Version="2.2.85"/> <PackageReference Include="MessagePack" Version="2.2.85" />
<PackageReference Include="Sodium.Core" Version="1.2.3"/> <PackageReference Include="Sodium.Core" Version="1.2.3" />
<PackageReference Include="System.Threading.Channels" Version="5.0.0"/> <PackageReference Include="System.Threading.Channels" Version="5.0.0" />
<PackageReference Include="WebSocketSharp" Version="1.0.3-rc11"/> <PackageReference Include="WebSocketSharp" Version="1.0.3-rc11" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\XIVChatCommon\XIVChatCommon.csproj"/> <ProjectReference Include="..\XIVChatCommon\XIVChatCommon.csproj" />
</ItemGroup> </ItemGroup>
<Target Name="CopyNativeLibraries" AfterTargets="AfterBuild"> <Target Name="CopyNativeLibraries" AfterTargets="AfterBuild">
<Copy SourceFiles="Resources\lib\libsodium.dll" DestinationFolder="$(OutDir)"/> <Copy SourceFiles="Resources\lib\libsodium.dll" DestinationFolder="$(OutDir)" />
<Copy SourceFiles="Resources\lib\xivchat_native_tools.dll" DestinationFolder="$(OutDir)"/> <Copy SourceFiles="Resources\lib\xivchat_native_tools.dll" DestinationFolder="$(OutDir)" />
</Target> </Target>
</Project> </Project>