diff --git a/CustomizePlus.GameData/CustomizePlus.GameData.csproj b/CustomizePlus.GameData/CustomizePlus.GameData.csproj
index ad75ed3..f10e52c 100644
--- a/CustomizePlus.GameData/CustomizePlus.GameData.csproj
+++ b/CustomizePlus.GameData/CustomizePlus.GameData.csproj
@@ -45,4 +45,12 @@
+
+
+
+ INCOGNIFY_STRINGS
+
+
diff --git a/CustomizePlus/Core/ServiceManagerBuilder.cs b/CustomizePlus/Core/ServiceManagerBuilder.cs
index b5d28f8..a3b87b6 100644
--- a/CustomizePlus/Core/ServiceManagerBuilder.cs
+++ b/CustomizePlus/Core/ServiceManagerBuilder.cs
@@ -137,7 +137,8 @@ private static ServiceManager AddCore(this ServiceManager services)
.AddSingleton()
.AddSingleton()
.AddSingleton()
- .AddSingleton();
+ .AddSingleton()
+ .AddSingleton();
return services;
}
diff --git a/CustomizePlus/Core/Services/SupportLogBuilderService.cs b/CustomizePlus/Core/Services/SupportLogBuilderService.cs
new file mode 100644
index 0000000..5570422
--- /dev/null
+++ b/CustomizePlus/Core/Services/SupportLogBuilderService.cs
@@ -0,0 +1,134 @@
+using CustomizePlus.Armatures.Services;
+using CustomizePlus.Configuration.Data;
+using CustomizePlus.Core.Data;
+using CustomizePlus.Core.Extensions;
+using CustomizePlus.Profiles;
+using CustomizePlus.Templates;
+using Dalamud.Plugin;
+using OtterGui.Services;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CustomizePlus.Core.Services;
+
+//Based on Penumbra's support log
+public class SupportLogBuilderService
+{
+ private readonly PluginConfiguration _configuration;
+ private readonly TemplateManager _templateManager;
+ private readonly ProfileManager _profileManager;
+ private readonly ArmatureManager _armatureManager;
+ private readonly DalamudPluginInterface _dalamudPluginInterface;
+
+ public SupportLogBuilderService(
+ PluginConfiguration configuration,
+ TemplateManager templateManager,
+ ProfileManager profileManager,
+ ArmatureManager armatureManager,
+ DalamudPluginInterface dalamudPluginInterface)
+ {
+ _configuration = configuration;
+ _templateManager = templateManager;
+ _profileManager = profileManager;
+ _armatureManager = armatureManager;
+ _dalamudPluginInterface = dalamudPluginInterface;
+ }
+
+ public string BuildSupportLog()
+ {
+ var sb = new StringBuilder(10240);
+ sb.AppendLine("**Settings**");
+ sb.Append($"> **`Plugin Version: `** {Plugin.Version}\n");
+ sb.Append($"> **`Commit Hash: `** {ThisAssembly.Git.Commit}+{ThisAssembly.Git.Sha}\n");
+ sb.Append($"> **`Root editing: `** {_configuration.EditorConfiguration.RootPositionEditingEnabled}\n");
+ sb.AppendLine("**Settings -> Editor Settings**");
+ sb.Append($"> **`Limit to my creatures (editor): `** {_configuration.EditorConfiguration.LimitLookupToOwnedObjects}\n");
+ sb.Append($"> **`Preview character (editor): `** {_configuration.EditorConfiguration.PreviewCharacterName?.Incognify() ?? "Not set"}\n");
+ sb.AppendLine("**Settings -> Profile application**");
+ sb.Append($"> **`Character window: `** {_configuration.ProfileApplicationSettings.ApplyInCharacterWindow}\n");
+ sb.Append($"> **`Try On: `** {_configuration.ProfileApplicationSettings.ApplyInTryOn}\n");
+ sb.Append($"> **`Cards: `** {_configuration.ProfileApplicationSettings.ApplyInCards}\n");
+ sb.Append($"> **`Inspect: `** {_configuration.ProfileApplicationSettings.ApplyInInspect}\n");
+ sb.Append($"> **`Lobby: `** {_configuration.ProfileApplicationSettings.ApplyInLobby}\n");
+ sb.AppendLine("**Relevant plugins**");
+ GatherRelevantPlugins(sb);
+ sb.AppendLine("**Templates**");
+ sb.Append($"> **`Count: `** {_templateManager.Templates.Count}\n");
+ foreach (var template in _templateManager.Templates)
+ {
+ sb.Append($"> > **`{template.ToString(),-29}`**\n");
+ }
+ sb.AppendLine("**Profiles**");
+ sb.Append($"> **`Count: `** {_profileManager.Profiles.Count}\n");
+ foreach (var profile in _profileManager.Profiles)
+ {
+ sb.Append($"> > =====\n");
+ sb.Append($"> > **`{profile.ToString(),-29}`*\n");
+ sb.Append($"> > **`Name: {profile.Name.Text.Incognify()}`**\n");
+ sb.Append($"> > **`Type: {profile.ProfileType}`**\n");
+ sb.Append($"> > **`Character name: {profile.CharacterName.Text.Incognify()}`**\n");
+ sb.Append($"> > **`Limit to my creatures: {profile.LimitLookupToOwnedObjects}`**\n");
+ sb.Append($"> > **`Templates:`**\n");
+ sb.Append($"> > > **`Count: {profile.Templates.Count}`**\n");
+ foreach (var template in profile.Templates)
+ {
+ sb.Append($"> > > **`{template.ToString()}`**\n");
+ }
+ sb.Append($"> > **`Armatures:`**\n");
+ sb.Append($"> > > **`Count: {profile.Armatures.Count}`**\n");
+ foreach (var armature in profile.Armatures)
+ {
+ sb.Append($"> > > **`{armature.ToString()}`**\n");
+ }
+ sb.Append($"> > =====\n");
+ }
+ sb.AppendLine("**Armatures**");
+ sb.Append($"> **`Count: `** {_armatureManager.Armatures.Count}\n");
+ foreach (var kvPair in _armatureManager.Armatures)
+ {
+ var identifier = kvPair.Key;
+ var armature = kvPair.Value;
+ sb.Append($"> > =====\n");
+ sb.Append($"> > **`{armature.ToString(),-29}`**\n");
+ sb.Append($"> > **`Actor: {armature.ActorIdentifier.Incognito(null) ?? "None"}`**\n");
+ sb.Append($"> > **`Built: {armature.IsBuilt}`**\n");
+ sb.Append($"> > **`Visible: {armature.IsVisible}`**\n");
+ sb.Append($"> > **`Pending rebind: {armature.IsPendingProfileRebind}`**\n");
+ sb.Append($"> > **`Last seen: {armature.LastSeen}`**\n");
+ sb.Append($"> > **`Profile: {armature.Profile?.ToString() ?? "None"}`**\n");
+ sb.Append($"> > **`Main Root Bone/Total Bones/Partial Skeleton Count: {armature.MainRootBone}/{armature.TotalBoneCount}/{armature.PartialSkeletonCount}`**\n");
+ sb.Append($"> > **`Bone template bindings:`**\n");
+ foreach (var bindingKvPair in armature.BoneTemplateBinding)
+ {
+ sb.Append($"> > > **`{BoneData.GetBoneDisplayName(bindingKvPair.Key)} ({bindingKvPair.Key}) -> {bindingKvPair.Value.ToString()}`**\n");
+ }
+ sb.Append($"> > =====\n");
+ }
+ return sb.ToString();
+ }
+
+
+ private void GatherRelevantPlugins(StringBuilder sb)
+ {
+ ReadOnlySpan relevantPlugins =
+ [
+ "MareSynchronos", "Ktisis", "Brio", "DynamicBridge"
+ ];
+ var plugins = _dalamudPluginInterface.InstalledPlugins
+ .GroupBy(p => p.InternalName)
+ .ToDictionary(g => g.Key, g =>
+ {
+ var item = g.OrderByDescending(p => p.IsLoaded).ThenByDescending(p => p.Version).First();
+ return (item.IsLoaded, item.Version, item.Name);
+ });
+ foreach (var plugin in relevantPlugins)
+ {
+ if (plugins.TryGetValue(plugin, out var data))
+ sb.Append($"> **`{data.Name + ':',-29}`** {data.Version}{(data.IsLoaded ? string.Empty : " (Disabled)")}\n");
+ }
+ }
+}
diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj
index ef310d9..d6d9e28 100644
--- a/CustomizePlus/CustomizePlus.csproj
+++ b/CustomizePlus/CustomizePlus.csproj
@@ -38,6 +38,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
all
@@ -82,7 +86,7 @@
-
diff --git a/CustomizePlus/Plugin.cs b/CustomizePlus/Plugin.cs
index 4bc0456..1240593 100644
--- a/CustomizePlus/Plugin.cs
+++ b/CustomizePlus/Plugin.cs
@@ -9,13 +9,25 @@
using OtterGui.Services;
using CustomizePlus.Api;
using ECommons;
+using ECommons.Commands;
+using ECommons.Configuration;
+using OtterGui;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using System.Linq;
+using CustomizePlus.Configuration.Data;
+using CustomizePlus.Core.Extensions;
+using CustomizePlus.Templates;
+using CustomizePlus.Profiles;
+using CustomizePlus.Armatures.Services;
namespace CustomizePlus;
public sealed class Plugin : IDalamudPlugin
{
#if DEBUG
- public static readonly string Version = $"{Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty} [DEBUG]";
+ public static readonly string Version = $"{ThisAssembly.Git.Commit}+{ThisAssembly.Git.Sha} [DEBUG]";
#else
public static readonly string Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;
#endif
@@ -40,7 +52,7 @@ public Plugin(DalamudPluginInterface pluginInterface)
_services.GetService();
_services.GetService();
- Logger.Information($"Customize+ v{Version} [FantasiaPlus] started");
+ Logger.Information($"Customize+ v{Version} ({ThisAssembly.Git.Commit}+{ThisAssembly.Git.Sha}) [FantasiaPlus] started");
}
catch (Exception ex)
{
diff --git a/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs b/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs
index d4eb6d2..631156d 100644
--- a/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs
+++ b/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs
@@ -12,6 +12,7 @@
using CustomizePlus.Core.Extensions;
using System.Numerics;
using CustomizePlus.Game.Services;
+using CustomizePlus.Core.Data;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Debug;
@@ -187,7 +188,7 @@ private void DrawSingleTemplate(string prefix, Template template)
#if !INCOGNIFY_STRINGS
ImGui.Text($"{kvPair.Key}: p: {kvPair.Value.Translation} | r: {kvPair.Value.Rotation} | s: {kvPair.Value.Scaling}");
#else
- ImGui.Text($"{kvPair.Key}: p: {(kvPair.Value.Translation.IsApproximately(Vector3.Zero) ? "Approx. not changed" : "Changed")} | r: {(kvPair.Value.Rotation.IsApproximately(Vector3.Zero) ? "Approx. not changed" : "Changed")} | s: {(kvPair.Value.Scaling.IsApproximately(Vector3.One) ? "Not changed" : "Changed")}");
+ ImGui.Text($"{BoneData.GetBoneDisplayName(kvPair.Key)} ({kvPair.Key}): p: {(kvPair.Value.Translation.IsApproximately(Vector3.Zero) ? "Approx. not changed" : "Changed")} | r: {(kvPair.Value.Rotation.IsApproximately(Vector3.Zero) ? "Approx. not changed" : "Changed")} | s: {(kvPair.Value.Scaling.IsApproximately(Vector3.One) ? "Not changed" : "Changed")}");
#endif
}
}
@@ -215,7 +216,7 @@ private void DrawSingleArmature(string prefix, Armature armature)
ImGui.Text($"Bone template bindings:");
foreach (var kvPair in armature.BoneTemplateBinding)
{
- ImGui.Text($"{kvPair.Key} -> {kvPair.Value.Name.Text.Incognify()} ({kvPair.Value.UniqueId})");
+ ImGui.Text($"{BoneData.GetBoneDisplayName(kvPair.Key)} ({kvPair.Key}) -> {kvPair.Value.Name.Text.Incognify()} ({kvPair.Value.UniqueId})");
}
}
}
diff --git a/CustomizePlus/UI/Windows/MainWindow/Tabs/SettingsTab.cs b/CustomizePlus/UI/Windows/MainWindow/Tabs/SettingsTab.cs
index 1ba8d42..f4581ee 100644
--- a/CustomizePlus/UI/Windows/MainWindow/Tabs/SettingsTab.cs
+++ b/CustomizePlus/UI/Windows/MainWindow/Tabs/SettingsTab.cs
@@ -28,6 +28,7 @@ public class SettingsTab
private readonly TemplateEditorManager _templateEditorManager;
private readonly CPlusChangeLog _changeLog;
private readonly MessageService _messageService;
+ private readonly SupportLogBuilderService _supportLogBuilderService;
public SettingsTab(
PluginConfiguration configuration,
@@ -35,7 +36,8 @@ public SettingsTab(
HookingService hookingService,
TemplateEditorManager templateEditorManager,
CPlusChangeLog changeLog,
- MessageService messageService)
+ MessageService messageService,
+ SupportLogBuilderService supportLogBuilderService)
{
_configuration = configuration;
_armatureManager = armatureManager;
@@ -43,6 +45,7 @@ public SettingsTab(
_templateEditorManager = templateEditorManager;
_changeLog = changeLog;
_messageService = messageService;
+ _supportLogBuilderService = supportLogBuilderService;
}
public void Draw()
@@ -53,6 +56,7 @@ public void Draw()
DrawGeneralSettings();
+ ImGui.NewLine();
ImGui.NewLine();
ImGui.NewLine();
@@ -299,7 +303,7 @@ private void DrawDebugModeCheckbox()
#region Support Area
private void DrawSupportButtons()
{
- var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2;
+ var width = ImGui.CalcTextSize("Copy Support Info to Clipboard").X + ImGui.GetStyle().FramePadding.X * 2;
var xPos = ImGui.GetWindowWidth() - width;
// Respect the scroll bar width.
if (ImGui.GetScrollMaxY() > 0)
@@ -311,6 +315,14 @@ private void DrawSupportButtons()
ImGui.SetCursorPos(new Vector2(xPos, 1 * ImGui.GetFrameHeightWithSpacing()));
if (ImGui.Button("Show update history", new Vector2(width, 0)))
_changeLog.Changelog.ForceOpen = true;
+
+ ImGui.SetCursorPos(new Vector2(xPos, 2 * ImGui.GetFrameHeightWithSpacing()));
+ if (!ImGui.Button("Copy Support Info to Clipboard"))
+ return;
+
+ var text = _supportLogBuilderService.BuildSupportLog();
+ ImGui.SetClipboardText(text);
+ _messageService.NotificationMessage($"Copied Support Info to Clipboard.", NotificationType.Success, false);
}
/// Draw a button to open the official discord server.