DalamudPython/DalamudPython/Commands.cs

115 lines
3.5 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Dalamud.IoC;
using Dalamud.Plugin;
namespace DalamudPython {
public class Commands {
public static readonly Dictionary<string, string> All = new() {
["/python"] = "Run a line of Python",
["/py"] = "Alias for /python",
["/pyprint"] = "Run a line of Python and print the result to the chat window",
["/pyadd"] = "Add a line of Python to a temporary script",
["/pyexecute"] = "Run the temporary script",
["/pyreset"] = "Clear the temporary script",
["/pyload"] = "Read the contents of a file relative to the config folder and run them as a Python script",
};
private Plugin Plugin { get; }
private string? Script { get; set; }
private Dictionary<object, object> Store { get; } = new();
public Commands(Plugin plugin) {
this.Plugin = plugin;
}
public void OnCommand(string name, string args) {
switch (name) {
case "/python":
case "/py":
case "/pyprint":
this.OneLiner(name, args);
break;
case "/pyadd":
this.Add(args);
break;
case "/pyexecute":
this.RunScript(args);
break;
case "/pyreset":
this.Script = null;
break;
case "/pyload":
this.LoadFile(args);
break;
}
}
private void Add(string args) {
this.Script ??= "";
this.Script += args + "\n";
}
private void RunScript(string args) {
var script = this.Script;
if (script == null) {
return;
}
var print = args == "print";
try {
this.Execute(script, print);
} finally {
this.Script = null;
}
}
private void Execute(string script, bool print) {
var services = typeof(IDalamudPlugin).Assembly.GetTypes()
.Where(t => t.GetCustomAttribute(typeof(PluginInterfaceAttribute)) != null)
.Where(t => t.Namespace != null)
.Select(t => $"from {t.Namespace!} import {t.Name}");
var scope = this.Plugin.Engine.CreateScope();
scope.SetVariable("interface", this.Plugin.Interface);
scope.SetVariable("store", this.Store);
var fullScript = $@"import clr
from DalamudPython.Util import *
from Dalamud import *
from Dalamud.Plugin import *
{string.Join('\n', services)}
from Lumina import *
from Lumina.Excel.GeneratedSheets import *
### begin custom
{script}";
var result = this.Plugin.Engine.Execute(fullScript, scope);
if (!print) {
return;
}
this.Plugin.ChatGui.Print(result.ToString());
}
private void OneLiner(string name, string args) {
var print = name == "/pyprint";
this.Execute(args, print);
}
private void LoadFile(string args) {
if (string.IsNullOrWhiteSpace(args)) {
return;
}
var scriptPath = Path.Combine(this.Plugin.ConfigDirectory, args);
var script = File.ReadAllText(scriptPath);
this.Execute(script, false);
}
}
}