Compare commits

...

No commits in common. "v1.17.2" and "main" have entirely different histories.

58 changed files with 6179 additions and 10127 deletions

View File

@ -1,63 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>1.17.2</Version> <Version>1.18.10</Version>
<TargetFramework>net5.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly> <ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<Dalamud>$(AppData)\XIVLauncher\addon\Hooks\dev</Dalamud> <DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev</DalamudLibPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'"> <PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
<Dalamud>$(DALAMUD_HOME)</Dalamud> <DalamudLibPath>$(DALAMUD_HOME)</DalamudLibPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(IsCI)' == 'true'"> <PropertyGroup Condition="'$(IsCI)' == 'true'">
<Dalamud>$(HOME)/dalamud</Dalamud> <DalamudLibPath>$(HOME)/dalamud</DalamudLibPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Dalamud"> <Reference Include="Dalamud">
<HintPath>$(Dalamud)\Dalamud.dll</HintPath> <HintPath>$(DalamudLibPath)\Dalamud.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="FFXIVClientStructs"> <Reference Include="FFXIVClientStructs">
<HintPath>$(Dalamud)\FFXIVClientStructs.dll</HintPath> <HintPath>$(DalamudLibPath)\FFXIVClientStructs.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="ImGui.NET"> <Reference Include="ImGui.NET">
<HintPath>$(Dalamud)\ImGui.NET.dll</HintPath> <HintPath>$(DalamudLibPath)\ImGui.NET.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ImGuiScene">
<HintPath>$(Dalamud)\ImGuiScene.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Lumina"> <Reference Include="Lumina">
<HintPath>$(Dalamud)\Lumina.dll</HintPath> <HintPath>$(DalamudLibPath)\Lumina.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Lumina.Excel"> <Reference Include="Lumina.Excel">
<HintPath>$(Dalamud)\Lumina.Excel.dll</HintPath> <HintPath>$(DalamudLibPath)\Lumina.Excel.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.6"/> <PackageReference Include="DalamudPackager" Version="2.1.12"/>
<PackageReference Include="LiteDB" Version="5.0.11"/> <PackageReference Include="LiteDB" Version="5.0.17"/>
<PackageReference Include="Pidgin" Version="3.1.0"/> <PackageReference Include="Pidgin" Version="3.2.2"/>
<PackageReference Include="SharpDX.Direct2D1" Version="4.2.0"/> <PackageReference Include="SharpDX.Direct2D1" Version="4.2.0"/>
<PackageReference Include="XivCommon" Version="5.0.1-alpha.1"/> <PackageReference Include="XivCommon" Version="9.0.0"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -87,8 +84,4 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="..\icon.png" Link="images/icon.png" CopyToOutputDirectory="PreserveNewest" Visible="false"/>
</ItemGroup>
</Project> </Project>

View File

@ -1,5 +1,5 @@
name: Chat 2 name: Chat 2
author: ascclemens author: Anna
punchline: Electric Boogaloo - ♪ A whole new chat, a new fantastic chat window ♪ punchline: Electric Boogaloo - ♪ A whole new chat, a new fantastic chat window ♪
description: |- description: |-
Chat 2 is a complete rewrite of the in-game chat window as a plugin. It Chat 2 is a complete rewrite of the in-game chat window as a plugin. It
@ -13,4 +13,6 @@ description: |-
- Sidebar tabs - Sidebar tabs
- Unread counts - Unread counts
- Screenshot mode (obfuscate names) - Screenshot mode (obfuscate names)
repo_url: https://git.annaclemens.io/ascclemens/ChatTwo repo_url: https://git.anna.lgbt/anna/ChatTwo
accepts_feedback: false
feedback_message: Submit only bugs to https://github.com/anna/plugin-issues

View File

@ -1,4 +1,4 @@
using Dalamud.Data; using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
namespace ChatTwo.Code; namespace ChatTwo.Code;
@ -82,7 +82,7 @@ internal static class InputChannelExt {
_ => "", _ => "",
}; };
public static IEnumerable<TextCommand>? TextCommands(this InputChannel channel, DataManager data) { public static IEnumerable<TextCommand>? TextCommands(this InputChannel channel, IDataManager data) {
var ids = channel switch { var ids = channel switch {
InputChannel.Tell => new uint[] { 104, 118 }, InputChannel.Tell => new uint[] { 104, 118 },
InputChannel.Say => new uint[] { 102 }, InputChannel.Say => new uint[] { 102 },

View File

@ -1,5 +1,4 @@
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Logging;
namespace ChatTwo; namespace ChatTwo;
@ -45,14 +44,14 @@ internal sealed class Commands : IDisposable {
private void Invoke(string command, string arguments) { private void Invoke(string command, string arguments) {
if (!this.Registered.TryGetValue(command, out var wrapper)) { if (!this.Registered.TryGetValue(command, out var wrapper)) {
PluginLog.Warning($"Missing registration for command {command}"); Plugin.Log.Warning($"Missing registration for command {command}");
return; return;
} }
try { try {
wrapper.Invoke(command, arguments); wrapper.Invoke(command, arguments);
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.Error(ex, $"Error while executing command {command}"); Plugin.Log.Error(ex, $"Error while executing command {command}");
} }
} }
} }

View File

@ -2,14 +2,14 @@ using ChatTwo.Code;
using ChatTwo.Resources; using ChatTwo.Resources;
using ChatTwo.Ui; using ChatTwo.Ui;
using Dalamud.Configuration; using Dalamud.Configuration;
using Dalamud.Logging;
using ImGuiNET; using ImGuiNET;
namespace ChatTwo; namespace ChatTwo;
[Serializable] [Serializable]
internal class Configuration : IPluginConfiguration { internal class Configuration : IPluginConfiguration {
private const int LatestVersion = 4; private const int LatestVersion = 5;
internal const int LatestDbVersion = 1;
public int Version { get; set; } = LatestVersion; public int Version { get; set; } = LatestVersion;
@ -49,6 +49,8 @@ internal class Configuration : IPluginConfiguration {
public Dictionary<ChatType, uint> ChatColours = new(); public Dictionary<ChatType, uint> ChatColours = new();
public List<Tab> Tabs = new(); public List<Tab> Tabs = new();
public uint DatabaseMigration = LatestDbVersion;
internal void UpdateFrom(Configuration other) { internal void UpdateFrom(Configuration other) {
this.HideChat = other.HideChat; this.HideChat = other.HideChat;
this.HideDuringCutscenes = other.HideDuringCutscenes; this.HideDuringCutscenes = other.HideDuringCutscenes;
@ -83,6 +85,7 @@ internal class Configuration : IPluginConfiguration {
this.WindowAlpha = other.WindowAlpha; this.WindowAlpha = other.WindowAlpha;
this.ChatColours = other.ChatColours.ToDictionary(entry => entry.Key, entry => entry.Value); this.ChatColours = other.ChatColours.ToDictionary(entry => entry.Key, entry => entry.Value);
this.Tabs = other.Tabs.Select(t => t.Clone()).ToList(); this.Tabs = other.Tabs.Select(t => t.Clone()).ToList();
this.DatabaseMigration = other.DatabaseMigration;
} }
public void Migrate() { public void Migrate() {
@ -110,9 +113,17 @@ internal class Configuration : IPluginConfiguration {
this.Version = 4; this.Version = 4;
this.WindowAlpha *= 100f; this.WindowAlpha *= 100f;
break;
case 4:
this.Version = 5;
foreach (var tab in this.Tabs) {
tab.ExtraChatAll = true;
}
break; break;
default: default:
PluginLog.Warning($"Couldn't migrate config version {this.Version}"); Plugin.Log.Warning($"Couldn't migrate config version {this.Version}");
loop = false; loop = false;
break; break;
} }
@ -147,6 +158,8 @@ internal static class UnreadModeExt {
internal class Tab { internal class Tab {
public string Name = Language.Tab_DefaultName; public string Name = Language.Tab_DefaultName;
public Dictionary<ChatType, ChatSource> ChatCodes = new(); public Dictionary<ChatType, ChatSource> ChatCodes = new();
public bool ExtraChatAll;
public HashSet<Guid> ExtraChatChannels = new();
[Obsolete("Use UnreadMode instead")] [Obsolete("Use UnreadMode instead")]
public bool DisplayUnread = true; public bool DisplayUnread = true;
@ -162,7 +175,7 @@ internal class Tab {
public uint Unread; public uint Unread;
[NonSerialized] [NonSerialized]
public Mutex MessagesMutex = new(); public SemaphoreSlim MessagesMutex = new(1, 1);
[NonSerialized] [NonSerialized]
public List<Message> Messages = new(); public List<Message> Messages = new();
@ -172,17 +185,22 @@ internal class Tab {
} }
internal bool Matches(Message message) { internal bool Matches(Message message) {
return message.Code.Type.IsGm() || this.ChatCodes.TryGetValue(message.Code.Type, out var sources) && (message.Code.Source is 0 or (ChatSource) 1 || sources.HasFlag(message.Code.Source)); if (message.ExtraChatChannel != Guid.Empty) {
return this.ExtraChatAll || this.ExtraChatChannels.Contains(message.ExtraChatChannel);
}
return message.Code.Type.IsGm()
|| this.ChatCodes.TryGetValue(message.Code.Type, out var sources) && (message.Code.Source is 0 or (ChatSource) 1 || sources.HasFlag(message.Code.Source));
} }
internal void AddMessage(Message message, bool unread = true) { internal void AddMessage(Message message, bool unread = true) {
this.MessagesMutex.WaitOne(); this.MessagesMutex.Wait();
this.Messages.Add(message); this.Messages.Add(message);
while (this.Messages.Count > Store.MessagesLimit) { while (this.Messages.Count > Store.MessagesLimit) {
this.Messages.RemoveAt(0); this.Messages.RemoveAt(0);
} }
this.MessagesMutex.ReleaseMutex(); this.MessagesMutex.Release();
if (unread) { if (unread) {
this.Unread += 1; this.Unread += 1;
@ -190,15 +208,17 @@ internal class Tab {
} }
internal void Clear() { internal void Clear() {
this.MessagesMutex.WaitOne(); this.MessagesMutex.Wait();
this.Messages.Clear(); this.Messages.Clear();
this.MessagesMutex.ReleaseMutex(); this.MessagesMutex.Release();
} }
internal Tab Clone() { internal Tab Clone() {
return new Tab { return new Tab {
Name = this.Name, Name = this.Name,
ChatCodes = this.ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value), ChatCodes = this.ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value),
ExtraChatAll = this.ExtraChatAll,
ExtraChatChannels = this.ExtraChatChannels.ToHashSet(),
#pragma warning disable CS0618 #pragma warning disable CS0618
DisplayUnread = this.DisplayUnread, DisplayUnread = this.DisplayUnread,
#pragma warning restore CS0618 #pragma warning restore CS0618
@ -258,8 +278,10 @@ internal enum LanguageOverride {
French, French,
German, German,
Greek, Greek,
// Italian, // Italian,
Japanese, Japanese,
// Korean, // Korean,
// Norwegian, // Norwegian,
PortugueseBrazil, PortugueseBrazil,

View File

@ -3,10 +3,11 @@ using ChatTwo.Code;
using ChatTwo.GameFunctions.Types; using ChatTwo.GameFunctions.Types;
using ChatTwo.Util; using ChatTwo.Util;
using Dalamud.Game.ClientState.Keys; using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.Config;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Logging;
using Dalamud.Memory; using Dalamud.Memory;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Framework; using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.System.Memory; using FFXIVClientStructs.FFXIV.Client.System.Memory;
@ -38,7 +39,7 @@ internal sealed unsafe class Chat : IDisposable {
[Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1 45 85 C9")] [Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1 45 85 C9")]
private readonly delegate* unmanaged<void*, int, IntPtr> _getTellHistory = null!; private readonly delegate* unmanaged<void*, int, IntPtr> _getTellHistory = null!;
[Signature("E8 ?? ?? ?? ?? B8 ?? ?? ?? ?? 48 8D 4D 50")] [Signature("E8 ?? ?? ?? ?? 48 8D 4D 50 E8 ?? ?? ?? ?? 48 8B 17")]
private readonly delegate* unmanaged<RaptureLogModule*, ushort, Utf8String*, Utf8String*, ulong, ushort, byte, int, byte, void> _printTell = null!; private readonly delegate* unmanaged<RaptureLogModule*, ushort, Utf8String*, Utf8String*, ulong, ushort, byte, int, byte, void> _printTell = null!;
[Signature("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D 8C 24 ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01")] [Signature("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D 8C 24 ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01")]
@ -53,9 +54,15 @@ internal sealed unsafe class Chat : IDisposable {
[Signature("3B 51 10 73 0F 8B C2 48 83 C0 0B")] [Signature("3B 51 10 73 0F 8B C2 48 83 C0 0B")]
private readonly delegate* unmanaged<IntPtr, uint, ulong*> _getLinkshellInfo = null!; private readonly delegate* unmanaged<IntPtr, uint, ulong*> _getLinkshellInfo = null!;
[Signature("E8 ?? ?? ?? ?? 4C 8B C0 FF C3")] [Signature("E8 ?? ?? ?? ?? 4C 8B C8 44 8D 47 01")]
private readonly delegate* unmanaged<IntPtr, ulong, byte*> _getLinkshellName = null!; private readonly delegate* unmanaged<IntPtr, ulong, byte*> _getLinkshellName = null!;
[Signature("40 56 41 54 41 55 41 57 48 83 EC 28 48 8B 01", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<UIModule*, int, ulong> _rotateLinkshellHistory;
[Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 20 48 8B 01 44 8B F2", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<UIModule*, int, ulong> _rotateCrossLinkshellHistory;
[Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B F2 48 8D B9")] [Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B F2 48 8D B9")]
private readonly delegate* unmanaged<IntPtr, uint, IntPtr> _getColourInfo = null!; private readonly delegate* unmanaged<IntPtr, uint, IntPtr> _getColourInfo = null!;
@ -109,6 +116,12 @@ internal sealed unsafe class Chat : IDisposable {
[Signature("4C 8D B6 ?? ?? ?? ?? 41 8B 1E 45 85 E4 74 7A 33 FF 8B EF 66 0F 1F 44 00", Offset = 3)] [Signature("4C 8D B6 ?? ?? ?? ?? 41 8B 1E 45 85 E4 74 7A 33 FF 8B EF 66 0F 1F 44 00", Offset = 3)]
private readonly int? _linkshellCycleOffset; private readonly int? _linkshellCycleOffset;
[Signature("BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B F0 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 10 33", Offset = 1)]
private readonly uint? _linkshellInfoProxyIdx;
[Signature("BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 89 6C 24 ?? 4C 8B E0 48 89 74 24", Offset = 1)]
private readonly uint? _crossLinkshellInfoProxyIdx;
#pragma warning restore 0649 #pragma warning restore 0649
// Pointers // Pointers
@ -130,7 +143,7 @@ internal sealed unsafe class Chat : IDisposable {
internal Chat(Plugin plugin) { internal Chat(Plugin plugin) {
this.Plugin = plugin; this.Plugin = plugin;
SignatureHelper.Initialise(this); this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
this.ChatLogRefreshHook?.Enable(); this.ChatLogRefreshHook?.Enable();
this.ChangeChannelNameHook?.Enable(); this.ChangeChannelNameHook?.Enable();
@ -139,7 +152,7 @@ internal sealed unsafe class Chat : IDisposable {
this.Plugin.Framework.Update += this.InterceptKeybinds; this.Plugin.Framework.Update += this.InterceptKeybinds;
this.Plugin.ClientState.Login += this.Login; this.Plugin.ClientState.Login += this.Login;
this.Login(null, null); this.Login();
} }
public void Dispose() { public void Dispose() {
@ -155,7 +168,11 @@ internal sealed unsafe class Chat : IDisposable {
} }
internal string? GetLinkshellName(uint idx) { internal string? GetLinkshellName(uint idx) {
var infoProxy = this.Plugin.Functions.GetInfoProxyByIndex(2); if (this._linkshellInfoProxyIdx is not { } proxyIdx) {
return null;
}
var infoProxy = this.Plugin.Functions.GetInfoProxyByIndex(proxyIdx);
if (infoProxy == IntPtr.Zero) { if (infoProxy == IntPtr.Zero) {
return null; return null;
} }
@ -170,7 +187,11 @@ internal sealed unsafe class Chat : IDisposable {
} }
internal string? GetCrossLinkshellName(uint idx) { internal string? GetCrossLinkshellName(uint idx) {
var infoProxy = this.Plugin.Functions.GetInfoProxyByIndex(26); if (this._crossLinkshellInfoProxyIdx is not { } proxyIdx) {
return null;
}
var infoProxy = this.Plugin.Functions.GetInfoProxyByIndex(proxyIdx);
if (infoProxy == IntPtr.Zero) { if (infoProxy == IntPtr.Zero) {
return null; return null;
} }
@ -186,12 +207,17 @@ internal sealed unsafe class Chat : IDisposable {
*(int*) (uiModule + this._linkshellCycleOffset.Value) = -1; *(int*) (uiModule + this._linkshellCycleOffset.Value) = -1;
} }
return RotateLinkshellHistoryInternal(201, mode); return RotateLinkshellHistoryInternal(this._rotateLinkshellHistory, mode);
} }
internal ulong RotateCrossLinkshellHistory(RotateMode mode) => RotateLinkshellHistoryInternal(203, mode); internal ulong RotateCrossLinkshellHistory(RotateMode mode) => RotateLinkshellHistoryInternal(this._rotateCrossLinkshellHistory, mode);
private static ulong RotateLinkshellHistoryInternal(delegate* unmanaged<UIModule*, int, ulong> func, RotateMode mode) {
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (func == null) {
return 0;
}
private static ulong RotateLinkshellHistoryInternal(int vfunc, RotateMode mode) {
var idx = mode switch { var idx = mode switch {
RotateMode.Forward => 1, RotateMode.Forward => 1,
RotateMode.Reverse => -1, RotateMode.Reverse => -1,
@ -199,8 +225,7 @@ internal sealed unsafe class Chat : IDisposable {
}; };
var uiModule = Framework.Instance()->GetUiModule(); var uiModule = Framework.Instance()->GetUiModule();
var cycleFunc = (delegate* unmanaged<UIModule*, int, ulong>) uiModule->vfunc[vfunc]; return func(uiModule, idx);
return cycleFunc(uiModule, idx);
} }
// This function looks up a channel's user-defined colour. // This function looks up a channel's user-defined colour.
@ -344,7 +369,7 @@ internal sealed unsafe class Chat : IDisposable {
} }
} }
private void InterceptKeybinds(Dalamud.Game.Framework framework) { private void InterceptKeybinds(IFramework framework1) {
this.CheckFocus(); this.CheckFocus();
this.UpdateKeybinds(); this.UpdateKeybinds();
@ -406,12 +431,12 @@ internal sealed unsafe class Chat : IDisposable {
TellReason = TellReason.Reply, TellReason = TellReason.Reply,
}); });
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event"); Plugin.Log.Error(ex, "Error in chat Activated event");
} }
} }
} }
private void Login(object? sender, EventArgs? e) { private void Login() {
if (this.ChangeChannelNameHook == null) { if (this.ChangeChannelNameHook == null) {
return; return;
} }
@ -430,10 +455,8 @@ internal sealed unsafe class Chat : IDisposable {
} }
string? input = null; string? input = null;
var option = Framework.Instance()->GetUiModule()->GetConfigModule()->GetValueById(572); if (this.Plugin.GameConfig.TryGet(UiControlOption.DirectChat, out bool option) && option) {
if (option != null) { if (this._currentCharacter != null) {
var directChat = option->Int > 0;
if (directChat && this._currentCharacter != null) {
// FIXME: this whole system sucks // FIXME: this whole system sucks
var c = *this._currentCharacter; var c = *this._currentCharacter;
if (c != '\0' && !char.IsControl(c)) { if (c != '\0' && !char.IsControl(c)) {
@ -459,7 +482,7 @@ internal sealed unsafe class Chat : IDisposable {
}; };
this.Activated?.Invoke(args); this.Activated?.Invoke(args);
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event"); Plugin.Log.Error(ex, "Error in chat Activated event");
} }
// prevent the game from focusing the chat log // prevent the game from focusing the chat log
@ -542,7 +565,7 @@ internal sealed unsafe class Chat : IDisposable {
TellTarget = target, TellTarget = target,
}); });
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event"); Plugin.Log.Error(ex, "Error in chat Activated event");
} }
} }
@ -568,7 +591,7 @@ internal sealed unsafe class Chat : IDisposable {
idx = 0; idx = 0;
} }
this._changeChatChannel(RaptureShellModule.Instance, (int) channel, idx, target, 1); this._changeChatChannel(RaptureShellModule.Instance(), (int) channel, idx, target, 1);
target->Dtor(); target->Dtor();
IMemorySpace.Free(target); IMemorySpace.Free(target);
} }

View File

@ -20,17 +20,27 @@ internal sealed unsafe class Context {
[Signature("E8 ?? ?? ?? ?? EB 3F 83 F8 FE", Fallibility = Fallibility.Fallible)] [Signature("E8 ?? ?? ?? ?? EB 3F 83 F8 FE", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<AgentInterface*, ushort, uint, byte, void> _itemComparison = null!; private readonly delegate* unmanaged<AgentInterface*, ushort, uint, byte, void> _itemComparison = null!;
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 41 B4 01", Fallibility = Fallibility.Fallible)] [Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 83 F8 0F", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<IntPtr, uint, void> _searchForRecipesUsingItem = null!; private readonly delegate* unmanaged<IntPtr, uint, void> _searchForRecipesUsingItem = null!;
[Signature("E8 ?? ?? ?? ?? EB 45 45 33 C9", Fallibility = Fallibility.Fallible)] [Signature("E8 ?? ?? ?? ?? EB 45 45 33 C9", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<void*, uint, byte, void> _searchForItem = null!; private readonly delegate* unmanaged<void*, uint, byte, void> _searchForItem = null!;
#region Offsets
[Signature(
"FF 90 ?? ?? ?? ?? 8B 93 ?? ?? ?? ?? 48 8B C8 E8 ?? ?? ?? ?? 41 0F B6 D4 48 8B CB E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 81 FF ?? ?? ?? ?? 0F 85",
Offset = 2
)]
private readonly int? _searchForRecipesUsingItemVfunc;
#endregion
private Plugin Plugin { get; } private Plugin Plugin { get; }
internal Context(Plugin plugin) { internal Context(Plugin plugin) {
this.Plugin = plugin; this.Plugin = plugin;
SignatureHelper.Initialise(this); this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
} }
internal void InviteToNoviceNetwork(string name, ushort world) { internal void InviteToNoviceNetwork(string name, ushort world) {
@ -38,8 +48,8 @@ internal sealed unsafe class Context {
return; return;
} }
// 6.05: 20E4CB // 6.3: 221EFD
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(0x11); var a1 = this.Plugin.Functions.GetInfoProxyByIndex(0x14);
fixed (byte* namePtr = name.ToTerminatedBytes()) { fixed (byte* namePtr = name.ToTerminatedBytes()) {
// can specify content id if we have it, but there's no need // can specify content id if we have it, but there's no need
@ -82,13 +92,13 @@ internal sealed unsafe class Context {
} }
internal void SearchForRecipesUsingItem(uint itemId) { internal void SearchForRecipesUsingItem(uint itemId) {
if (this._searchForRecipesUsingItem == null) { if (this._searchForRecipesUsingItem == null || this._searchForRecipesUsingItemVfunc is not { } offset) {
return; return;
} }
var uiModule = Framework.Instance()->GetUiModule(); var uiModule = Framework.Instance()->GetUiModule();
var vf36 = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[36]; var vf = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[offset / 8];
var a1 = vf36(uiModule); var a1 = vf(uiModule);
this._searchForRecipesUsingItem(a1, itemId); this._searchForRecipesUsingItem(a1, itemId);
} }

View File

@ -33,7 +33,7 @@ internal unsafe class GameFunctions : IDisposable {
[Signature("E8 ?? ?? ?? ?? EB 20 48 8B 46 28", Fallibility = Fallibility.Fallible)] [Signature("E8 ?? ?? ?? ?? EB 20 48 8B 46 28", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<AgentInterface*, uint, void> _openAchievement = null!; private readonly delegate* unmanaged<AgentInterface*, uint, void> _openAchievement = null!;
[Signature("E8 ?? ?? ?? ?? 84 C0 49 8B DE", Fallibility = Fallibility.Fallible)] [Signature("E8 ?? ?? ?? ?? 41 8D 4F 08 84 C0", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged<byte> _inInstance = null!; private readonly delegate* unmanaged<byte> _inInstance = null!;
#endregion #endregion
@ -57,6 +57,9 @@ internal unsafe class GameFunctions : IDisposable {
#pragma warning restore 0649 #pragma warning restore 0649
[Signature("FF 90 ?? ?? ?? ?? 48 8B C8 BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B F0 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 10 33 ED", Offset = 2)]
private readonly int? _infoModuleVfunc;
private Plugin Plugin { get; } private Plugin Plugin { get; }
internal Party Party { get; } internal Party Party { get; }
internal Chat Chat { get; } internal Chat Chat { get; }
@ -68,7 +71,7 @@ internal unsafe class GameFunctions : IDisposable {
this.Chat = new Chat(this.Plugin); this.Chat = new Chat(this.Plugin);
this.Context = new Context(this.Plugin); this.Context = new Context(this.Plugin);
SignatureHelper.Initialise(this); this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
this.ResolveTextCommandPlaceholderHook?.Enable(); this.ResolveTextCommandPlaceholderHook?.Enable();
} }
@ -81,14 +84,18 @@ internal unsafe class GameFunctions : IDisposable {
Marshal.FreeHGlobal(this._placeholderNamePtr); Marshal.FreeHGlobal(this._placeholderNamePtr);
} }
private static IntPtr GetInfoModule() { private IntPtr GetInfoModule() {
if (this._infoModuleVfunc is not { } vfunc) {
return IntPtr.Zero;
}
var uiModule = Framework.Instance()->GetUiModule(); var uiModule = Framework.Instance()->GetUiModule();
var getInfoModule = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[33]; var getInfoModule = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[vfunc / 8];
return getInfoModule(uiModule); return getInfoModule(uiModule);
} }
internal IntPtr GetInfoProxyByIndex(uint idx) { internal IntPtr GetInfoProxyByIndex(uint idx) {
var infoModule = GetInfoModule(); var infoModule = this.GetInfoModule();
return infoModule == IntPtr.Zero ? IntPtr.Zero : this._getInfoProxyByIndex(infoModule, idx); return infoModule == IntPtr.Zero ? IntPtr.Zero : this._getInfoProxyByIndex(infoModule, idx);
} }
@ -189,7 +196,7 @@ internal unsafe class GameFunctions : IDisposable {
// this just probably needs to be set // this just probably needs to be set
agent->AddonId = addon->ID; agent->AddonId = addon->ID;
// vcall from E8 ?? ?? ?? ?? 0F B7 C0 48 83 C4 60 // vcall from E8 ?? ?? ?? ?? 0F B7 C0 48 83 C4 60 (FF 50 28 48 8B D3 48 8B CF)
var vf5 = (delegate* unmanaged<AtkUnitBase*, byte, uint, void>*) ((IntPtr) addon->VTable + 40); var vf5 = (delegate* unmanaged<AtkUnitBase*, byte, uint, void>*) ((IntPtr) addon->VTable + 40);
// EA8BED: lets vf5 actually run // EA8BED: lets vf5 actually run
*(byte*) ((IntPtr) atkStage + 0x2B4) |= 2; *(byte*) ((IntPtr) atkStage + 0x2B4) |= 2;
@ -200,7 +207,7 @@ internal unsafe class GameFunctions : IDisposable {
// hide addon first to prevent the "addon close" sound // hide addon first to prevent the "addon close" sound
var addon = AtkStage.GetSingleton()->RaptureAtkUnitManager->GetAddonByName("ItemDetail"); var addon = AtkStage.GetSingleton()->RaptureAtkUnitManager->GetAddonByName("ItemDetail");
if (addon != null) { if (addon != null) {
addon->Hide(true); addon->Hide(true, false, 0);
} }
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail); var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail);
@ -210,7 +217,7 @@ internal unsafe class GameFunctions : IDisposable {
} }
internal static void OpenPartyFinder() { internal static void OpenPartyFinder() {
// this whole method: 6.05: 84433A // this whole method: 6.05: 84433A (FF 97 ?? ?? ?? ?? 41 B4 01)
var lfg = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup); var lfg = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup);
if (lfg->IsAgentActive()) { if (lfg->IsAgentActive()) {
var addonId = lfg->GetAddonID(); var addonId = lfg->GetAddonID();
@ -220,7 +227,7 @@ internal unsafe class GameFunctions : IDisposable {
vf27(atkModule, addonId, 1); vf27(atkModule, addonId, 1);
} else { } else {
// 6.05: 8443DD // 6.05: 8443DD
if (*(uint*) ((IntPtr) lfg + 0x2AB8) > 0) { if (*(uint*) ((IntPtr) lfg + 0x2C20) > 0) {
lfg->Hide(); lfg->Hide();
} else { } else {
lfg->Show(); lfg->Show();
@ -273,7 +280,7 @@ internal unsafe class GameFunctions : IDisposable {
Type = ValueType.Int, Type = ValueType.Int,
Int = 3, Int = 3,
}; };
int result = 0; var result = 0;
var vf0 = *(delegate* unmanaged<AgentInterface*, int*, AtkValue*, ulong, ulong, int*>*) agent->VTable; var vf0 = *(delegate* unmanaged<AgentInterface*, int*, AtkValue*, ulong, ulong, int*>*) agent->VTable;
vf0(agent, &result, &value, 0, 0); vf0(agent, &result, &value, 0, 0);
} }

View File

@ -26,7 +26,7 @@ internal sealed unsafe class Party {
internal Party(Plugin plugin) { internal Party(Plugin plugin) {
this.Plugin = plugin; this.Plugin = plugin;
SignatureHelper.Initialise(this); this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
} }
internal void InviteSameWorld(string name, ushort world, ulong contentId) { internal void InviteSameWorld(string name, ushort world, ulong contentId) {
@ -35,7 +35,7 @@ internal sealed unsafe class Party {
} }
// 6.11: 214A55 // 6.11: 214A55
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(1); var a1 = this.Plugin.Functions.GetInfoProxyByIndex(2);
fixed (byte* namePtr = name.ToTerminatedBytes()) { fixed (byte* namePtr = name.ToTerminatedBytes()) {
// this only works if target is on the same world // this only works if target is on the same world
this._inviteToParty(a1, contentId, namePtr, world); this._inviteToParty(a1, contentId, namePtr, world);
@ -48,7 +48,7 @@ internal sealed unsafe class Party {
} }
// 6.11: 214A55 // 6.11: 214A55
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(1); var a1 = this.Plugin.Functions.GetInfoProxyByIndex(2);
if (contentId != 0) { if (contentId != 0) {
// third param is world, but it requires a specific world // third param is world, but it requires a specific world
// if they're not on that world, it will fail // if they're not on that world, it will fail
@ -64,7 +64,7 @@ internal sealed unsafe class Party {
} }
// 6.11: 214A55 // 6.11: 214A55
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(1); var a1 = this.Plugin.Functions.GetInfoProxyByIndex(2);
if (contentId != 0) { if (contentId != 0) {
// third param is world, but it requires a specific world // third param is world, but it requires a specific world
// if they're not on that world, it will fail // if they're not on that world, it will fail

View File

@ -14,30 +14,34 @@ internal sealed class ExtraChat : IDisposable {
private ICallGateSubscriber<OverrideInfo, object> OverrideChannelGate { get; } private ICallGateSubscriber<OverrideInfo, object> OverrideChannelGate { get; }
private ICallGateSubscriber<Dictionary<string, uint>, Dictionary<string, uint>> ChannelCommandColoursGate { get; } private ICallGateSubscriber<Dictionary<string, uint>, Dictionary<string, uint>> ChannelCommandColoursGate { get; }
private ICallGateSubscriber<Dictionary<Guid, string>, Dictionary<Guid, string>> ChannelNamesGate { get; }
internal (string, uint)? ChannelOverride { get; set; } internal (string, uint)? ChannelOverride { get; set; }
private Dictionary<string, uint> ChannelCommandColoursInternal { get; set; } = new(); private Dictionary<string, uint> ChannelCommandColoursInternal { get; set; } = new();
internal IReadOnlyDictionary<string, uint> ChannelCommandColours => this.ChannelCommandColoursInternal; internal IReadOnlyDictionary<string, uint> ChannelCommandColours => this.ChannelCommandColoursInternal;
private Dictionary<Guid, string> ChannelNamesInternal { get; set; } = new();
internal IReadOnlyDictionary<Guid, string> ChannelNames => this.ChannelNamesInternal;
internal ExtraChat(Plugin plugin) { internal ExtraChat(Plugin plugin) {
this.Plugin = plugin; this.Plugin = plugin;
this.OverrideChannelGate = this.Plugin.Interface.GetIpcSubscriber<OverrideInfo, object>("ExtraChat.OverrideChannelColour"); this.OverrideChannelGate = this.Plugin.Interface.GetIpcSubscriber<OverrideInfo, object>("ExtraChat.OverrideChannelColour");
this.ChannelCommandColoursGate = this.Plugin.Interface.GetIpcSubscriber<Dictionary<string, uint>, Dictionary<string, uint>>("ExtraChat.ChannelCommandColours"); this.ChannelCommandColoursGate = this.Plugin.Interface.GetIpcSubscriber<Dictionary<string, uint>, Dictionary<string, uint>>("ExtraChat.ChannelCommandColours");
this.ChannelNamesGate = this.Plugin.Interface.GetIpcSubscriber<Dictionary<Guid, string>, Dictionary<Guid, string>>("ExtraChat.ChannelNames");
this.OverrideChannelGate.Subscribe(this.OnOverrideChannel); this.OverrideChannelGate.Subscribe(this.OnOverrideChannel);
this.ChannelCommandColoursGate.Subscribe(this.OnChannelCommandColours); this.ChannelCommandColoursGate.Subscribe(this.OnChannelCommandColours);
this.ChannelNamesGate.Subscribe(this.OnChannelNames);
try { try {
this.ChannelCommandColoursInternal = this.ChannelCommandColoursGate.InvokeFunc(null!); this.ChannelCommandColoursInternal = this.ChannelCommandColoursGate.InvokeFunc(null!);
this.ChannelNamesInternal = this.ChannelNamesGate.InvokeFunc(null!);
} catch (Exception) { } catch (Exception) {
// no-op // no-op
} }
} }
private void OnChannelCommandColours(Dictionary<string, uint> obj) {
this.ChannelCommandColoursInternal = obj;
}
public void Dispose() { public void Dispose() {
this.OverrideChannelGate.Unsubscribe(this.OnOverrideChannel); this.OverrideChannelGate.Unsubscribe(this.OnOverrideChannel);
} }
@ -50,4 +54,12 @@ internal sealed class ExtraChat : IDisposable {
this.ChannelOverride = (info.Channel, info.Rgba); this.ChannelOverride = (info.Channel, info.Rgba);
} }
private void OnChannelCommandColours(Dictionary<string, uint> obj) {
this.ChannelCommandColoursInternal = obj;
}
private void OnChannelNames(Dictionary<Guid, string> obj) {
this.ChannelNamesInternal = obj;
}
} }

View File

@ -1,5 +1,6 @@
using ChatTwo.Code; using ChatTwo.Code;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using LiteDB; using LiteDB;
namespace ChatTwo; namespace ChatTwo;
@ -60,6 +61,7 @@ internal class Message {
internal SeString ContentSource { get; } internal SeString ContentSource { get; }
internal SortCode SortCode { get; } internal SortCode SortCode { get; }
internal Guid ExtraChatChannel { get; }
internal int Hash { get; } internal int Hash { get; }
@ -72,6 +74,7 @@ internal class Message {
this.SenderSource = senderSource; this.SenderSource = senderSource;
this.ContentSource = contentSource; this.ContentSource = contentSource;
this.SortCode = new SortCode(this.Code.Type, this.Code.Source); this.SortCode = new SortCode(this.Code.Type, this.Code.Source);
this.ExtraChatChannel = this.ExtractExtraChatChannel();
this.Hash = this.GenerateHash(); this.Hash = this.GenerateHash();
foreach (var chunk in sender.Concat(content)) { foreach (var chunk in sender.Concat(content)) {
@ -90,6 +93,26 @@ internal class Message {
this.SenderSource = BsonMapper.Global.Deserialize<SeString>(senderSource); this.SenderSource = BsonMapper.Global.Deserialize<SeString>(senderSource);
this.ContentSource = BsonMapper.Global.Deserialize<SeString>(contentSource); this.ContentSource = BsonMapper.Global.Deserialize<SeString>(contentSource);
this.SortCode = BsonMapper.Global.ToObject<SortCode>(sortCode); this.SortCode = BsonMapper.Global.ToObject<SortCode>(sortCode);
this.ExtraChatChannel = this.ExtractExtraChatChannel();
this.Hash = this.GenerateHash();
foreach (var chunk in this.Sender.Concat(this.Content)) {
chunk.Message = this;
}
}
internal Message(ObjectId id, ulong receiver, ulong contentId, DateTime date, BsonDocument code, BsonArray sender, BsonArray content, BsonValue senderSource, BsonValue contentSource, BsonDocument sortCode, BsonValue extraChatChannel) {
this.Id = id;
this.Receiver = receiver;
this.ContentId = contentId;
this.Date = date;
this.Code = BsonMapper.Global.ToObject<ChatCode>(code);
this.Sender = BsonMapper.Global.Deserialize<List<Chunk>>(sender);
this.Content = BsonMapper.Global.Deserialize<List<Chunk>>(content);
this.SenderSource = BsonMapper.Global.Deserialize<SeString>(senderSource);
this.ContentSource = BsonMapper.Global.Deserialize<SeString>(contentSource);
this.SortCode = BsonMapper.Global.ToObject<SortCode>(sortCode);
this.ExtraChatChannel = BsonMapper.Global.Deserialize<Guid>(extraChatChannel);
this.Hash = this.GenerateHash(); this.Hash = this.GenerateHash();
foreach (var chunk in this.Sender.Concat(this.Content)) { foreach (var chunk in this.Sender.Concat(this.Content)) {
@ -99,7 +122,20 @@ internal class Message {
private int GenerateHash() { private int GenerateHash() {
return this.SortCode.GetHashCode() return this.SortCode.GetHashCode()
^ this.ExtraChatChannel.GetHashCode()
^ string.Join("", this.Sender.Select(c => c.StringValue())).GetHashCode() ^ string.Join("", this.Sender.Select(c => c.StringValue())).GetHashCode()
^ string.Join("", this.Content.Select(c => c.StringValue())).GetHashCode(); ^ string.Join("", this.Content.Select(c => c.StringValue())).GetHashCode();
} }
private Guid ExtractExtraChatChannel() {
if (this.ContentSource.Payloads.Count > 0 && this.ContentSource.Payloads[0] is RawPayload raw) {
// this does an encode and clone every time it's accessed, so cache
var data = raw.Data;
if (data[1] == 0x27 && data[2] == 18 && data[3] == 0x20) {
return new Guid(data[4..^1]);
}
}
return Guid.Empty;
}
} }

View File

@ -7,13 +7,14 @@ using ChatTwo.Util;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface; using Dalamud.Interface.Internal;
using Dalamud.Logging; using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using ImGuiScene;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using Action = System.Action; using Action = System.Action;
using DalamudPartyFinderPayload = Dalamud.Game.Text.SeStringHandling.Payloads.PartyFinderPayload;
using ChatTwoPartyFinderPayload = ChatTwo.Util.PartyFinderPayload;
namespace ChatTwo; namespace ChatTwo;
@ -99,7 +100,7 @@ internal sealed class PayloadHandler {
try { try {
this.Ui.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource); this.Ui.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource);
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.Error(ex, "Error executing integration"); Plugin.Log.Error(ex, "Error executing integration");
} }
} }
@ -118,7 +119,7 @@ internal sealed class PayloadHandler {
ImGui.Separator(); ImGui.Separator();
} }
if (!ImGui.BeginMenu(this.Ui.Plugin.Name)) { if (!ImGui.BeginMenu(Plugin.Name)) {
return; return;
} }
@ -214,7 +215,7 @@ internal sealed class PayloadHandler {
} }
} }
private static void InlineIcon(TextureWrap icon) { private static void InlineIcon(IDalamudTextureWrap icon) {
var lineHeight = ImGui.CalcTextSize("A").Y; var lineHeight = ImGui.CalcTextSize("A").Y;
var cursor = ImGui.GetCursorPos(); var cursor = ImGui.GetCursorPos();
@ -294,7 +295,16 @@ internal sealed class PayloadHandler {
this.ClickLinkPayload(chunk, payload, link); this.ClickLinkPayload(chunk, payload, link);
break; break;
} }
case PartyFinderPayload pf: { case DalamudPartyFinderPayload pf: {
if (pf.LinkType == DalamudPartyFinderPayload.PartyFinderLinkType.PartyFinderNotification) {
GameFunctions.GameFunctions.OpenPartyFinder();
} else {
this.Ui.Plugin.Functions.OpenPartyFinder(pf.ListingId);
}
break;
}
case ChatTwoPartyFinderPayload pf: {
this.Ui.Plugin.Functions.OpenPartyFinder(pf.Id); this.Ui.Plugin.Functions.OpenPartyFinder(pf.Id);
break; break;
} }
@ -325,16 +335,25 @@ internal sealed class PayloadHandler {
var payloads = source.Payloads.Skip(start).Take(end - start + 1).ToList(); var payloads = source.Payloads.Skip(start).Take(end - start + 1).ToList();
var chatGui = this.Ui.Plugin.ChatGui; var chatGuiScoped = this.Ui.Plugin.ChatGui;
var field = chatGui.GetType().GetField("dalamudLinkHandlers", BindingFlags.Instance | BindingFlags.NonPublic); var chatGuiService = chatGuiScoped.GetType()
if (field == null || field.GetValue(chatGui) is not Dictionary<(string PluginName, uint CommandId), Action<uint, SeString>> dict || !dict.TryGetValue((link.Plugin, link.CommandId), out var action)) { .GetField("chatGuiService", BindingFlags.Instance | BindingFlags.NonPublic)!
.GetValue(chatGuiScoped);
if (chatGuiService == null) {
Plugin.Log.Warning("could not find chatGuiService");
return;
}
var field = chatGuiService.GetType().GetField("dalamudLinkHandlers", BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null || field.GetValue(chatGuiService) is not Dictionary<(string PluginName, uint CommandId), Action<uint, SeString>> dict || !dict.TryGetValue((link.Plugin, link.CommandId), out var action)) {
Plugin.Log.Warning("could not find dalamudLinkHandlers");
return; return;
} }
try { try {
action(link.CommandId, new SeString(payloads)); action(link.CommandId, new SeString(payloads));
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error executing DalamudLinkPayload handler"); Plugin.Log.Error(ex, "Error executing DalamudLinkPayload handler");
} }
} }
@ -520,7 +539,7 @@ internal sealed class PayloadHandler {
} }
if (ImGui.Selectable(Language.Context_Target) && this.FindCharacterForPayload(player) is { } obj) { if (ImGui.Selectable(Language.Context_Target) && this.FindCharacterForPayload(player) is { } obj) {
this.Ui.Plugin.TargetManager.SetTarget(obj); this.Ui.Plugin.TargetManager.Target = obj;
} }
// View Party Finder 0x2E // View Party Finder 0x2E

View File

@ -3,17 +3,10 @@ using System.Globalization;
using ChatTwo.Ipc; using ChatTwo.Ipc;
using ChatTwo.Resources; using ChatTwo.Resources;
using ChatTwo.Util; using ChatTwo.Util;
using Dalamud.Data;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Party;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using XivCommon; using XivCommon;
namespace ChatTwo; namespace ChatTwo;
@ -22,43 +15,55 @@ namespace ChatTwo;
public sealed class Plugin : IDalamudPlugin { public sealed class Plugin : IDalamudPlugin {
internal const string PluginName = "Chat 2"; internal const string PluginName = "Chat 2";
public string Name => PluginName; internal static string Name => PluginName;
[PluginService]
internal static IPluginLog Log { get; private set; }
[PluginService] [PluginService]
internal DalamudPluginInterface Interface { get; init; } internal DalamudPluginInterface Interface { get; init; }
[PluginService] [PluginService]
internal ChatGui ChatGui { get; init; } internal IChatGui ChatGui { get; init; }
[PluginService] [PluginService]
internal ClientState ClientState { get; init; } internal IClientState ClientState { get; init; }
[PluginService] [PluginService]
internal CommandManager CommandManager { get; init; } internal ICommandManager CommandManager { get; init; }
[PluginService] [PluginService]
internal Condition Condition { get; init; } internal ICondition Condition { get; init; }
[PluginService] [PluginService]
internal DataManager DataManager { get; init; } internal IDataManager DataManager { get; init; }
[PluginService] [PluginService]
internal Framework Framework { get; init; } internal IFramework Framework { get; init; }
[PluginService] [PluginService]
internal GameGui GameGui { get; init; } internal IGameGui GameGui { get; init; }
[PluginService] [PluginService]
internal KeyState KeyState { get; init; } internal IKeyState KeyState { get; init; }
[PluginService] [PluginService]
internal ObjectTable ObjectTable { get; init; } internal IObjectTable ObjectTable { get; init; }
[PluginService] [PluginService]
internal PartyList PartyList { get; init; } internal IPartyList PartyList { get; init; }
[PluginService] [PluginService]
internal TargetManager TargetManager { get; init; } internal ITargetManager TargetManager { get; init; }
[PluginService]
internal ITextureProvider TextureProvider { get; init; }
[PluginService]
internal IGameInteropProvider GameInteropProvider { get; init; }
[PluginService]
internal IGameConfig GameConfig { get; init; }
internal Configuration Config { get; } internal Configuration Config { get; }
internal Commands Commands { get; } internal Commands Commands { get; }
@ -88,8 +93,8 @@ public sealed class Plugin : IDalamudPlugin {
this.LanguageChanged(this.Interface.UiLanguage); this.LanguageChanged(this.Interface.UiLanguage);
this.Commands = new Commands(this); this.Commands = new Commands(this);
this.Common = new XivCommonBase(); this.Common = new XivCommonBase(this.Interface);
this.TextureCache = new TextureCache(this.DataManager!); this.TextureCache = new TextureCache(this.TextureProvider!);
this.Functions = new GameFunctions.GameFunctions(this); this.Functions = new GameFunctions.GameFunctions(this);
this.Store = new Store(this); this.Store = new Store(this);
this.Ipc = new IpcManager(this.Interface); this.Ipc = new IpcManager(this.Interface);
@ -143,7 +148,7 @@ public sealed class Plugin : IDalamudPlugin {
"ChatLogPanel_3", "ChatLogPanel_3",
}; };
private void FrameworkUpdate(Framework framework) { private void FrameworkUpdate(IFramework framework) {
if (this.DeferredSaveFrames >= 0 && this.DeferredSaveFrames-- == 0) { if (this.DeferredSaveFrames >= 0 && this.DeferredSaveFrames-- == 0) {
this.SaveConfig(); this.SaveConfig();
} }

View File

@ -3,7 +3,6 @@ using System.Runtime.InteropServices;
using ChatTwo.Ui; using ChatTwo.Ui;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.GameFonts; using Dalamud.Interface.GameFonts;
using Dalamud.Logging;
using ImGuiNET; using ImGuiNET;
namespace ChatTwo; namespace ChatTwo;
@ -130,6 +129,10 @@ internal sealed class PluginUi : IDisposable {
} }
private void Draw() { private void Draw() {
if (this.Plugin.Config.DatabaseMigration != Configuration.LatestDbVersion) {
return;
}
this.Plugin.Interface.UiBuilder.DisableUserUiHide = !this.Plugin.Config.HideWhenUiHidden; this.Plugin.Interface.UiBuilder.DisableUserUiHide = !this.Plugin.Config.HideWhenUiHidden;
this.DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text]; this.DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text];
@ -147,7 +150,7 @@ internal sealed class PluginUi : IDisposable {
try { try {
component.Draw(); component.Draw();
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error drawing component"); Plugin.Log.Error(ex, "Error drawing component");
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,279 +121,55 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
<data name="Options_HideChat_Name" xml:space="preserve"> <data name="Options_HideChat_Name">
<value>Απόκρυψη αρχικού παραθύρου συνομιλιών</value> <value>Απόκρυψη αρχικού παραθύρου συνομιλιών</value>
</data> </data>
<data name="Options_HideChat_Description" xml:space="preserve"> <data name="Options_HideChat_Description">
<value>Απόκρυψη αρχικού παραθύρου συνομιλιών όταν το plugin είναι ενεργό.</value> <value>Απόκρυψη αρχικού παραθύρου συνομιλιών όταν το plugin είναι ενεργό.</value>
</data> </data>
<data name="Options_SidebarTabView_Name">
<value>Εμφάνιση καρτελών σε πλαϊνή μπάρα</value>
</data>
<data name="Options_SidebarTabView_Description">
<data name="Options_SidebarTabView_Name" xml:space="preserve"> <value>Εμφάνιση καρτελών στο {0} ως πλαϊνή μπάρα αντί για μια μπάρα στην κορυφή.</value>
<value>Εμφάνιση καρτελών σε πλαϊνή μπάρα</value> </data>
</data> <data name="Options_PrettierTimestamps_Name">
<data name="Options_SidebarTabView_Description" xml:space="preserve">
<value>Εμφάνιση καρτελών στο {0} ως πλαϊνή μπάρα αντί για μια μπάρα στην κορυφή.</value>
</data>
<data name="Options_PrettierTimestamps_Name" xml:space="preserve">
<value>Χρήση σύγχρονης διάταξης</value> <value>Χρήση σύγχρονης διάταξης</value>
</data> </data>
<data name="Options_PrettierTimestamps_Description" xml:space="preserve"> <data name="Options_PrettierTimestamps_Description">
<value>Εμφάνιση μηνυμάτων σε πιο μοντέρνο στυλ.</value> <value>Εμφάνιση μηνυμάτων σε πιο μοντέρνο στυλ.</value>
</data> </data>
<data name="Options_MoreCompactPretty_Name" xml:space="preserve"> <data name="Options_MoreCompactPretty_Name">
<value>Πιο συμπαγής μοντέρνα διάταξη</value> <value>Πιο συμπαγής μοντέρνα διάταξη</value>
</data> </data>
<data name="Options_MoreCompactPretty_Description" xml:space="preserve"> <data name="Options_MoreCompactPretty_Description">
<value>Μείωση της απόστασης μεταξύ μηνυμάτων.</value> <value>Μείωση της απόστασης μεταξύ μηνυμάτων.</value>
</data> </data>
<data name="Options_ShowNoviceNetwork_Name" xml:space="preserve"> <data name="Options_ShowNoviceNetwork_Name">
<value>Εμφάνιση κουμπιού σύνδεσης στο Δίκτυο Αρχαρίων</value> <value>Εμφάνιση κουμπιού σύνδεσης στο Δίκτυο Αρχαρίων</value>
</data> </data>
<data name="Options_ShowNoviceNetwork_Description" xml:space="preserve"> <data name="Options_ShowNoviceNetwork_Description">
<value>Εμφάνιση του κουμπιού σύνδεσης στο Δίκτυο Αρχαρίων δίπλα στο κουμπί ρυθμίσεων, εάν συνδέεστε ως μέντορας.</value> <value>Εμφάνιση του κουμπιού σύνδεσης στο Δίκτυο Αρχαρίων δίπλα στο κουμπί ρυθμίσεων, εάν συνδέεστε ως μέντορας.</value>
</data> </data>
<data name="Options_FontSize_Name" xml:space="preserve"> <data name="Options_FontSize_Name">
<value>Μέγεθος γραμματοσειράς</value> <value>Μέγεθος γραμματοσειράς</value>
</data> </data>
<data name="Options_WindowOpacity_Name" xml:space="preserve"> <data name="Options_WindowOpacity_Name">
<value>Διαφάνεια παραθύρου</value> <value>Διαφάνεια παραθύρου</value>
</data> </data>
<data name="Options_CanMove_Name" xml:space="preserve"> <data name="Options_CanMove_Name">
<value>Να επιτρέπεται η μετακίνηση του παραθύρου συνομιλιών</value> <value>Να επιτρέπεται η μετακίνηση του παραθύρου συνομιλιών</value>
</data> </data>
<data name="Options_CanResize_Name" xml:space="preserve"> <data name="Options_CanResize_Name">
<value>Να επιτρέπεται η αλλαγή μεγέθους του παραθύρου συνομιλιών</value> <value>Να επιτρέπεται η αλλαγή μεγέθους του παραθύρου συνομιλιών</value>
</data> </data>
<data name="Options_ShowTitleBar_Name" xml:space="preserve"> <data name="Options_ShowTitleBar_Name">
<value>Να εμφανίζεται η γραμμή τίτλου του παραθύρου συνομιλιών</value> <value>Να εμφανίζεται η γραμμή τίτλου του παραθύρου συνομιλιών</value>
</data> </data>
<data name="Options_Display_Tab" xml:space="preserve"> <data name="Options_Display_Tab">
<value>Εμφάνιση</value> <value>Εμφάνιση</value>
</data> </data>
<data name="Options_ChatColours_Tab" xml:space="preserve"> <data name="Options_ChatColours_Tab">
<value>Χρώματα παραθύρου συνομιλιών</value> <value>Χρώματα παραθύρου συνομιλιών</value>
</data> </data>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,339 +121,145 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
<data name="Context_HideChat">
<data name="Context_HideChat" xml:space="preserve">
<value>ログウィンドウを隠す</value> <value>ログウィンドウを隠す</value>
</data> </data>
<data name="Context_Copy" xml:space="preserve"> <data name="Context_Copy">
<value>コピーする</value> <value>コピーする</value>
</data> </data>
<data name="Context_TryOn" xml:space="preserve"> <data name="Context_TryOn">
<value>装備試着</value> <value>装備試着</value>
</data> </data>
<data name="Context_ItemComparison" xml:space="preserve"> <data name="Context_ItemComparison">
<value>装備詳細を比較</value> <value>装備詳細を比較</value>
</data> </data>
<data name="Context_SearchRecipes" xml:space="preserve"> <data name="Context_SearchRecipes">
<value>この素材から作れるものを確認</value> <value>この素材から作れるものを確認</value>
</data> </data>
<data name="Context_SearchForItem" xml:space="preserve"> <data name="Context_SearchForItem">
<value>所持状況を確認</value> <value>所持状況を確認</value>
</data> </data>
<data name="Context_Link" xml:space="preserve"> <data name="Context_Link">
<value>基本性能を伝える</value> <value>基本性能を伝える</value>
</data> </data>
<data name="Context_CopyItemName" xml:space="preserve"> <data name="Context_CopyItemName">
<value>アイテム名をコピーする</value> <value>アイテム名をコピーする</value>
</data> </data>
<data name="Context_SendTell" xml:space="preserve"> <data name="Context_SendTell">
<value>Tellする</value> <value>Tellする</value>
</data> </data>
<data name="Context_InviteToParty" xml:space="preserve"> <data name="Context_InviteToParty">
<value>パーティに誘う</value> <value>パーティに誘う</value>
</data> </data>
<data name="Context_Promote">
<data name="Context_Promote" xml:space="preserve">
<value>パーティリーダーを委譲する</value> <value>パーティリーダーを委譲する</value>
</data> </data>
<data name="Context_KickFromParty" xml:space="preserve"> <data name="Context_KickFromParty">
<value>パーティから除外する</value> <value>パーティから除外する</value>
</data> </data>
<data name="Context_SendFriendRequest" xml:space="preserve"> <data name="Context_SendFriendRequest">
<value>フレンド申請をする</value> <value>フレンド申請をする</value>
</data> </data>
<data name="Context_AddToBlacklist" xml:space="preserve"> <data name="Context_AddToBlacklist">
<value>ブラックリストに登録する</value> <value>ブラックリストに登録する</value>
</data> </data>
<data name="Context_InviteToNoviceNetwork" xml:space="preserve"> <data name="Context_InviteToNoviceNetwork">
<value>ビギナーチャンネルに招待する</value> <value>ビギナーチャンネルに招待する</value>
</data> </data>
<data name="Context_ReplyInSelectedChatMode" xml:space="preserve"> <data name="Context_ReplyInSelectedChatMode">
<value>選択した会話モードに返信する</value> <value>選択した会話モードに返信する</value>
</data> </data>
<data name="Context_Target" xml:space="preserve"> <data name="Context_Target">
<value>ターゲットする</value> <value>ターゲットする</value>
</data> </data>
<data name="ChatType_Alliance">
<data name="ChatType_Alliance" xml:space="preserve">
<value>アライアンス</value> <value>アライアンス</value>
</data> </data>
<data name="ChatType_Linkshell1" xml:space="preserve"> <data name="ChatType_Linkshell1">
<value>Linkshell[1]</value> <value>Linkshell[1]</value>
</data> </data>
<data name="ChatType_Linkshell2" xml:space="preserve"> <data name="ChatType_Linkshell2">
<value>Linkshell[2]</value> <value>Linkshell[2]</value>
</data> </data>
<data name="ChatType_Linkshell3" xml:space="preserve"> <data name="ChatType_Linkshell3">
<value>Linkshell[3]</value> <value>Linkshell[3]</value>
</data> </data>
<data name="ChatType_Linkshell4" xml:space="preserve"> <data name="ChatType_Linkshell4">
<value>Linkshell[4]</value> <value>Linkshell[4]</value>
</data> </data>
<data name="ChatType_Linkshell5" xml:space="preserve"> <data name="ChatType_Linkshell5">
<value>Linkshell[5]</value> <value>Linkshell[5]</value>
</data> </data>
<data name="ChatType_Linkshell6" xml:space="preserve"> <data name="ChatType_Linkshell6">
<value>Linkshell[6]</value> <value>Linkshell[6]</value>
</data> </data>
<data name="ChatType_Linkshell7" xml:space="preserve"> <data name="ChatType_Linkshell7">
<value>Linkshell[7]</value> <value>Linkshell[7]</value>
</data> </data>
<data name="ChatType_Linkshell8" xml:space="preserve"> <data name="ChatType_Linkshell8">
<value>Linkshell[8]</value> <value>Linkshell[8]</value>
</data> </data>
<data name="ChatType_FreeCompany" xml:space="preserve"> <data name="ChatType_FreeCompany">
<value>フリーカンパニー</value> <value>フリーカンパニー</value>
</data> </data>
<data name="ChatType_NoviceNetwork" xml:space="preserve"> <data name="ChatType_NoviceNetwork">
<value>ビギナーチャンネル</value> <value>ビギナーチャンネル</value>
</data> </data>
<data name="ChatType_PvpTeam">
<data name="ChatType_PvpTeam" xml:space="preserve">
<value>PvPチーム</value> <value>PvPチーム</value>
</data> </data>
<data name="ChatType_CrossLinkshell1" xml:space="preserve"> <data name="ChatType_CrossLinkshell1">
<value>クロスワールドリンクシェルチャンネル1</value> <value>クロスワールドリンクシェルチャンネル1</value>
</data> </data>
<data name="ChatType_CrossLinkshell2" xml:space="preserve"> <data name="ChatType_CrossLinkshell2">
<value>クロスワールドリンクシェルチャンネル2</value> <value>クロスワールドリンクシェルチャンネル2</value>
</data> </data>
<data name="ChatType_CrossLinkshell3" xml:space="preserve"> <data name="ChatType_CrossLinkshell3">
<value>クロスワールドリンクシェルチャンネル3</value> <value>クロスワールドリンクシェルチャンネル3</value>
</data> </data>
<data name="ChatType_CrossLinkshell4" xml:space="preserve"> <data name="ChatType_CrossLinkshell4">
<value>クロスワールドリンクシェルチャンネル4</value> <value>クロスワールドリンクシェルチャンネル4</value>
</data> </data>
<data name="ChatType_CrossLinkshell5" xml:space="preserve"> <data name="ChatType_CrossLinkshell5">
<value>クロスワールドリンクシェルチャンネル5</value> <value>クロスワールドリンクシェルチャンネル5</value>
</data> </data>
<data name="ChatType_CrossLinkshell6" xml:space="preserve"> <data name="ChatType_CrossLinkshell6">
<value>クロスワールドリンクシェルチャンネル6</value> <value>クロスワールドリンクシェルチャンネル6</value>
</data> </data>
<data name="ChatType_CrossLinkshell7" xml:space="preserve"> <data name="ChatType_CrossLinkshell7">
<value>クロスワールドリンクシェルチャンネル7</value> <value>クロスワールドリンクシェルチャンネル7</value>
</data> </data>
<data name="ChatType_CrossLinkshell8" xml:space="preserve"> <data name="ChatType_CrossLinkshell8">
<value>クロスワールドリンクシェルチャンネル8</value> <value>クロスワールドリンクシェルチャンネル8</value>
</data> </data>
<data name="ChatType_Damage" xml:space="preserve"> <data name="ChatType_Damage">
<value>ダメージを与えた</value> <value>ダメージを与えた</value>
</data> </data>
<data name="ChatType_Echo">
<data name="ChatType_Echo" xml:space="preserve">
<value>/echoで出力するテキスト</value> <value>/echoで出力するテキスト</value>
</data> </data>
<data name="ChatType_System" xml:space="preserve"> <data name="ChatType_System">
<value>システムメッセージ</value> <value>システムメッセージ</value>
</data> </data>
<data name="ChatType_BattleSystem" xml:space="preserve"> <data name="ChatType_BattleSystem">
<value>戦闘に関するシステムメッセージ</value> <value>戦闘に関するシステムメッセージ</value>
</data> </data>
<data name="ChatType_GatheringSystem" xml:space="preserve"> <data name="ChatType_GatheringSystem">
<value>採集に関するシステムメッセージ</value> <value>採集に関するシステムメッセージ</value>
</data> </data>
<data name="ChatType_Error" xml:space="preserve"> <data name="ChatType_Error">
<value>エラーメッセージ</value> <value>エラーメッセージ</value>
</data> </data>
<data name="ChatType_NpcDialogue" xml:space="preserve"> <data name="ChatType_NpcDialogue">
<value>NPC会話</value> <value>NPC会話</value>
</data> </data>
<data name="ChatType_FreeCompanyAnnouncement">
<data name="ChatType_FreeCompanyAnnouncement" xml:space="preserve">
<value>フリーカンパニーアナウンス</value> <value>フリーカンパニーアナウンス</value>
</data> </data>
<data name="ChatType_NoviceNetworkSystem">
<data name="ChatType_NoviceNetworkSystem" xml:space="preserve">
<value>ビギナーチャンネルアナウンス</value> <value>ビギナーチャンネルアナウンス</value>
</data> </data>
<data name="ChatType_PvpTeamAnnouncement">
<data name="ChatType_PvpTeamAnnouncement" xml:space="preserve">
<value>PvPチームアナウンス</value> <value>PvPチームアナウンス</value>
</data> </data>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,521 +121,418 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
<data name="Options_HideChat_Name" xml:space="preserve"> <data name="Options_HideChat_Name">
<value>Ascunde chat-ul normal</value> <value>Ascunde chat-ul normal</value>
</data> </data>
<data name="Options_HideChat_Description" xml:space="preserve"> <data name="Options_HideChat_Description">
<value>Ascunde fereastra de chat a jocului atunci când pluginul este activ.</value> <value>Ascunde fereastra de chat a jocului atunci când pluginul este activ.</value>
</data> </data>
<data name="Options_HideDuringCutscenes_Name" xml:space="preserve"> <data name="Options_HideDuringCutscenes_Name">
<value>Ascunde chat-ul pe durata cinematic-urilor</value> <value>Ascunde chat-ul pe durata cinematic-urilor</value>
</data> </data>
<data name="Options_HideDuringCutscenes_Description" xml:space="preserve"> <data name="Options_HideDuringCutscenes_Description">
<value>Ascunde {0} pe durata cinematic-urilor.</value> <value>Ascunde {0} pe durata cinematic-urilor.</value>
</data> </data>
<data name="Options_NativeItemTooltips_Name" xml:space="preserve"> <data name="Options_NativeItemTooltips_Name">
<value>Afișează descrierea nativa a item-urilor</value> <value>Afișează descrierea nativa a item-urilor</value>
</data> </data>
<data name="Options_NativeItemTooltips_Description" xml:space="preserve"> <data name="Options_NativeItemTooltips_Description">
<value>Afișează descrierea item-urilor din joc când cursorul este peste un item in {0}.</value> <value>Afișează descrierea item-urilor din joc când cursorul este peste un item in {0}.</value>
</data> </data>
<data name="Options_SidebarTabView_Name" xml:space="preserve"> <data name="Options_SidebarTabView_Name">
<value>Afișează taburi într-o bara laterala</value> <value>Afișează taburi într-o bara laterala</value>
</data> </data>
<data name="Options_SidebarTabView_Description" xml:space="preserve"> <data name="Options_SidebarTabView_Description">
<value>Afișează taburi in {0} ca o bara laterala in loc de o bara deasupra ferestrei.</value> <value>Afișează taburi in {0} ca o bara laterala in loc de o bara deasupra ferestrei.</value>
</data> </data>
<data name="Options_PrettierTimestamps_Name" xml:space="preserve"> <data name="Options_PrettierTimestamps_Name">
<value>Folosește aspectul modern</value> <value>Folosește aspectul modern</value>
</data> </data>
<data name="Options_PrettierTimestamps_Description" xml:space="preserve"> <data name="Options_PrettierTimestamps_Description">
<value>Afișează mesajele într-un stil modern.</value> <value>Afișează mesajele într-un stil modern.</value>
</data> </data>
<data name="Options_MoreCompactPretty_Name" xml:space="preserve"> <data name="Options_MoreCompactPretty_Name">
<value>Aspect modern mai compact</value> <value>Aspect modern mai compact</value>
</data> </data>
<data name="Options_MoreCompactPretty_Description" xml:space="preserve"> <data name="Options_MoreCompactPretty_Description">
<value>Reduce spațiul dintre mesaje.</value> <value>Reduce spațiul dintre mesaje.</value>
</data> </data>
<data name="Options_ShowNoviceNetwork_Name" xml:space="preserve"> <data name="Options_ShowNoviceNetwork_Name">
<value>Afișează butonul de alăturare la Novice Network</value> <value>Afișează butonul de alăturare la Novice Network</value>
</data> </data>
<data name="Options_ShowNoviceNetwork_Description" xml:space="preserve"> <data name="Options_ShowNoviceNetwork_Description">
<value>Afișează butonul de alăturare la Novice Network lângă butonul de setări daca ești conectat ca un mentor.</value> <value>Afișează butonul de alăturare la Novice Network lângă butonul de setări daca ești conectat ca un mentor.</value>
</data> </data>
<data name="Options_FontSize_Name" xml:space="preserve"> <data name="Options_FontSize_Name">
<value>Dimensiunea textului</value> <value>Dimensiunea textului</value>
</data> </data>
<data name="Options_WindowOpacity_Name" xml:space="preserve"> <data name="Options_WindowOpacity_Name">
<value>Opacitatea ferestrei</value> <value>Opacitatea ferestrei</value>
</data> </data>
<data name="Options_CanMove_Name" xml:space="preserve"> <data name="Options_CanMove_Name">
<value>Permite mutarea chat-ului</value> <value>Permite mutarea chat-ului</value>
</data> </data>
<data name="Options_CanResize_Name" xml:space="preserve"> <data name="Options_CanResize_Name">
<value>Permite redimensionarea chat-ului</value> <value>Permite redimensionarea chat-ului</value>
</data> </data>
<data name="Options_ShowTitleBar_Name" xml:space="preserve"> <data name="Options_ShowTitleBar_Name">
<value>Afișează bara de titlu pentru chat</value> <value>Afișează bara de titlu pentru chat</value>
</data> </data>
<data name="Options_Display_Tab" xml:space="preserve"> <data name="Options_Display_Tab">
<value>Afișaj</value> <value>Afișaj</value>
</data> </data>
<data name="Options_ChatColours_Tab" xml:space="preserve"> <data name="Options_ChatColours_Tab">
<value>Culori în chat</value> <value>Culori în chat</value>
</data> </data>
<data name="Options_ChatColours_Reset" xml:space="preserve"> <data name="Options_ChatColours_Reset">
<value>Resetează la valorile implicite</value> <value>Resetează la valorile implicite</value>
</data> </data>
<data name="Options_ChatColours_Import" xml:space="preserve"> <data name="Options_ChatColours_Import">
<value>Importă din joc</value> <value>Importă din joc</value>
</data> </data>
<data name="Options_Tabs_Tab" xml:space="preserve"> <data name="Options_Tabs_Tab">
<value>Taburi</value> <value>Taburi</value>
</data> </data>
<data name="Options_Tabs_Add" xml:space="preserve"> <data name="Options_Tabs_Add">
<value>Adaugă</value> <value>Adaugă</value>
</data> </data>
<data name="Options_Tabs_Delete" xml:space="preserve"> <data name="Options_Tabs_Delete">
<value>Șterge</value> <value>Șterge</value>
</data> </data>
<data name="Options_Tabs_MoveUp" xml:space="preserve"> <data name="Options_Tabs_MoveUp">
<value>Mută în sus</value> <value>Mută în sus</value>
</data> </data>
<data name="Options_Tabs_MoveDown" xml:space="preserve"> <data name="Options_Tabs_MoveDown">
<value>Mută în jos</value> <value>Mută în jos</value>
</data> </data>
<data name="Options_Tabs_Name" xml:space="preserve"> <data name="Options_Tabs_Name">
<value>Nume</value> <value>Nume</value>
</data> </data>
<data name="Options_Tabs_ShowTimestamps" xml:space="preserve"> <data name="Options_Tabs_ShowTimestamps">
<value>Afișează marcajele de timp</value> <value>Afișează marcajele de timp</value>
</data> </data>
<data name="Options_Tabs_UnreadMode" xml:space="preserve"> <data name="Options_Tabs_UnreadMode">
<value>Modul necitit</value> <value>Modul necitit</value>
</data> </data>
<data name="Options_Tabs_NoInputChannel" xml:space="preserve"> <data name="Options_Tabs_NoInputChannel">
<value>&lt;Nimic&gt;</value> <value>&lt;Nimic&gt;</value>
</data> </data>
<data name="Options_Tabs_InputChannel" xml:space="preserve"> <data name="Options_Tabs_InputChannel">
<value>Canalul de comunicare</value> <value>Canalul de comunicare</value>
</data> </data>
<data name="Options_Tabs_Channels" xml:space="preserve"> <data name="Options_Tabs_Channels">
<value>Canale</value> <value>Canale</value>
</data> </data>
<data name="UnreadMode_All_Tooltip" xml:space="preserve"> <data name="UnreadMode_All_Tooltip">
<value>Afișează întotdeauna indicatorii pentru mesajele necitite.</value> <value>Afișează întotdeauna indicatorii pentru mesajele necitite.</value>
</data> </data>
<data name="UnreadMode_Unseen_Tooltip" xml:space="preserve"> <data name="UnreadMode_Unseen_Tooltip">
<value>Afișează indicatorii pentru mesajele necitite doar pentru mesajele pe care nu le-ai văzut.</value> <value>Afișează indicatorii pentru mesajele necitite doar pentru mesajele pe care nu le-ai văzut.</value>
</data> </data>
<data name="UnreadMode_None_Tooltip" xml:space="preserve"> <data name="UnreadMode_None_Tooltip">
<value>Nu arată indicatori pentru mesajele necitite.</value> <value>Nu arată indicatori pentru mesajele necitite.</value>
</data> </data>
<data name="Tab_DefaultName" xml:space="preserve"> <data name="Tab_DefaultName">
<value>Tab nou</value> <value>Tab nou</value>
</data> </data>
<data name="Settings_Kofi" xml:space="preserve"> <data name="Settings_Kofi">
<value>Suportă {0} pe Ko-fi</value> <value>Suportă {0} pe Ko-fi</value>
</data> </data>
<data name="Settings_SaveAndClose" xml:space="preserve"> <data name="Settings_SaveAndClose">
<value>Salvează si închide</value> <value>Salvează si închide</value>
</data> </data>
<data name="Settings_Save" xml:space="preserve"> <data name="Settings_Save">
<value>Salvează</value> <value>Salvează</value>
</data> </data>
<data name="Settings_Discard" xml:space="preserve"> <data name="Settings_Discard">
<value>Anulează</value> <value>Anulează</value>
</data> </data>
<data name="Settings_Title" xml:space="preserve"> <data name="Settings_Title">
<value>Setări {0}</value> <value>Setări {0}</value>
</data> </data>
<data name="ChatLog_SwitcherDisabled" xml:space="preserve"> <data name="ChatLog_SwitcherDisabled">
<value>Dezactivat pentru acest tab.</value> <value>Dezactivat pentru acest tab.</value>
</data> </data>
<data name="ChatLog_HideChat" xml:space="preserve"> <data name="ChatLog_HideChat">
<value>Ascunde chat-ul</value> <value>Ascunde chat-ul</value>
</data> </data>
<data name="ChatLog_Tabs_MoveUp" xml:space="preserve"> <data name="ChatLog_Tabs_MoveUp">
<value>Mută în sus</value> <value>Mută în sus</value>
</data> </data>
<data name="ChatLog_Tabs_MoveLeft" xml:space="preserve"> <data name="ChatLog_Tabs_MoveLeft">
<value>Mută în stânga</value> <value>Mută în stânga</value>
</data> </data>
<data name="ChatLog_Tabs_MoveDown" xml:space="preserve"> <data name="ChatLog_Tabs_MoveDown">
<value>Mută în jos</value> <value>Mută în jos</value>
</data> </data>
<data name="ChatLog_Tabs_MoveRight" xml:space="preserve"> <data name="ChatLog_Tabs_MoveRight">
<value>Mută în dreapta</value> <value>Mută în dreapta</value>
</data> </data>
<data name="Options_Tabs_ChannelTypes_Chat" xml:space="preserve"> <data name="Options_Tabs_ChannelTypes_Chat">
<value>Conversație</value> <value>Conversație</value>
</data> </data>
<data name="Options_Tabs_ChannelTypes_Battle" xml:space="preserve"> <data name="Options_Tabs_ChannelTypes_Battle">
<value>Luptă</value> <value>Luptă</value>
</data> </data>
<data name="Options_Tabs_ChannelTypes_Announcements" xml:space="preserve"> <data name="Options_Tabs_ChannelTypes_Announcements">
<value>Anunțuri</value> <value>Anunțuri</value>
</data> </data>
<data name="UnreadMode_All" xml:space="preserve"> <data name="UnreadMode_All">
<value>Toate</value> <value>Toate</value>
</data> </data>
<data name="UnreadMode_Unseen" xml:space="preserve"> <data name="UnreadMode_Unseen">
<value>Nevăzut</value> <value>Nevăzut</value>
</data> </data>
<data name="UnreadMode_None" xml:space="preserve"> <data name="UnreadMode_None">
<value>Niciunul</value> <value>Niciunul</value>
</data> </data>
<data name="ChatSource_Self" xml:space="preserve"> <data name="ChatSource_Self">
<value>Propriu</value> <value>Propriu</value>
</data> </data>
<data name="ChatSource_PartyMember" xml:space="preserve"> <data name="ChatSource_PartyMember">
<value>Membru al grupului</value> <value>Membru al grupului</value>
</data> </data>
<data name="ChatSource_AllianceMember" xml:space="preserve"> <data name="ChatSource_AllianceMember">
<value>Membru al alianței</value> <value>Membru al alianței</value>
</data> </data>
<data name="ChatSource_Other" xml:space="preserve"> <data name="ChatSource_Other">
<value>Altele</value> <value>Altele</value>
</data> </data>
<data name="ChatSource_EngagedEnemy" xml:space="preserve"> <data name="ChatSource_EngagedEnemy">
<value>Inamic atacat</value> <value>Inamic atacat</value>
</data> </data>
<data name="ChatSource_UnengagedEnemy" xml:space="preserve"> <data name="ChatSource_UnengagedEnemy">
<value>Inamic neatacat</value> <value>Inamic neatacat</value>
</data> </data>
<data name="ChatSource_FriendlyNpc" xml:space="preserve"> <data name="ChatSource_FriendlyNpc">
<value>NPC prietenos</value> <value>NPC prietenos</value>
</data> </data>
<data name="ChatSource_SelfPet" xml:space="preserve"> <data name="ChatSource_SelfPet">
<value>Pet (Propriu)</value> <value>Pet (Propriu)</value>
</data> </data>
<data name="ChatSource_PartyPet" xml:space="preserve"> <data name="ChatSource_PartyPet">
<value>Pet (Grup)</value> <value>Pet (Grup)</value>
</data> </data>
<data name="ChatSource_AlliancePet" xml:space="preserve"> <data name="ChatSource_AlliancePet">
<value>Pet (Membru al alianței)</value> <value>Pet (Membru al alianței)</value>
</data> </data>
<data name="ChatSource_OtherPet" xml:space="preserve"> <data name="ChatSource_OtherPet">
<value>Pet (Altele)</value> <value>Pet (Altele)</value>
</data> </data>
<data name="Options_Font_Name" xml:space="preserve"> <data name="Options_Font_Name">
<value>Font</value> <value>Font</value>
</data> </data>
<data name="Options_JapaneseFont_Name" xml:space="preserve"> <data name="Options_JapaneseFont_Name">
<value>Font japonez</value> <value>Font japonez</value>
</data> </data>
<data name="Options_Font_Description" xml:space="preserve"> <data name="Options_Font_Description">
<value>Fontul pe care {0} îl va folosii sa afișeze text non-japonez.</value> <value>Fontul pe care {0} îl va folosii sa afișeze text non-japonez.</value>
</data> </data>
<data name="Options_Font_Warning" xml:space="preserve"> <data name="Options_Font_Warning">
<value>Folosirea anumitor fonturi de sistem vă poate închide jocul. Ați fost avertizat.</value> <value>Folosirea anumitor fonturi de sistem vă poate închide jocul. Ați fost avertizat.</value>
</data> </data>
<data name="Options_JapaneseFont_Description" xml:space="preserve"> <data name="Options_JapaneseFont_Description">
<value>Fontul care va fi folosit pentru a afișa textul japonez in {0}.</value> <value>Fontul care va fi folosit pentru a afișa textul japonez in {0}.</value>
</data> </data>
<data name="Options_Tabs_ChannelTypes_Special" xml:space="preserve"> <data name="Options_Tabs_ChannelTypes_Special">
<value>Special</value> <value>Special</value>
</data> </data>
<data name="Options_Fonts_Tab" xml:space="preserve"> <data name="Options_Fonts_Tab">
<value>Fonturi</value> <value>Fonturi</value>
</data> </data>
<data name="Options_SymbolsFontSize_Name" xml:space="preserve"> <data name="Options_SymbolsFontSize_Name">
<value>Dimensiunea fontului simbolurilor</value> <value>Dimensiunea fontului simbolurilor</value>
</data> </data>
<data name="Options_JapaneseFontSize_Name" xml:space="preserve"> <data name="Options_JapaneseFontSize_Name">
<value>Dimensiunea fontului japonez</value> <value>Dimensiunea fontului japonez</value>
</data> </data>
<data name="Options_SymbolsFontSize_Description" xml:space="preserve"> <data name="Options_SymbolsFontSize_Description">
<value>Dimensiunea fontului care va fi folosită pentru simbolurile jocului.</value> <value>Dimensiunea fontului care va fi folosită pentru simbolurile jocului.</value>
</data> </data>
<data name="ChatLog_Tabs_Delete" xml:space="preserve"> <data name="ChatLog_Tabs_Delete">
<value>Șterge tabul</value> <value>Șterge tabul</value>
</data> </data>
<data name="Options_HideWhenNotLoggedIn_Name" xml:space="preserve"> <data name="Options_HideWhenNotLoggedIn_Name">
<value>Ascunde când nu ești autentificat</value> <value>Ascunde când nu ești autentificat</value>
</data> </data>
<data name="Options_HideWhenNotLoggedIn_Description" xml:space="preserve"> <data name="Options_HideWhenNotLoggedIn_Description">
<value>Ascunde {0} când nu ești conectat la un caracter.</value> <value>Ascunde {0} când nu ești conectat la un caracter.</value>
</data> </data>
<data name="Tabs_Presets_General" xml:space="preserve"> <data name="Tabs_Presets_General">
<value>General</value> <value>General</value>
</data> </data>
<data name="Options_Tabs_Preset" xml:space="preserve"> <data name="Options_Tabs_Preset">
<value>Presetare: {0}</value> <value>Presetare: {0}</value>
</data> </data>
<data name="Tabs_Presets_Event" xml:space="preserve"> <data name="Tabs_Presets_Event">
<value>Eveniment</value> <value>Eveniment</value>
</data> </data>
<data name="Options_Tabs_NewTab" xml:space="preserve"> <data name="Options_Tabs_NewTab">
<value>Tab nou</value> <value>Tab nou</value>
</data> </data>
<data name="Options_About_Tab" xml:space="preserve"> <data name="Options_About_Tab">
<value>Despre</value> <value>Despre</value>
</data> </data>
<data name="Options_About_Opening" xml:space="preserve"> <data name="Options_About_Opening">
<value>{0} este un proiect care recreează complet chat-ul din joc si îl îmbunătățește.</value> <value>{0} este un proiect care recreează complet chat-ul din joc si îl îmbunătățește.</value>
</data> </data>
<data name="Options_About_ClickUp" xml:space="preserve"> <data name="Options_About_ClickUp">
<value>Apasă butonul din stânga pentru a vedea ce este in lucru si ce urmează.</value> <value>Apasă butonul din stânga pentru a vedea ce este in lucru si ce urmează.</value>
</data> </data>
<data name="Options_About_CrowdIn" xml:space="preserve"> <data name="Options_About_CrowdIn">
<value>Apasă butonul din stânga pentru a contribui la traducerea {0}.</value> <value>Apasă butonul din stânga pentru a contribui la traducerea {0}.</value>
</data> </data>
<data name="Options_About_Translators" xml:space="preserve"> <data name="Options_About_Translators">
<value>Traducători</value> <value>Traducători</value>
</data> </data>
<data name="CommandHelpSide_None" xml:space="preserve"> <data name="CommandHelpSide_None">
<value>Niciunul</value> <value>Niciunul</value>
</data> </data>
<data name="CommandHelpSide_Left" xml:space="preserve"> <data name="CommandHelpSide_Left">
<value>Stânga</value> <value>Stânga</value>
</data> </data>
<data name="CommandHelpSide_Right" xml:space="preserve"> <data name="CommandHelpSide_Right">
<value>Dreapta</value> <value>Dreapta</value>
</data> </data>
<data name="Options_CommandHelpSide_Name" xml:space="preserve"> <data name="Options_CommandHelpSide_Name">
<value>Partea pentru ajutor la comenzi</value> <value>Partea pentru ajutor la comenzi</value>
</data> </data>
<data name="Options_CommandHelpSide_Description" xml:space="preserve"> <data name="Options_CommandHelpSide_Description">
<value>Partea {0}-ului de afișare a ajutorului pentru comenzi.</value> <value>Partea {0}-ului de afișare a ajutorului pentru comenzi.</value>
</data> </data>
<data name="Options_HideWhenUiHidden_Name" xml:space="preserve"> <data name="Options_HideWhenUiHidden_Name">
<value>Ascunde când interfața jocului este ascunsă</value> <value>Ascunde când interfața jocului este ascunsă</value>
</data> </data>
<data name="Options_HideWhenUiHidden_Description" xml:space="preserve"> <data name="Options_HideWhenUiHidden_Description">
<value>Ascunde {0} atunci când interfața jocului este ascunsă.</value> <value>Ascunde {0} atunci când interfața jocului este ascunsă.</value>
</data> </data>
<data name="Options_KeybindMode_Name" xml:space="preserve"> <data name="Options_KeybindMode_Name">
<value>Modul scurtăturilor</value> <value>Modul scurtăturilor</value>
</data> </data>
<data name="Options_KeybindMode_Description" xml:space="preserve"> <data name="Options_KeybindMode_Description">
<value>Modul în care {0} ar trebui să se ocupe de scurtături.</value> <value>Modul în care {0} ar trebui să se ocupe de scurtături.</value>
</data> </data>
<data name="Options_Miscellaneous_Tab" xml:space="preserve"> <data name="Options_Miscellaneous_Tab">
<value>Diverse</value> <value>Diverse</value>
</data> </data>
<data name="LanguageOverride_None" xml:space="preserve"> <data name="LanguageOverride_None">
<value>Folosește limba implicită a lui Dalamud</value> <value>Folosește limba implicită a lui Dalamud</value>
</data> </data>
<data name="KeybindMode_Flexible_Name" xml:space="preserve"> <data name="KeybindMode_Flexible_Name">
<value>Flexibil</value> <value>Flexibil</value>
</data> </data>
<data name="KeybindMode_Strict_Name" xml:space="preserve"> <data name="KeybindMode_Strict_Name">
<value>Strict</value> <value>Strict</value>
</data> </data>
<data name="KeybindMode_Flexible_Tooltip" xml:space="preserve"> <data name="KeybindMode_Flexible_Tooltip">
<value>Procesează funcția tastelor cu modificatori, chiar dacă sunt apăsați alți modificatori.</value> <value>Procesează funcția tastelor cu modificatori, chiar dacă sunt apăsați alți modificatori.</value>
</data> </data>
<data name="KeybindMode_Strict_Tooltip" xml:space="preserve"> <data name="KeybindMode_Strict_Tooltip">
<value>Procesează tastele cu modificatori doar daca alți modificatori nu sunt apăsați.</value> <value>Procesează tastele cu modificatori doar daca alți modificatori nu sunt apăsați.</value>
</data> </data>
<data name="Options_Language_Name" xml:space="preserve"> <data name="Options_Language_Name">
<value>Limbă</value> <value>Limbă</value>
</data> </data>
<data name="Options_Language_Description" xml:space="preserve"> <data name="Options_Language_Description">
<value>Limba în care se afișează {0}.</value> <value>Limba în care se afișează {0}.</value>
</data> </data>
<data name="Options_DatabaseBattleMessages_Name" xml:space="preserve"> <data name="Options_DatabaseBattleMessages_Name">
<value>Salvează mesajele de luptă în baza de date</value> <value>Salvează mesajele de luptă în baza de date</value>
</data> </data>
<data name="Options_DatabaseBattleMessages_Description" xml:space="preserve"> <data name="Options_DatabaseBattleMessages_Description">
<value>Daca mesajele de lupta sunt salvate in baza de date, dimensiunea bazei de date va creste mult mai repede, și va exista o întârziere vizibilă la salvarea setărilor. Este recomandat să lăsați aceasta opțiune dezactivată.</value> <value>Daca mesajele de lupta sunt salvate in baza de date, dimensiunea bazei de date va creste mult mai repede, și va exista o întârziere vizibilă la salvarea setărilor. Este recomandat să lăsați aceasta opțiune dezactivată.</value>
</data> </data>
<data name="Options_LoadPreviousSession_Name" xml:space="preserve"> <data name="Options_LoadPreviousSession_Name">
<value>Afișează sesiunea anterioară a chat-ului la autentificare</value> <value>Afișează sesiunea anterioară a chat-ului la autentificare</value>
</data> </data>
<data name="Options_LoadPreviousSession_Description" xml:space="preserve"> <data name="Options_LoadPreviousSession_Description">
<value>După autentificare, populează chat-ul cu mesajele de când te-ai deconectat ultima dată.</value> <value>După autentificare, populează chat-ul cu mesajele de când te-ai deconectat ultima dată.</value>
</data> </data>
<data name="Options_Database_Tab" xml:space="preserve"> <data name="Options_Database_Tab">
<value>Bază de date</value> <value>Bază de date</value>
</data> </data>
<data name="Options_FilterIncludePreviousSessions_Name" xml:space="preserve"> <data name="Options_FilterIncludePreviousSessions_Name">
<value>Include sesiunile anterioare la popularea taburilor</value> <value>Include sesiunile anterioare la popularea taburilor</value>
</data> </data>
<data name="Options_FilterIncludePreviousSessions_Description" xml:space="preserve"> <data name="Options_FilterIncludePreviousSessions_Description">
<value>Include mesaje de dinaintea lansării jocului atunci când se populează taburile. Taburile sunt populate atunci când setările sunt salvate.</value> <value>Include mesaje de dinaintea lansării jocului atunci când se populează taburile. Taburile sunt populate atunci când setările sunt salvate.</value>
</data> </data>
<data name="Options_Database_Advanced_Warning" xml:space="preserve"> <data name="Options_Database_Advanced_Warning">
<value>Nu apasă butoanele astea daca nu știi ce faci.</value> <value>Nu apasă butoanele astea daca nu știi ce faci.</value>
</data> </data>
<data name="Options_Database_Advanced" xml:space="preserve"> <data name="Options_Database_Advanced">
<value>Avansat</value> <value>Avansat</value>
</data> </data>
<data name="Options_SharedMode_Name" xml:space="preserve"> <data name="Options_SharedMode_Name">
<value>Activează modul instanțelor multiple</value> <value>Activează modul instanțelor multiple</value>
</data> </data>
<data name="Options_SharedMode_Description" xml:space="preserve"> <data name="Options_SharedMode_Description">
<value>Permite mai multor instanțe sa folosească {0} simultan, folosind aceeași data de baze.</value> <value>Permite mai multor instanțe sa folosească {0} simultan, folosind aceeași data de baze.</value>
</data> </data>
<data name="Options_SharedMode_Warning" xml:space="preserve"> <data name="Options_SharedMode_Warning">
<value>Această opțiune nu este recomandată. Dacă o activați nu veți primi niciun suport. Această opțiune va afecta performanța {0}-ului.</value> <value>Această opțiune nu este recomandată. Dacă o activați nu veți primi niciun suport. Această opțiune va afecta performanța {0}-ului.</value>
</data> </data>
<data name="ChatLog_Tabs_PopOut" xml:space="preserve"> <data name="ChatLog_Tabs_PopOut">
<value>Mută tabul într-o fereastra noua</value> <value>Mută tabul într-o fereastra noua</value>
</data> </data>
<data name="Options_HideSameTimestamps_Name" xml:space="preserve"> <data name="Options_HideSameTimestamps_Name">
<value>Ascunde marcajele de timp când nu sunt necesare</value> <value>Ascunde marcajele de timp când nu sunt necesare</value>
</data> </data>
<data name="Options_HideSameTimestamps_Description" xml:space="preserve"> <data name="Options_HideSameTimestamps_Description">
<value>Ascunde marcajele de timp atunci când mesajele anterioare au aceeași marcă de timp.</value> <value>Ascunde marcajele de timp atunci când mesajele anterioare au aceeași marcă de timp.</value>
</data> </data>
<data name="Options_ShowPopOutTitleBar_Name" xml:space="preserve"> <data name="Options_ShowPopOutTitleBar_Name">
<value>Arată bara de titlu pentru tab-urile in ferestre diferite</value> <value>Arată bara de titlu pentru tab-urile in ferestre diferite</value>
</data> </data>
<data name="Options_Tabs_PopOut" xml:space="preserve"> <data name="Options_Tabs_PopOut">
<value>Afișează într-o fereastră separată</value> <value>Afișează într-o fereastră separată</value>
</data> </data>
<data name="Options_Tabs_IndependentOpacity" xml:space="preserve"> <data name="Options_Tabs_IndependentOpacity">
<value>Folosește o transparentă diferită de fereastra principală</value> <value>Folosește o transparentă diferită de fereastra principală</value>
</data> </data>
<data name="Options_Tabs_Opacity" xml:space="preserve"> <data name="Options_Tabs_Opacity">
<value>Transparență</value> <value>Transparență</value>
</data> </data>
<data name="Options_FontsEnabled" xml:space="preserve"> <data name="Options_FontsEnabled">
<value>Activează fonturi personalizate</value> <value>Activează fonturi personalizate</value>
</data> </data>
<data name="AutoTranslate_Search_Hint" xml:space="preserve"> <data name="AutoTranslate_Search_Hint">
<value>Caută traducere automată...</value> <value>Caută traducere automată...</value>
</data> </data>
<data name="Options_SortAutoTranslate_Name" xml:space="preserve"> <data name="Options_SortAutoTranslate_Name">
<value>Sortează lista de traduceri automate</value> <value>Sortează lista de traduceri automate</value>
</data> </data>
<data name="Options_SortAutoTranslate_Description" xml:space="preserve"> <data name="Options_SortAutoTranslate_Description">
<value>Dacă această opțiune este activată, lista de traduceri automate va fi sortată alfabetic.</value> <value>Dacă această opțiune este activată, lista de traduceri automate va fi sortată alfabetic.</value>
</data> </data>
<data name="AutoTranslate_Completion_Key" xml:space="preserve"> <data name="AutoTranslate_Completion_Key">
<value>Ctrl + {0}</value> <value>Ctrl + {0}</value>
</data> </data>
<data name="Options_ExtraGlyphs_Name" xml:space="preserve"> <data name="Options_ExtraGlyphs_Name">
<value>Caractere suplimentare</value> <value>Caractere suplimentare</value>
</data> </data>
<data name="Options_ExtraGlyphs_Description" xml:space="preserve"> <data name="Options_ExtraGlyphs_Description">
<value>Pot fi adăugate mai multe caractere la fontul global al {0} prin activarea opțiunilor de mai jos. Este posibil să fie necesară creșterea dimensiunilor fontului din Dalamud.</value> <value>Pot fi adăugate mai multe caractere la fontul global al {0} prin activarea opțiunilor de mai jos. Este posibil să fie necesară creșterea dimensiunilor fontului din Dalamud.</value>
</data> </data>
<data name="ExtraGlyphRanges_ChineseFull_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_ChineseFull_Name">
<value>Chineză (completă)</value> <value>Chineză (completă)</value>
</data> </data>
<data name="ExtraGlyphRanges_ChineseSimplifiedCommon_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_ChineseSimplifiedCommon_Name">
<value>Chineză (simplificată)</value> <value>Chineză (simplificată)</value>
</data> </data>
<data name="ExtraGlyphRanges_Cyrillic_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_Cyrillic_Name">
<value>Chirilică</value> <value>Chirilică</value>
</data> </data>
<data name="ExtraGlyphRanges_Japanese_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_Japanese_Name">
<value>Japoneză</value> <value>Japoneză</value>
</data> </data>
<data name="ExtraGlyphRanges_Korean_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_Korean_Name">
<value>Coreeană</value> <value>Coreeană</value>
</data> </data>
<data name="ExtraGlyphRanges_Thai_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_Thai_Name">
<value>Tailandeză</value> <value>Tailandeză</value>
</data> </data>
<data name="ExtraGlyphRanges_Vietnamese_Name" xml:space="preserve"> <data name="ExtraGlyphRanges_Vietnamese_Name">
<value>Vietnameză</value> <value>Vietnameză</value>
</data> </data>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

View File

@ -121,245 +121,4 @@
PublicKeyToken=b77a5c561934e089 PublicKeyToken=b77a5c561934e089
</value> </value>
</resheader> </resheader>
</root> </root>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,13 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics;
using ChatTwo.Code; using ChatTwo.Code;
using ChatTwo.Resources;
using ChatTwo.Util; using ChatTwo.Util;
using Dalamud.Game;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin.Services;
using ImGuiNET;
using LiteDB; using LiteDB;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
@ -39,20 +42,40 @@ internal class Store : IDisposable {
TrimWhitespace = false, TrimWhitespace = false,
// EnumAsInteger = true, // EnumAsInteger = true,
}; };
BsonMapper.Global.Entity<Message>()
.Id(msg => msg.Id) if (this.Plugin.Config.DatabaseMigration == 0) {
.Ctor(doc => new Message( BsonMapper.Global.Entity<Message>()
doc["_id"].AsObjectId, .Id(msg => msg.Id)
(ulong) doc["Receiver"].AsInt64, .Ctor(doc => new Message(
(ulong) doc["ContentId"].AsInt64, doc["_id"].AsObjectId,
DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64), (ulong) doc["Receiver"].AsInt64,
doc["Code"].AsDocument, (ulong) doc["ContentId"].AsInt64,
doc["Sender"].AsArray, DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64),
doc["Content"].AsArray, doc["Code"].AsDocument,
doc["SenderSource"], doc["Sender"].AsArray,
doc["ContentSource"], doc["Content"].AsArray,
doc["SortCode"].AsDocument doc["SenderSource"],
)); doc["ContentSource"],
doc["SortCode"].AsDocument
));
} else {
BsonMapper.Global.Entity<Message>()
.Id(msg => msg.Id)
.Ctor(doc => new Message(
doc["_id"].AsObjectId,
(ulong) doc["Receiver"].AsInt64,
(ulong) doc["ContentId"].AsInt64,
DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64),
doc["Code"].AsDocument,
doc["Sender"].AsArray,
doc["Content"].AsArray,
doc["SenderSource"],
doc["ContentSource"],
doc["SortCode"].AsDocument,
doc["ExtraChatChannel"]
));
}
BsonMapper.Global.RegisterType<Payload?>( BsonMapper.Global.RegisterType<Payload?>(
payload => { payload => {
switch (payload) { switch (payload) {
@ -116,6 +139,9 @@ internal class Store : IDisposable {
this.Database = this.Connect(); this.Database = this.Connect();
this.Messages.EnsureIndex(msg => msg.Date); this.Messages.EnsureIndex(msg => msg.Date);
this.Messages.EnsureIndex(msg => msg.SortCode); this.Messages.EnsureIndex(msg => msg.SortCode);
this.Messages.EnsureIndex(msg => msg.ExtraChatChannel);
this.MigrateWrapper();
this.Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage; this.Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage;
this.Plugin.Framework.Update += this.GetMessageInfo; this.Plugin.Framework.Update += this.GetMessageInfo;
@ -150,18 +176,18 @@ internal class Store : IDisposable {
this.Database = this.Connect(); this.Database = this.Connect();
} }
private void Logout(object? sender, EventArgs eventArgs) { private void Logout() {
this.LastContentId = 0; this.LastContentId = 0;
} }
private void UpdateReceiver(Framework framework) { private void UpdateReceiver(IFramework framework) {
var contentId = this.Plugin.ClientState.LocalContentId; var contentId = this.Plugin.ClientState.LocalContentId;
if (contentId != 0) { if (contentId != 0) {
this.LastContentId = contentId; this.LastContentId = contentId;
} }
} }
private void GetMessageInfo(Framework framework) { private void GetMessageInfo(IFramework framework) {
if (this.CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) { if (this.CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) {
this.CheckpointTimer.Restart(); this.CheckpointTimer.Restart();
new Thread(() => this.Database.Checkpoint()).Start(); new Thread(() => this.Database.Checkpoint()).Start();
@ -178,6 +204,87 @@ internal class Store : IDisposable {
} }
} }
private long _migrateCurrent;
private long _migrateMax;
private void MigrateDraw() {
ImGui.SetNextWindowSizeConstraints(new Vector2(450, 0), new Vector2(450, float.MaxValue));
if (!ImGui.Begin($"{Plugin.Name}##migration-window", ImGuiWindowFlags.AlwaysAutoResize)) {
ImGui.End();
return;
}
ImGui.PushTextWrapPos();
ImGui.TextUnformatted(string.Format(Language.Migration_Line1, Plugin.PluginName));
ImGui.TextUnformatted(string.Format(Language.Migration_Line2, Plugin.PluginName));
ImGui.TextUnformatted(Language.Migration_Line3);
ImGui.TextUnformatted(Language.Migration_Line4);
ImGui.PopTextWrapPos();
ImGui.Spacing();
ImGui.ProgressBar((float) this._migrateCurrent / this._migrateMax, new Vector2(-1, 0), $"{this._migrateCurrent} / {this._migrateMax}");
ImGui.End();
}
internal void MigrateWrapper() {
if (this.Plugin.Config.DatabaseMigration < Configuration.LatestDbVersion) {
this.Plugin.Interface.UiBuilder.Draw += this.MigrateDraw;
}
try {
this.Migrate();
} finally {
this.Plugin.Interface.UiBuilder.Draw -= this.MigrateDraw;
}
}
internal void Migrate() {
// re-save all messages, which will add the ExtraChat channel
if (this.Plugin.Config.DatabaseMigration == 0) {
var total = (float) this.Messages.LongCount() / 10_000.0;
var rounds = (long) Math.Ceiling(total);
this._migrateMax = rounds;
var lastId = ObjectId.Empty;
for (var i = 0; i < rounds; i++) {
this._migrateCurrent = i + 1;
Plugin.Log.Info($"Update round {i + 1}/{rounds}");
var messages = this.Messages.Query()
.OrderBy(msg => msg.Id)
.Where(msg => msg.Id > lastId)
.Limit(10_000)
.ToArray();
foreach (var message in messages) {
this.Messages.Update(message);
lastId = message.Id;
}
}
this.Database.Checkpoint();
BsonMapper.Global.Entity<Message>()
.Id(msg => msg.Id)
.Ctor(doc => new Message(
doc["_id"].AsObjectId,
(ulong) doc["Receiver"].AsInt64,
(ulong) doc["ContentId"].AsInt64,
DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64),
doc["Code"].AsDocument,
doc["Sender"].AsArray,
doc["Content"].AsArray,
doc["SenderSource"],
doc["ContentSource"],
doc["SortCode"].AsDocument,
doc["ExtraChatChannel"]
));
this.Plugin.Config.DatabaseMigration = 1;
this.Plugin.SaveConfig();
}
}
internal void AddMessage(Message message, Tab? currentTab) { internal void AddMessage(Message message, Tab? currentTab) {
if (this.Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) { if (this.Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) {
this.Messages.Insert(message); this.Messages.Insert(message);
@ -218,7 +325,7 @@ internal class Store : IDisposable {
var query = this.Messages var query = this.Messages
.Query() .Query()
.OrderByDescending(msg => msg.Date) .OrderByDescending(msg => msg.Date)
.Where(msg => sortCodes.Contains(msg.SortCode)) .Where(msg => sortCodes.Contains(msg.SortCode) || msg.ExtraChatChannel != Guid.Empty)
.Where(msg => msg.Receiver == this.CurrentContentId); .Where(msg => msg.Receiver == this.CurrentContentId);
if (!this.Plugin.Config.FilterIncludePreviousSessions) { if (!this.Plugin.Config.FilterIncludePreviousSessions) {
query = query.Where(msg => msg.Date >= this.Plugin.GameStarted); query = query.Where(msg => msg.Date >= this.Plugin.GameStarted);
@ -229,7 +336,10 @@ internal class Store : IDisposable {
.ToEnumerable() .ToEnumerable()
.Reverse(); .Reverse();
foreach (var message in messages) { foreach (var message in messages) {
tab.AddMessage(message, unread); // redundant matches check for extrachat
if (tab.Matches(message)) {
tab.AddMessage(message, unread);
}
} }
} }

View File

@ -1,22 +1,22 @@
using Dalamud.Data; using Dalamud.Interface.Internal;
using ImGuiScene; using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
namespace ChatTwo; namespace ChatTwo;
internal class TextureCache : IDisposable { internal class TextureCache : IDisposable {
private DataManager Data { get; } private ITextureProvider TextureProvider { get; }
private readonly Dictionary<(uint, bool), TextureWrap> _itemIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _itemIcons = new();
private readonly Dictionary<(uint, bool), TextureWrap> _statusIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _statusIcons = new();
private readonly Dictionary<(uint, bool), TextureWrap> _eventItemIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _eventItemIcons = new();
internal IReadOnlyDictionary<(uint, bool), TextureWrap> ItemIcons => this._itemIcons; internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> ItemIcons => this._itemIcons;
internal IReadOnlyDictionary<(uint, bool), TextureWrap> StatusIcons => this._statusIcons; internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> StatusIcons => this._statusIcons;
internal IReadOnlyDictionary<(uint, bool), TextureWrap> EventItemIcons => this._eventItemIcons; internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> EventItemIcons => this._eventItemIcons;
internal TextureCache(DataManager data) { internal TextureCache(ITextureProvider textureProvider) {
this.Data = data; this.TextureProvider = textureProvider;
} }
public void Dispose() { public void Dispose() {
@ -28,14 +28,14 @@ internal class TextureCache : IDisposable {
} }
} }
private void AddIcon(IDictionary<(uint, bool), TextureWrap> dict, uint icon, bool hq = false) { private void AddIcon(IDictionary<(uint, bool), IDalamudTextureWrap> dict, uint icon, bool hq = false) {
if (dict.ContainsKey((icon, hq))) { if (dict.ContainsKey((icon, hq))) {
return; return;
} }
var tex = hq var tex = hq
? this.Data.GetImGuiTextureHqIcon(icon) ? this.TextureProvider.GetIcon(icon, ITextureProvider.IconFlags.ItemHighQuality)
: this.Data.GetImGuiTextureIcon(icon); : this.TextureProvider.GetIcon(icon);
if (tex != null) { if (tex != null) {
dict[(icon, hq)] = tex; dict[(icon, hq)] = tex;
} }
@ -53,19 +53,19 @@ internal class TextureCache : IDisposable {
this.AddIcon(this._eventItemIcons, item.Icon); this.AddIcon(this._eventItemIcons, item.Icon);
} }
internal TextureWrap? GetItem(Item item, bool hq = false) { internal IDalamudTextureWrap? GetItem(Item item, bool hq = false) {
this.AddItem(item, hq); this.AddItem(item, hq);
this.ItemIcons.TryGetValue((item.Icon, hq), out var icon); this.ItemIcons.TryGetValue((item.Icon, hq), out var icon);
return icon; return icon;
} }
internal TextureWrap? GetStatus(Status status) { internal IDalamudTextureWrap? GetStatus(Status status) {
this.AddStatus(status); this.AddStatus(status);
this.StatusIcons.TryGetValue((status.Icon, false), out var icon); this.StatusIcons.TryGetValue((status.Icon, false), out var icon);
return icon; return icon;
} }
internal TextureWrap? GetEventItem(EventItem item) { internal IDalamudTextureWrap? GetEventItem(EventItem item) {
this.AddEventItem(item); this.AddEventItem(item);
this.EventItemIcons.TryGetValue((item.Icon, false), out var icon); this.EventItemIcons.TryGetValue((item.Icon, false), out var icon);
return icon; return icon;

View File

@ -11,10 +11,10 @@ using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Logging; using Dalamud.Interface.Internal;
using Dalamud.Interface.Utility;
using Dalamud.Memory; using Dalamud.Memory;
using ImGuiNET; using ImGuiNET;
using ImGuiScene;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
namespace ChatTwo.Ui; namespace ChatTwo.Ui;
@ -28,7 +28,7 @@ internal sealed class ChatLog : IUiComponent {
internal bool Activate; internal bool Activate;
private int _activatePos = -1; private int _activatePos = -1;
internal string Chat = string.Empty; internal string Chat = string.Empty;
private readonly TextureWrap? _fontIcon; private readonly IDalamudTextureWrap? _fontIcon;
private readonly List<string> _inputBacklog = new(); private readonly List<string> _inputBacklog = new();
private int _inputBacklogIdx = -1; private int _inputBacklogIdx = -1;
internal int LastTab { get; private set; } internal int LastTab { get; private set; }
@ -62,7 +62,7 @@ internal sealed class ChatLog : IUiComponent {
this.Ui.Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += this.ClearLog; this.Ui.Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += this.ClearLog;
this.Ui.Plugin.Commands.Register("/chat2").Execute += this.ToggleChat; this.Ui.Plugin.Commands.Register("/chat2").Execute += this.ToggleChat;
this._fontIcon = this.Ui.Plugin.DataManager.GetImGuiTexture("common/font/fonticon_ps5.tex"); this._fontIcon = this.Ui.Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
this.Ui.Plugin.Functions.Chat.Activated += this.Activated; this.Ui.Plugin.Functions.Chat.Activated += this.Activated;
this.Ui.Plugin.ClientState.Login += this.Login; this.Ui.Plugin.ClientState.Login += this.Login;
@ -78,13 +78,13 @@ internal sealed class ChatLog : IUiComponent {
this.Ui.Plugin.Commands.Register("/clearlog2").Execute -= this.ClearLog; this.Ui.Plugin.Commands.Register("/clearlog2").Execute -= this.ClearLog;
} }
private void Logout(object? sender, EventArgs e) { private void Logout() {
foreach (var tab in this.Ui.Plugin.Config.Tabs) { foreach (var tab in this.Ui.Plugin.Config.Tabs) {
tab.Clear(); tab.Clear();
} }
} }
private void Login(object? sender, EventArgs e) { private void Login() {
this.Ui.Plugin.Store.FilterAllTabs(false); this.Ui.Plugin.Store.FilterAllTabs(false);
} }
@ -327,7 +327,7 @@ internal sealed class ChatLog : IUiComponent {
TellReason = reason, TellReason = reason,
}); });
} catch (Exception ex) { } catch (Exception ex) {
PluginLog.LogError(ex, "Error in chat Activated event"); Plugin.Log.Error(ex, "Error in chat Activated event");
} }
} }
} }
@ -415,7 +415,7 @@ internal sealed class ChatLog : IUiComponent {
ImGui.SetNextWindowSize(new Vector2(500, 250) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver); ImGui.SetNextWindowSize(new Vector2(500, 250) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
if (!ImGui.Begin($"{this.Ui.Plugin.Name}###chat2", flags)) { if (!ImGui.Begin($"{Plugin.Name}###chat2", flags)) {
this._lastViewport = ImGui.GetWindowViewport().NativePtr; this._lastViewport = ImGui.GetWindowViewport().NativePtr;
this._wasDocked = ImGui.IsWindowDocked(); this._wasDocked = ImGui.IsWindowDocked();
ImGui.End(); ImGui.End();
@ -707,7 +707,7 @@ internal sealed class ChatLog : IUiComponent {
} }
try { try {
tab.MessagesMutex.WaitOne(); tab.MessagesMutex.Wait();
var reset = false; var reset = false;
if (this._lastResize.IsRunning && this._lastResize.Elapsed.TotalSeconds > 0.25) { if (this._lastResize.IsRunning && this._lastResize.Elapsed.TotalSeconds > 0.25) {
@ -820,7 +820,12 @@ internal sealed class ChatLog : IUiComponent {
ImGui.SameLine(); ImGui.SameLine();
} }
this.DrawChunks(message.Content, true, handler, lineWidth); if (message.Content.Count == 0) {
this.DrawChunks(new[] { new TextChunk(ChunkSource.Content, null, " ") }, true, handler, lineWidth);
} else {
this.DrawChunks(message.Content, true, handler, lineWidth);
}
var afterDraw = ImGui.GetCursorScreenPos(); var afterDraw = ImGui.GetCursorScreenPos();
message.Height = ImGui.GetCursorPosY() - lastPos; message.Height = ImGui.GetCursorPosY() - lastPos;
@ -836,7 +841,7 @@ internal sealed class ChatLog : IUiComponent {
lastPos = ImGui.GetCursorPosY(); lastPos = ImGui.GetCursorPosY();
} }
} finally { } finally {
tab.MessagesMutex.ReleaseMutex(); tab.MessagesMutex.Release();
ImGui.PopStyleVar(this.Ui.Plugin.Config.PrettierTimestamps && this.Ui.Plugin.Config.MoreCompactPretty ? 2 : 1); ImGui.PopStyleVar(this.Ui.Plugin.Config.PrettierTimestamps && this.Ui.Plugin.Config.MoreCompactPretty ? 2 : 1);
} }

View File

@ -1,6 +1,6 @@
using System.Numerics; using System.Numerics;
using ChatTwo.Util; using ChatTwo.Util;
using Dalamud.Interface; using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;

View File

@ -3,7 +3,7 @@ using System.Numerics;
using ChatTwo.Resources; using ChatTwo.Resources;
using ChatTwo.Ui.SettingsTabs; using ChatTwo.Ui.SettingsTabs;
using ChatTwo.Util; using ChatTwo.Util;
using Dalamud.Interface; using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace ChatTwo.Ui; namespace ChatTwo.Ui;
@ -13,7 +13,6 @@ internal sealed class Settings : IUiComponent {
private Configuration Mutable { get; } private Configuration Mutable { get; }
private List<ISettingsTab> Tabs { get; } private List<ISettingsTab> Tabs { get; }
private int _currentTab; private int _currentTab;
internal Settings(PluginUi ui) { internal Settings(PluginUi ui) {
@ -24,7 +23,7 @@ internal sealed class Settings : IUiComponent {
new Display(this.Mutable), new Display(this.Mutable),
new Ui.SettingsTabs.Fonts(this.Mutable), new Ui.SettingsTabs.Fonts(this.Mutable),
new ChatColours(this.Mutable, this.Ui.Plugin), new ChatColours(this.Mutable, this.Ui.Plugin),
new Tabs(this.Mutable), new Tabs(this.Ui.Plugin, this.Mutable),
new Database(this.Mutable, this.Ui.Plugin.Store), new Database(this.Mutable, this.Ui.Plugin.Store),
new Miscellaneous(this.Mutable), new Miscellaneous(this.Mutable),
new About(), new About(),
@ -62,7 +61,7 @@ internal sealed class Settings : IUiComponent {
ImGui.SetNextWindowSize(new Vector2(475, 600) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver); ImGui.SetNextWindowSize(new Vector2(475, 600) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
var name = string.Format(Language.Settings_Title, this.Ui.Plugin.Name); var name = string.Format(Language.Settings_Title, Plugin.Name);
if (!ImGui.Begin($"{name}###chat2-settings", ref this.Ui.SettingsVisible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) { if (!ImGui.Begin($"{name}###chat2-settings", ref this.Ui.SettingsVisible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) {
ImGui.End(); ImGui.End();
return; return;
@ -118,7 +117,7 @@ internal sealed class Settings : IUiComponent {
this.Ui.SettingsVisible = false; this.Ui.SettingsVisible = false;
} }
var buttonLabel = string.Format(Language.Settings_Kofi, this.Ui.Plugin.Name); var buttonLabel = string.Format(Language.Settings_Kofi, Plugin.Name);
ImGui.PushStyleColor(ImGuiCol.Button, ColourUtil.RgbaToAbgr(0xFF5E5BFF)); ImGui.PushStyleColor(ImGuiCol.Button, ColourUtil.RgbaToAbgr(0xFF5E5BFF));
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, ColourUtil.RgbaToAbgr(0xFF7775FF)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, ColourUtil.RgbaToAbgr(0xFF7775FF));
@ -130,7 +129,7 @@ internal sealed class Settings : IUiComponent {
ImGui.SameLine(ImGui.GetContentRegionAvail().X - buttonWidth); ImGui.SameLine(ImGui.GetContentRegionAvail().X - buttonWidth);
if (ImGui.Button(buttonLabel)) { if (ImGui.Button(buttonLabel)) {
Process.Start(new ProcessStartInfo("https://ko-fi.com/ascclemens") { Process.Start(new ProcessStartInfo("https://ko-fi.com/lojewalo") {
UseShellExecute = true, UseShellExecute = true,
}); });
} }

View File

@ -23,10 +23,10 @@ internal sealed class ChatColours : ISettingsTab {
.ToHashSet(); .ToHashSet();
var total = Enum.GetValues<ChatType>().Where(type => !type.IsGm()).ToHashSet(); var total = Enum.GetValues<ChatType>().Where(type => !type.IsGm()).ToHashSet();
if (sortable.Count != total.Count) { if (sortable.Count != total.Count) {
Dalamud.Logging.PluginLog.Warning($"There are {sortable.Count} sortable channels, but there are {total.Count} total channels."); Dalamud.Logging.Plugin.Log.Warning($"There are {sortable.Count} sortable channels, but there are {total.Count} total channels.");
total.ExceptWith(sortable); total.ExceptWith(sortable);
foreach (var missing in total) { foreach (var missing in total) {
Dalamud.Logging.PluginLog.Log($"Missing {missing}"); Dalamud.Logging.Plugin.Log.Log($"Missing {missing}");
} }
} }
#endif #endif

View File

@ -7,13 +7,15 @@ using ImGuiNET;
namespace ChatTwo.Ui.SettingsTabs; namespace ChatTwo.Ui.SettingsTabs;
internal sealed class Tabs : ISettingsTab { internal sealed class Tabs : ISettingsTab {
private Plugin Plugin { get; }
private Configuration Mutable { get; } private Configuration Mutable { get; }
public string Name => Language.Options_Tabs_Tab + "###tabs-tabs"; public string Name => Language.Options_Tabs_Tab + "###tabs-tabs";
private int _toOpen = -2; private int _toOpen = -2;
internal Tabs(Configuration mutable) { internal Tabs(Plugin plugin, Configuration mutable) {
this.Plugin = plugin;
this.Mutable = mutable; this.Mutable = mutable;
} }
@ -158,6 +160,35 @@ internal sealed class Tabs : ISettingsTab {
ImGui.TreePop(); ImGui.TreePop();
} }
if (this.Plugin.ExtraChat.ChannelNames.Count > 0 && ImGui.TreeNodeEx(Language.Options_Tabs_ExtraChatChannels)) {
ImGui.Checkbox(Language.Options_Tabs_ExtraChatAll, ref tab.ExtraChatAll);
ImGui.Separator();
if (tab.ExtraChatAll) {
ImGui.BeginDisabled();
}
foreach (var (id, name) in this.Plugin.ExtraChat.ChannelNames) {
var enabled = tab.ExtraChatChannels.Contains(id);
if (!ImGui.Checkbox($"{name}##ec-{id}", ref enabled)) {
continue;
}
if (enabled) {
tab.ExtraChatChannels.Add(id);
} else {
tab.ExtraChatChannels.Remove(id);
}
}
if (tab.ExtraChatAll) {
ImGui.EndDisabled();
}
ImGui.TreePop();
}
ImGui.TreePop(); ImGui.TreePop();
ImGui.PopID(); ImGui.PopID();

View File

@ -1,9 +1,9 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Dalamud; using Dalamud;
using Dalamud.Data;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Plugin.Services;
using Dalamud.Utility; using Dalamud.Utility;
using Lumina.Excel; using Lumina.Excel;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
@ -89,7 +89,7 @@ internal static class AutoTranslate {
return string.Join("", payloads); return string.Join("", payloads);
} }
private static List<AutoTranslateEntry> AllEntries(DataManager data) { private static List<AutoTranslateEntry> AllEntries(IDataManager data) {
if (Entries.TryGetValue(data.Language, out var entries)) { if (Entries.TryGetValue(data.Language, out var entries)) {
return entries; return entries;
} }
@ -197,7 +197,7 @@ internal static class AutoTranslate {
return list; return list;
} }
internal static List<AutoTranslateEntry> Matching(DataManager data, string prefix, bool sort) { internal static List<AutoTranslateEntry> Matching(IDataManager data, string prefix, bool sort) {
var wholeMatches = new List<AutoTranslateEntry>(); var wholeMatches = new List<AutoTranslateEntry>();
var prefixMatches = new List<AutoTranslateEntry>(); var prefixMatches = new List<AutoTranslateEntry>();
var otherMatches = new List<AutoTranslateEntry>(); var otherMatches = new List<AutoTranslateEntry>();
@ -227,7 +227,7 @@ internal static class AutoTranslate {
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count); private static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count);
internal static void ReplaceWithPayload(DataManager data, ref byte[] bytes) { internal static void ReplaceWithPayload(IDataManager data, ref byte[] bytes) {
var search = Encoding.UTF8.GetBytes("<at:"); var search = Encoding.UTF8.GetBytes("<at:");
if (bytes.Length <= search.Length) { if (bytes.Length <= search.Length) {
return; return;

View File

@ -63,11 +63,19 @@ internal static class ChunkUtil {
case PayloadType.Player: case PayloadType.Player:
link = payload; link = payload;
break; break;
case PayloadType.PartyFinder:
link = payload;
break;
case PayloadType.Unknown: case PayloadType.Unknown:
var rawPayload = (RawPayload) payload; var rawPayload = (RawPayload) payload;
if (rawPayload.Data.Length > 1 && rawPayload.Data[1] == 0x13) { if (rawPayload.Data.Length > 1 && rawPayload.Data[1] == 0x13) {
foreground.Pop(); if (foreground.Count > 0) {
glow.Pop(); foreground.Pop();
}
if (glow.Count > 0) {
glow.Pop();
}
} else if (rawPayload.Data.Length > 7 && rawPayload.Data[1] == 0x27 && rawPayload.Data[3] == 0x0A) { } else if (rawPayload.Data.Length > 7 && rawPayload.Data[1] == 0x27 && rawPayload.Data[3] == 0x0A) {
// pf payload // pf payload
var reader = new BinaryReader(new MemoryStream(rawPayload.Data[4..])); var reader = new BinaryReader(new MemoryStream(rawPayload.Data[4..]));
@ -80,8 +88,6 @@ internal static class ChunkUtil {
link = new AchievementPayload(id); link = new AchievementPayload(id);
} else if (Equals(rawPayload, RawPayload.LinkTerminator)) { } else if (Equals(rawPayload, RawPayload.LinkTerminator)) {
link = null; link = null;
} else if (Equals(rawPayload, PeriodicRecruitmentLink)) {
link = rawPayload;
} }
break; break;

View File

@ -4,6 +4,7 @@ using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace ChatTwo.Util; namespace ChatTwo.Util;

957
ChatTwo/packages.lock.json Normal file
View File

@ -0,0 +1,957 @@
{
"version": 1,
"dependencies": {
"net7.0-windows7.0": {
"DalamudPackager": {
"type": "Direct",
"requested": "[2.1.12, )",
"resolved": "2.1.12",
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
},
"LiteDB": {
"type": "Direct",
"requested": "[5.0.17, )",
"resolved": "5.0.17",
"contentHash": "cKPvkdlzIts3ZKu/BzoIc/Y71e4VFKlij4LyioPFATZMot+wB7EAm1FFbZSJez6coJmQUoIg/3yHE1MMU+zOdg=="
},
"Pidgin": {
"type": "Direct",
"requested": "[3.2.2, )",
"resolved": "3.2.2",
"contentHash": "imvuRt8fzxJCJs9kCk7s418NRyEdP6aDtz2qL9XYcn1ywTkpnrSq4IORVTQ879HNoTfJkyGkFadmEoCZEsebGg=="
},
"SharpDX.Direct2D1": {
"type": "Direct",
"requested": "[4.2.0, )",
"resolved": "4.2.0",
"contentHash": "Qs8LzDMaQf1u3KB8ArHu9pDv6itZ++QXs99a/bVAG+nKr0Hx5NG4mcN5vsfE0mVR2TkeHfeUm4PksRah6VUPtA==",
"dependencies": {
"NETStandard.Library": "1.6.1",
"SharpDX": "4.2.0",
"SharpDX.DXGI": "4.2.0"
}
},
"XivCommon": {
"type": "Direct",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "avaBp3FmSCi/PiQhntCeBDYOHejdyTWmFtz4pRBVQQ8vHkmRx+YTk1la9dkYBMlXxRXKckEdH1iI1Fu61JlE7w=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
},
"Microsoft.NETCore.Targets": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
},
"Microsoft.Win32.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"NETStandard.Library": {
"type": "Transitive",
"resolved": "1.6.1",
"contentHash": "WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.Win32.Primitives": "4.3.0",
"System.AppContext": "4.3.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Console": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tools": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Calendars": "4.3.0",
"System.IO": "4.3.0",
"System.IO.Compression": "4.3.0",
"System.IO.Compression.ZipFile": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Linq": "4.3.0",
"System.Linq.Expressions": "4.3.0",
"System.Net.Http": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Net.Sockets": "4.3.0",
"System.ObjectModel": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Extensions": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0",
"System.Text.RegularExpressions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"System.Threading.Timer": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0",
"System.Xml.XDocument": "4.3.0"
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q=="
},
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA=="
},
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw=="
},
"runtime.native.System": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.IO.Compression": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
"dependencies": {
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
}
},
"runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==",
"dependencies": {
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A=="
},
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g=="
},
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg=="
},
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ=="
},
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A=="
},
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg=="
},
"SharpDX": {
"type": "Transitive",
"resolved": "4.2.0",
"contentHash": "3pv0LFMvfK/dv1qISJnn8xBeeT6R/FRvr0EV4KI2DGsL84Qlv6P7isWqxGyU0LCwlSVCJN3jgHJ4Bl0KI2PJww==",
"dependencies": {
"NETStandard.Library": "1.6.1"
}
},
"SharpDX.DXGI": {
"type": "Transitive",
"resolved": "4.2.0",
"contentHash": "UjKqkgWc8U+SP+j3LBzFP6OB6Ntapjih7Xo+g1rLcsGbIb5KwewBrBChaUu7sil8rWoeVU/k0EJd3SMN4VqNZw==",
"dependencies": {
"NETStandard.Library": "1.6.1",
"SharpDX": "4.2.0"
}
},
"System.AppContext": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==",
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Buffers": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ratu44uTIHgeBeI0dE8DWvmXVBSo4u7ozRZZHOMmK/JPpYyo0dAfgSiHlpiObMQ5lEtEyIXA40sKRYg5J6A8uQ==",
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Collections": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Collections.Concurrent": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Console": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Diagnostics.Debug": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.DiagnosticSource": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Diagnostics.Tools": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.Tracing": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Calendars": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Globalization": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0"
}
},
"System.IO": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.Compression": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Buffers": "4.3.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.IO.Compression": "4.3.0"
}
},
"System.IO.Compression.ZipFile": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==",
"dependencies": {
"System.Buffers": "4.3.0",
"System.IO": "4.3.0",
"System.IO.Compression": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.IO.FileSystem": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Linq": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Linq.Expressions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Linq": "4.3.0",
"System.ObjectModel": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Emit": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Emit.Lightweight": "4.3.0",
"System.Reflection.Extensions": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Reflection.TypeExtensions": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.DiagnosticSource": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Extensions": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Net.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Net.Sockets": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.ObjectModel": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Reflection": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==",
"dependencies": {
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit.ILGeneration": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit.Lightweight": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.TypeExtensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==",
"dependencies": {
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Resources.ResourceManager": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"System.Runtime.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime.Handles": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime.InteropServices": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Reflection": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Runtime.InteropServices.RuntimeInformation": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==",
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Extensions": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0"
}
},
"System.Runtime.Numerics": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
"dependencies": {
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Security.Cryptography.Algorithms": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.Apple": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Cng": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Security.Cryptography.Csp": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Security.Cryptography.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
"dependencies": {
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Security.Cryptography.X509Certificates": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Calendars": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Cng": "4.3.0",
"System.Security.Cryptography.Csp": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Text.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Text.Encoding.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Text.RegularExpressions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Threading": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
"dependencies": {
"System.Runtime": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Threading.Tasks": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Threading.Timer": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Xml.ReaderWriter": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0",
"System.Text.RegularExpressions": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"System.Threading.Tasks.Extensions": "4.3.0"
}
},
"System.Xml.XDocument": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tools": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0"
}
}
}
}
}

6
fix_resources.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
for f in ChatTwo/Resources/Language.resx ChatTwo/Resources/Language.*.resx; do
sed -i 's/ xml:space="preserve"//g' "$f"
xmlstarlet fo -e utf-8 -s 4 "$f" | sponge "$f"
done

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB