mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
Remove scratchpad
So sad, a king among features.
This commit is contained in:
parent
ef16e346c6
commit
653363fd8f
7 changed files with 0 additions and 778 deletions
|
|
@ -43,7 +43,6 @@ namespace Dalamud.Interface.Internal
|
||||||
private readonly ConsoleWindow consoleWindow;
|
private readonly ConsoleWindow consoleWindow;
|
||||||
private readonly PluginStatWindow pluginStatWindow;
|
private readonly PluginStatWindow pluginStatWindow;
|
||||||
private readonly PluginInstallerWindow pluginWindow;
|
private readonly PluginInstallerWindow pluginWindow;
|
||||||
private readonly ScratchpadWindow scratchpadWindow;
|
|
||||||
private readonly SettingsWindow settingsWindow;
|
private readonly SettingsWindow settingsWindow;
|
||||||
private readonly SelfTestWindow selfTestWindow;
|
private readonly SelfTestWindow selfTestWindow;
|
||||||
private readonly StyleEditorWindow styleEditorWindow;
|
private readonly StyleEditorWindow styleEditorWindow;
|
||||||
|
|
@ -77,7 +76,6 @@ namespace Dalamud.Interface.Internal
|
||||||
this.consoleWindow = new ConsoleWindow() { IsOpen = configuration.LogOpenAtStartup };
|
this.consoleWindow = new ConsoleWindow() { IsOpen = configuration.LogOpenAtStartup };
|
||||||
this.pluginStatWindow = new PluginStatWindow() { IsOpen = false };
|
this.pluginStatWindow = new PluginStatWindow() { IsOpen = false };
|
||||||
this.pluginWindow = new PluginInstallerWindow() { IsOpen = false };
|
this.pluginWindow = new PluginInstallerWindow() { IsOpen = false };
|
||||||
this.scratchpadWindow = new ScratchpadWindow() { IsOpen = false };
|
|
||||||
this.settingsWindow = new SettingsWindow() { IsOpen = false };
|
this.settingsWindow = new SettingsWindow() { IsOpen = false };
|
||||||
this.selfTestWindow = new SelfTestWindow() { IsOpen = false };
|
this.selfTestWindow = new SelfTestWindow() { IsOpen = false };
|
||||||
this.styleEditorWindow = new StyleEditorWindow() { IsOpen = false };
|
this.styleEditorWindow = new StyleEditorWindow() { IsOpen = false };
|
||||||
|
|
@ -92,7 +90,6 @@ namespace Dalamud.Interface.Internal
|
||||||
this.WindowSystem.AddWindow(this.consoleWindow);
|
this.WindowSystem.AddWindow(this.consoleWindow);
|
||||||
this.WindowSystem.AddWindow(this.pluginStatWindow);
|
this.WindowSystem.AddWindow(this.pluginStatWindow);
|
||||||
this.WindowSystem.AddWindow(this.pluginWindow);
|
this.WindowSystem.AddWindow(this.pluginWindow);
|
||||||
this.WindowSystem.AddWindow(this.scratchpadWindow);
|
|
||||||
this.WindowSystem.AddWindow(this.settingsWindow);
|
this.WindowSystem.AddWindow(this.settingsWindow);
|
||||||
this.WindowSystem.AddWindow(this.selfTestWindow);
|
this.WindowSystem.AddWindow(this.selfTestWindow);
|
||||||
this.WindowSystem.AddWindow(this.styleEditorWindow);
|
this.WindowSystem.AddWindow(this.styleEditorWindow);
|
||||||
|
|
@ -130,7 +127,6 @@ namespace Dalamud.Interface.Internal
|
||||||
|
|
||||||
this.creditsWindow.Dispose();
|
this.creditsWindow.Dispose();
|
||||||
this.consoleWindow.Dispose();
|
this.consoleWindow.Dispose();
|
||||||
this.scratchpadWindow.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Open
|
#region Open
|
||||||
|
|
@ -198,11 +194,6 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenPluginInstaller() => this.pluginWindow.IsOpen = true;
|
public void OpenPluginInstaller() => this.pluginWindow.IsOpen = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Opens the <see cref="ScratchpadWindow"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void OpenScratchpadWindow() => this.scratchpadWindow.IsOpen = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the <see cref="SettingsWindow"/>.
|
/// Opens the <see cref="SettingsWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -294,11 +285,6 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void TogglePluginInstallerWindow() => this.pluginWindow.Toggle();
|
public void TogglePluginInstallerWindow() => this.pluginWindow.Toggle();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the <see cref="ScratchpadWindow"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void ToggleScratchpadWindow() => this.scratchpadWindow.Toggle();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggles the <see cref="SettingsWindow"/>.
|
/// Toggles the <see cref="SettingsWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -621,21 +607,6 @@ namespace Dalamud.Interface.Internal
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.BeginMenu("Scratchpad"))
|
|
||||||
{
|
|
||||||
if (ImGui.MenuItem("Open Scratchpad"))
|
|
||||||
{
|
|
||||||
this.OpenScratchpadWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.MenuItem("Dispose all scratches"))
|
|
||||||
{
|
|
||||||
this.scratchpadWindow.Execution.DisposeAllScratches();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginMenu("Localization"))
|
if (ImGui.BeginMenu("Localization"))
|
||||||
{
|
{
|
||||||
var localization = Service<Localization>.Get();
|
var localization = Service<Localization>.Get();
|
||||||
|
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
using Dalamud.IoC.Internal;
|
|
||||||
using Dalamud.Plugin;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
|
||||||
using Microsoft.CodeAnalysis.Scripting;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Scratchpad
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class manages the execution of <see cref="ScratchpadDocument"/> classes.
|
|
||||||
/// </summary>
|
|
||||||
internal class ScratchExecutionManager
|
|
||||||
{
|
|
||||||
private Dictionary<Guid, IDalamudPlugin> loadedScratches = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ScratchExecutionManager"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public ScratchExecutionManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ScratchPad macro processor.
|
|
||||||
/// </summary>
|
|
||||||
public ScratchMacroProcessor MacroProcessor { get; private set; } = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose of all currently loaded ScratchPads.
|
|
||||||
/// </summary>
|
|
||||||
public void DisposeAllScratches()
|
|
||||||
{
|
|
||||||
foreach (var dalamudPlugin in this.loadedScratches)
|
|
||||||
{
|
|
||||||
dalamudPlugin.Value.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loadedScratches.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Renew a given ScratchPadDocument.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="doc">The document to renew.</param>
|
|
||||||
/// <returns>The new load status.</returns>
|
|
||||||
public ScratchLoadStatus RenewScratch(ScratchpadDocument doc)
|
|
||||||
{
|
|
||||||
var existingScratch = this.loadedScratches.FirstOrDefault(x => x.Key == doc.Id);
|
|
||||||
if (existingScratch.Value != null)
|
|
||||||
{
|
|
||||||
existingScratch.Value.Dispose();
|
|
||||||
this.loadedScratches[existingScratch.Key] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var code = doc.IsMacro ? this.MacroProcessor.Process(doc.Content) : doc.Content;
|
|
||||||
|
|
||||||
var options = ScriptOptions.Default
|
|
||||||
// Dalamud
|
|
||||||
.AddReferences(typeof(Dalamud).Assembly)
|
|
||||||
// ImGui
|
|
||||||
.AddReferences(typeof(ImGuiNET.ImGui).Assembly)
|
|
||||||
// ImGuiScene
|
|
||||||
.AddReferences(typeof(ImGuiScene.RawDX11Scene).Assembly)
|
|
||||||
// FFXIVClientStructs
|
|
||||||
.AddReferences(typeof(FFXIVClientStructs.Resolver).Assembly)
|
|
||||||
// Lumina
|
|
||||||
.AddReferences(typeof(Lumina.GameData).Assembly)
|
|
||||||
// Lumina.Excel
|
|
||||||
.AddReferences(typeof(Lumina.Excel.GeneratedSheets.TerritoryType).Assembly)
|
|
||||||
.AddImports("System")
|
|
||||||
.AddImports("System.IO")
|
|
||||||
.AddImports("System.Reflection")
|
|
||||||
.AddImports("System.Runtime.InteropServices")
|
|
||||||
.AddImports("Dalamud")
|
|
||||||
.AddImports("Dalamud.Data")
|
|
||||||
.AddImports("Dalamud.Game")
|
|
||||||
.AddImports("Dalamud.Game.ClientState")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Buddy")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Conditions")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Fates")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.JobGauge")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Keys")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Objects")
|
|
||||||
.AddImports("Dalamud.Game.ClientState.Party")
|
|
||||||
.AddImports("Dalamud.Game.Command")
|
|
||||||
.AddImports("Dalamud.Game.Gui")
|
|
||||||
.AddImports("Dalamud.Game.Gui.FlyText")
|
|
||||||
.AddImports("Dalamud.Game.Gui.PartyFinder")
|
|
||||||
.AddImports("Dalamud.Game.Gui.Toast")
|
|
||||||
.AddImports("Dalamud.Hooking")
|
|
||||||
.AddImports("Dalamud.Game.Libc")
|
|
||||||
.AddImports("Dalamud.Game.Network")
|
|
||||||
.AddImports("Dalamud.Game.Text.SeStringHandling")
|
|
||||||
.AddImports("Dalamud.Logging")
|
|
||||||
.AddImports("Dalamud.Plugin")
|
|
||||||
.AddImports("Dalamud.Utility")
|
|
||||||
.AddImports("ImGuiNET");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var script = CSharpScript.Create(code, options);
|
|
||||||
|
|
||||||
var pluginType = script.ContinueWith<Type>("return typeof(ScratchPlugin);")
|
|
||||||
.RunAsync().GetAwaiter().GetResult().ReturnValue;
|
|
||||||
|
|
||||||
var pi = new DalamudPluginInterface($"Scratch-{doc.Id}", PluginLoadReason.Unknown, false);
|
|
||||||
|
|
||||||
var ioc = Service<ServiceContainer>.Get();
|
|
||||||
var plugin = ioc.Create(pluginType, pi);
|
|
||||||
|
|
||||||
if (plugin == null)
|
|
||||||
throw new Exception("Could not initialize scratch plugin");
|
|
||||||
|
|
||||||
this.loadedScratches[doc.Id] = (IDalamudPlugin)plugin;
|
|
||||||
return ScratchLoadStatus.Success;
|
|
||||||
}
|
|
||||||
catch (CompilationErrorException ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Compilation error occurred!\n" + string.Join(Environment.NewLine, ex.Diagnostics));
|
|
||||||
return ScratchLoadStatus.FailureCompile;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Initialization error occured!\n");
|
|
||||||
|
|
||||||
return ScratchLoadStatus.FailureInit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Scratchpad
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A file watcher for <see cref="ScratchpadDocument"/> classes.
|
|
||||||
/// </summary>
|
|
||||||
internal class ScratchFileWatcher
|
|
||||||
{
|
|
||||||
private FileSystemWatcher watcher = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the list of tracked ScratchPad documents.
|
|
||||||
/// </summary>
|
|
||||||
public List<ScratchpadDocument> TrackedScratches { get; set; } = new List<ScratchpadDocument>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load a new ScratchPadDocument from disk.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The filepath to load.</param>
|
|
||||||
public void Load(string path)
|
|
||||||
{
|
|
||||||
this.TrackedScratches.Add(new ScratchpadDocument
|
|
||||||
{
|
|
||||||
Title = Path.GetFileName(path),
|
|
||||||
Content = File.ReadAllText(path),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.watcher.Path = Path.GetDirectoryName(path);
|
|
||||||
this.watcher.Filter = Path.GetFileName(path);
|
|
||||||
this.watcher.EnableRaisingEvents = true;
|
|
||||||
this.watcher.Changed += (sender, args) => this.TrackedScratches[0].Content = File.ReadAllText(args.FullPath);
|
|
||||||
this.watcher.BeginInit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
namespace Dalamud.Interface.Internal.Scratchpad
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The load status of a <see cref="ScratchpadDocument"/> class.
|
|
||||||
/// </summary>
|
|
||||||
internal enum ScratchLoadStatus
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown.
|
|
||||||
/// </summary>
|
|
||||||
Unknown,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Failure to compile.
|
|
||||||
/// </summary>
|
|
||||||
FailureCompile,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Failure to initialize.
|
|
||||||
/// </summary>
|
|
||||||
FailureInit,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Success.
|
|
||||||
/// </summary>
|
|
||||||
Success,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,309 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
using Dalamud.Logging;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Scratchpad
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class converts ScratchPad macros into runnable scripts.
|
|
||||||
/// </summary>
|
|
||||||
internal class ScratchMacroProcessor
|
|
||||||
{
|
|
||||||
private const string Template = @"
|
|
||||||
|
|
||||||
public class ScratchPlugin : IDalamudPlugin {
|
|
||||||
|
|
||||||
public string Name => ""ScratchPlugin"";
|
|
||||||
|
|
||||||
private readonly DalamudPluginInterface pi;
|
|
||||||
private readonly BuddyList buddies;
|
|
||||||
private readonly ChatGui chat;
|
|
||||||
private readonly ChatHandlers chatHandlers;
|
|
||||||
private readonly ClientState clientState;
|
|
||||||
private readonly CommandManager commands;
|
|
||||||
private readonly Condition condition;
|
|
||||||
private readonly DataManager data;
|
|
||||||
private readonly FateTable fates;
|
|
||||||
private readonly FlyTextGui flyText;
|
|
||||||
private readonly Framework framework;
|
|
||||||
private readonly GameGui gameGui;
|
|
||||||
private readonly GameNetwork gameNetwork;
|
|
||||||
private readonly JobGauges gauges;
|
|
||||||
private readonly KeyState keyState;
|
|
||||||
private readonly LibcFunction libc;
|
|
||||||
private readonly ObjectTable objects;
|
|
||||||
private readonly PartyFinderGui pfGui;
|
|
||||||
private readonly PartyList party;
|
|
||||||
private readonly SeStringManager seStringManager;
|
|
||||||
private readonly SigScanner sigScanner;
|
|
||||||
private readonly TargetManager targets;
|
|
||||||
private readonly ToastGui toasts;
|
|
||||||
|
|
||||||
{SETUPBODY}
|
|
||||||
|
|
||||||
public ScratchPlugin(
|
|
||||||
DalamudPluginInterface pluginInterface,
|
|
||||||
BuddyList buddies,
|
|
||||||
ChatGui chat,
|
|
||||||
ChatHandlers chatHandlers,
|
|
||||||
ClientState clientState,
|
|
||||||
CommandManager commands,
|
|
||||||
Condition condition,
|
|
||||||
DataManager data,
|
|
||||||
FateTable fates,
|
|
||||||
FlyTextGui flyText,
|
|
||||||
Framework framework,
|
|
||||||
GameGui gameGui,
|
|
||||||
GameNetwork gameNetwork,
|
|
||||||
JobGauges gauges,
|
|
||||||
KeyState keyState,
|
|
||||||
LibcFunction libcFunction,
|
|
||||||
ObjectTable objects,
|
|
||||||
PartyFinderGui pfGui,
|
|
||||||
PartyList party,
|
|
||||||
SeStringManager seStringManager,
|
|
||||||
SigScanner sigScanner,
|
|
||||||
TargetManager targets,
|
|
||||||
ToastGui toasts)
|
|
||||||
{
|
|
||||||
this.pi = pluginInterface;
|
|
||||||
|
|
||||||
this.buddies = buddies;
|
|
||||||
this.chat = chat;
|
|
||||||
this.chatHandlers = chatHandlers;
|
|
||||||
this.clientState = clientState;
|
|
||||||
this.commands = commands;
|
|
||||||
this.condition = condition;
|
|
||||||
this.data = data;
|
|
||||||
this.fates = fates;
|
|
||||||
this.flyText = flyText;
|
|
||||||
this.framework = framework;
|
|
||||||
this.gameGui = gameGui;
|
|
||||||
this.gameNetwork = gameNetwork;
|
|
||||||
this.gauges = gauges;
|
|
||||||
this.keyState = keyState;
|
|
||||||
this.libc = libcFunction;
|
|
||||||
this.objects = objects;
|
|
||||||
this.pfGui = pfGui;
|
|
||||||
this.party = party;
|
|
||||||
this.seStringManager = seStringManager;
|
|
||||||
this.sigScanner = sigScanner;
|
|
||||||
this.targets = targets;
|
|
||||||
this.toasts = toasts;
|
|
||||||
|
|
||||||
this.pi.UiBuilder.Draw += DrawUI;
|
|
||||||
|
|
||||||
{INITBODY}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawUI()
|
|
||||||
{
|
|
||||||
{DRAWBODY}
|
|
||||||
}
|
|
||||||
|
|
||||||
{NONEBODY}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
this.pi.UiBuilder.Draw -= DrawUI;
|
|
||||||
{DISPOSEBODY}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
";
|
|
||||||
|
|
||||||
private enum ParseContext
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Init,
|
|
||||||
Draw,
|
|
||||||
Hook,
|
|
||||||
Dispose,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Process the given macro input and return a script.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Input to process.</param>
|
|
||||||
/// <returns>A runnable script.</returns>
|
|
||||||
public string Process(string input)
|
|
||||||
{
|
|
||||||
var lines = input.Split(new[] { '\r', '\n' });
|
|
||||||
|
|
||||||
var ctx = ParseContext.None;
|
|
||||||
|
|
||||||
var setupBody = string.Empty;
|
|
||||||
var noneBody = string.Empty;
|
|
||||||
var initBody = string.Empty;
|
|
||||||
var disposeBody = string.Empty;
|
|
||||||
var drawBody = string.Empty;
|
|
||||||
var tHook = new HookInfo();
|
|
||||||
|
|
||||||
var hooks = new List<HookInfo>();
|
|
||||||
|
|
||||||
for (var i = 0; i < lines.Length; i++)
|
|
||||||
{
|
|
||||||
var line = lines[i];
|
|
||||||
|
|
||||||
if (line.StartsWith("INITIALIZE:"))
|
|
||||||
{
|
|
||||||
ctx = ParseContext.Init;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith("DRAW:"))
|
|
||||||
{
|
|
||||||
ctx = ParseContext.Draw;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith("DISPOSE:"))
|
|
||||||
{
|
|
||||||
ctx = ParseContext.Dispose;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith("HOOK("))
|
|
||||||
{
|
|
||||||
ctx = ParseContext.Hook;
|
|
||||||
|
|
||||||
var args = Regex.Match(line, "HOOK\\((.+)+\\):").Groups[0].Captures[0].Value
|
|
||||||
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => x[0] == ' ' ? x[1..] : x).ToArray();
|
|
||||||
|
|
||||||
tHook.Sig = args[0].Replace("\"", string.Empty); // Split quotation marks if any
|
|
||||||
tHook.Sig = tHook.Sig.Replace("HOOK(", string.Empty);
|
|
||||||
tHook.RetType = args[1];
|
|
||||||
tHook.Arguments = string.Join(", ", args.Skip(2).ToArray()).Replace("):", string.Empty);
|
|
||||||
|
|
||||||
var invocationGroups = Regex.Matches(tHook.Arguments, "\\S+ ([a-zA-Z0-9]+),*").Cast<Match>()
|
|
||||||
.Select(x => x.Groups[1].Value);
|
|
||||||
tHook.Invocation = string.Join(", ", invocationGroups);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith("END;"))
|
|
||||||
{
|
|
||||||
switch (ctx)
|
|
||||||
{
|
|
||||||
case ParseContext.None:
|
|
||||||
throw new Exception("Not in a macro!!!");
|
|
||||||
case ParseContext.Init:
|
|
||||||
break;
|
|
||||||
case ParseContext.Draw:
|
|
||||||
break;
|
|
||||||
case ParseContext.Hook:
|
|
||||||
hooks.Add(tHook);
|
|
||||||
tHook = new HookInfo();
|
|
||||||
break;
|
|
||||||
case ParseContext.Dispose:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(paramName: nameof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = ParseContext.None;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ctx)
|
|
||||||
{
|
|
||||||
case ParseContext.None:
|
|
||||||
noneBody += line + "\n";
|
|
||||||
break;
|
|
||||||
case ParseContext.Init:
|
|
||||||
initBody += line + "\n";
|
|
||||||
break;
|
|
||||||
case ParseContext.Draw:
|
|
||||||
drawBody += line + "\n";
|
|
||||||
break;
|
|
||||||
case ParseContext.Hook:
|
|
||||||
tHook.Body += line + "\n";
|
|
||||||
break;
|
|
||||||
case ParseContext.Dispose:
|
|
||||||
disposeBody += line + "\n";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(paramName: nameof(input));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hookSetup = string.Empty;
|
|
||||||
var hookInit = string.Empty;
|
|
||||||
var hookDetour = string.Empty;
|
|
||||||
var hookDispose = string.Empty;
|
|
||||||
for (var i = 0; i < hooks.Count; i++)
|
|
||||||
{
|
|
||||||
var hook = hooks[i];
|
|
||||||
|
|
||||||
hookSetup += $"private delegate {hook.RetType} Hook{i}Delegate({hook.Arguments});\n";
|
|
||||||
hookSetup += $"private Hook<Hook{i}Delegate> hook{i}Inst;\n";
|
|
||||||
|
|
||||||
hookInit += $"var addrH{i} = pi.TargetModuleScanner.ScanText(\"{hook.Sig}\");\n";
|
|
||||||
hookInit += $"this.hook{i}Inst = new Hook<Hook{i}Delegate>(addrH{i}, new Hook{i}Delegate(Hook{i}Detour), this);\n";
|
|
||||||
hookInit += $"this.hook{i}Inst.Enable();\n";
|
|
||||||
|
|
||||||
var originalCall = $"this.hook{i}Inst.Original({hook.Invocation});\n";
|
|
||||||
if (hook.RetType != "void")
|
|
||||||
originalCall = "return " + originalCall;
|
|
||||||
|
|
||||||
if (hook.Body.Contains($"hook{i}Inst.Original(") || hook.Body.Contains("ORIG("))
|
|
||||||
{
|
|
||||||
PluginLog.Warning($"Attention! A manual call to Original() in Hook #{i} was detected. Original calls will not be managed for you.");
|
|
||||||
originalCall = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hook.Body.Contains("ORIG("))
|
|
||||||
{
|
|
||||||
PluginLog.Warning($"Normalizing Original() call in Hook #{i}.");
|
|
||||||
hook.Body = hook.Body.Replace("ORIG(", $"this.hook{i}Inst.Original(");
|
|
||||||
}
|
|
||||||
|
|
||||||
hookDetour +=
|
|
||||||
$"private {hook.RetType} Hook{i}Detour({hook.Arguments}) {{\n" +
|
|
||||||
(!string.IsNullOrEmpty(originalCall) ? "try {\n" : string.Empty) +
|
|
||||||
$" {hook.Body}\n";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(originalCall))
|
|
||||||
{
|
|
||||||
hookDetour += "} catch(Exception ex) {\n" +
|
|
||||||
$" PluginLog.Error(ex, \"Exception in Hook{i}Detour!!\");\n" +
|
|
||||||
"}\n" +
|
|
||||||
$"{originalCall}";
|
|
||||||
}
|
|
||||||
|
|
||||||
hookDetour += $"\n}}\n";
|
|
||||||
|
|
||||||
hookDispose += $"this.hook{i}Inst.Dispose();\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
setupBody += "\n" + hookSetup;
|
|
||||||
initBody = hookInit + "\n" + initBody;
|
|
||||||
noneBody += "\n" + hookDetour;
|
|
||||||
disposeBody += "\n" + hookDispose;
|
|
||||||
|
|
||||||
var output = Template;
|
|
||||||
output = output.Replace("{SETUPBODY}", setupBody);
|
|
||||||
output = output.Replace("{INITBODY}", initBody);
|
|
||||||
output = output.Replace("{DRAWBODY}", drawBody);
|
|
||||||
output = output.Replace("{NONEBODY}", noneBody);
|
|
||||||
output = output.Replace("{DISPOSEBODY}", disposeBody);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class HookInfo
|
|
||||||
{
|
|
||||||
public string Body { get; set; }
|
|
||||||
|
|
||||||
public string Arguments { get; set; }
|
|
||||||
|
|
||||||
public string Invocation { get; set; }
|
|
||||||
|
|
||||||
public string RetType { get; set; }
|
|
||||||
|
|
||||||
public string Sig { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Scratchpad
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents a single document in the ScratchPad.
|
|
||||||
/// </summary>
|
|
||||||
internal class ScratchpadDocument
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the guid ID of the document.
|
|
||||||
/// </summary>
|
|
||||||
public Guid Id { get; set; } = Guid.NewGuid();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the document content.
|
|
||||||
/// </summary>
|
|
||||||
public string Content { get; set; } = "INITIALIZE:\n\tPluginLog.Information(\"Loaded!\");\nEND;\n\nDISPOSE:\n\tPluginLog.Information(\"Disposed!\");\nEND;\n";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the document title.
|
|
||||||
/// </summary>
|
|
||||||
public string Title { get; set; } = "New Document";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the document has unsaved content.
|
|
||||||
/// </summary>
|
|
||||||
public bool HasUnsaved { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the document is open.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsOpen { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the load status of the document.
|
|
||||||
/// </summary>
|
|
||||||
public ScratchLoadStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this document is a macro.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsMacro { get; set; } = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,196 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
using Dalamud.Interface.Colors;
|
|
||||||
using Dalamud.Interface.Internal.Scratchpad;
|
|
||||||
using Dalamud.Interface.Windowing;
|
|
||||||
using ImGuiNET;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class facilitates interacting with the ScratchPad window.
|
|
||||||
/// </summary>
|
|
||||||
internal class ScratchpadWindow : Window, IDisposable
|
|
||||||
{
|
|
||||||
private readonly List<ScratchpadDocument> documents = new();
|
|
||||||
private readonly ScratchFileWatcher watcher = new();
|
|
||||||
private string pathInput = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ScratchpadWindow"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public ScratchpadWindow()
|
|
||||||
: base("Plugin Scratchpad", ImGuiWindowFlags.MenuBar)
|
|
||||||
{
|
|
||||||
this.documents.Add(new ScratchpadDocument());
|
|
||||||
|
|
||||||
this.SizeConstraints = new WindowSizeConstraints
|
|
||||||
{
|
|
||||||
MinimumSize = new Vector2(400, 400),
|
|
||||||
MaximumSize = new Vector2(1000, 1000),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Execution = new ScratchExecutionManager();
|
|
||||||
|
|
||||||
this.RespectCloseHotkey = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ScratchPad execution manager.
|
|
||||||
/// </summary>
|
|
||||||
public ScratchExecutionManager Execution { get; private set; }
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public override void Draw()
|
|
||||||
{
|
|
||||||
if (ImGui.BeginPopupModal("Choose Path"))
|
|
||||||
{
|
|
||||||
ImGui.Text("Enter path:\n\n");
|
|
||||||
|
|
||||||
ImGui.InputText("###ScratchPathInput", ref this.pathInput, 1000);
|
|
||||||
|
|
||||||
if (ImGui.Button("OK", new Vector2(120, 0)))
|
|
||||||
{
|
|
||||||
ImGui.CloseCurrentPopup();
|
|
||||||
this.watcher.Load(this.pathInput);
|
|
||||||
this.pathInput = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SetItemDefaultFocus();
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGui.Button("Cancel", new Vector2(120, 0)))
|
|
||||||
{
|
|
||||||
ImGui.CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginMenuBar())
|
|
||||||
{
|
|
||||||
if (ImGui.BeginMenu("File"))
|
|
||||||
{
|
|
||||||
if (ImGui.MenuItem("Load & Watch"))
|
|
||||||
{
|
|
||||||
ImGui.OpenPopup("Choose Path");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags = ImGuiTabBarFlags.Reorderable | ImGuiTabBarFlags.TabListPopupButton |
|
|
||||||
ImGuiTabBarFlags.FittingPolicyScroll;
|
|
||||||
|
|
||||||
if (ImGui.BeginTabBar("ScratchDocTabBar", flags))
|
|
||||||
{
|
|
||||||
if (ImGui.TabItemButton("+", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
|
|
||||||
this.documents.Add(new ScratchpadDocument());
|
|
||||||
|
|
||||||
var docs = this.documents.Concat(this.watcher.TrackedScratches).ToArray();
|
|
||||||
|
|
||||||
for (var i = 0; i < docs.Length; i++)
|
|
||||||
{
|
|
||||||
var isOpen = true;
|
|
||||||
|
|
||||||
if (ImGui.BeginTabItem(docs[i].Title + (docs[i].HasUnsaved ? "*" : string.Empty) + "###ScratchItem" + i, ref isOpen))
|
|
||||||
{
|
|
||||||
var content = docs[i].Content;
|
|
||||||
if (ImGui.InputTextMultiline("###ScratchInput" + i, ref content, 20000, new Vector2(-1, -34), ImGuiInputTextFlags.AllowTabInput))
|
|
||||||
{
|
|
||||||
docs[i].Content = content;
|
|
||||||
docs[i].HasUnsaved = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(3);
|
|
||||||
|
|
||||||
if (ImGui.Button("Compile & Reload"))
|
|
||||||
{
|
|
||||||
docs[i].Status = this.Execution.RenewScratch(docs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button("Dispose all"))
|
|
||||||
{
|
|
||||||
this.Execution.DisposeAllScratches();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button("Dump processed code"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var code = this.Execution.MacroProcessor.Process(docs[i].Content);
|
|
||||||
Log.Information(code);
|
|
||||||
ImGui.SetClipboardText(code);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Could not process macros");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button("Toggle Log"))
|
|
||||||
{
|
|
||||||
Service<DalamudInterface>.Get().ToggleLogWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
var isMacro = docs[i].IsMacro;
|
|
||||||
if (ImGui.Checkbox("Use Macros", ref isMacro))
|
|
||||||
{
|
|
||||||
docs[i].IsMacro = isMacro;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
switch (docs[i].Status)
|
|
||||||
{
|
|
||||||
case ScratchLoadStatus.Unknown:
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudGrey, "Compile scratch to see status");
|
|
||||||
break;
|
|
||||||
case ScratchLoadStatus.FailureCompile:
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "Error during compilation");
|
|
||||||
break;
|
|
||||||
case ScratchLoadStatus.FailureInit:
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "Error during init");
|
|
||||||
break;
|
|
||||||
case ScratchLoadStatus.Success:
|
|
||||||
ImGui.TextColored(ImGuiColors.HealerGreen, "OK!");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudGrey, docs[i].Id.ToString());
|
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTabBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose of managed and unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
this.Execution.DisposeAllScratches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue