Files
CustomizeTool/CustomizePlus/Core/Services/CommandService.cs

241 lines
9.9 KiB
C#

using Dalamud.Game.Command;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin.Services;
using OtterGui.Classes;
using System;
using System.Linq;
using OtterGui.Log;
using Dalamud.Game.Text.SeStringHandling;
using CustomizePlus.Profiles;
using CustomizePlus.Game.Services;
using CustomizePlus.UI.Windows.MainWindow.Tabs.Templates;
using CustomizePlus.UI.Windows.MainWindow;
using static System.Windows.Forms.AxHost;
using CustomizePlus.Profiles.Data;
using CustomizePlus.Configuration.Data;
namespace CustomizePlus.Core.Services;
public class CommandService : IDisposable
{
private readonly ProfileManager _profileManager;
private readonly GameObjectService _gameObjectService;
private readonly ICommandManager _commandManager;
private readonly Logger _logger;
private readonly ChatService _chatService;
private readonly MainWindow _mainWindow;
private readonly BoneEditorPanel _boneEditorPanel;
private readonly MessageService _messageService;
private readonly PluginConfiguration _pluginConfiguration;
private static readonly string[] Commands = new[] { "/customize", "/c+" };
public CommandService(
ProfileManager profileManager,
GameObjectService gameObjectService,
ICommandManager commandManager,
MainWindow mainWindow,
ChatService chatService,
BoneEditorPanel boneEditorPanel,
Logger logger,
MessageService messageService,
PluginConfiguration pluginConfiguration)
{
_profileManager = profileManager;
_gameObjectService = gameObjectService;
_commandManager = commandManager;
_logger = logger;
_chatService = chatService;
_mainWindow = mainWindow;
_boneEditorPanel = boneEditorPanel;
_messageService = messageService;
_pluginConfiguration = pluginConfiguration;
foreach (var command in Commands)
{
_commandManager.AddHandler(command, new CommandInfo(OnMainCommand) { HelpMessage = "Toggles main plugin window if no commands passed. Use \"/customize help\" for list of available commands." });
}
if (_pluginConfiguration.CommandSettings.PrintSuccessMessages)
chatService.PrintInChat($"Started!"); //safe to assume at this point we have successfully initialized
}
public void Dispose()
{
foreach (var command in Commands)
{
_commandManager.RemoveHandler(command);
}
}
private void OnMainCommand(string command, string arguments)
{
if (_boneEditorPanel.IsEditorActive)
{
_messageService.NotificationMessage("Customize+ commands cannot be used when editor is active", NotificationType.Error);
return;
}
var argumentList = arguments.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var argument = argumentList.Length == 2 ? argumentList[1] : string.Empty;
if (arguments.Length > 0)
{
switch (argumentList[0].ToLowerInvariant())
{
case "profile":
ProfileCommand(argument);
return;
default:
case "help":
PrintHelp(argumentList[0]);
return;
}
}
_mainWindow.Toggle();
}
private bool PrintHelp(string argument)
{
if (!string.Equals(argument, "help", StringComparison.OrdinalIgnoreCase) && argument != "?")
_chatService.PrintInChat(new SeStringBuilder().AddText("The given argument ").AddRed(argument, true)
.AddText(" is not valid. Valid arguments are:").BuiltString);
else
_chatService.PrintInChat(new SeStringBuilder().AddText("Valid arguments for /customize are:").BuiltString);
_chatService.PrintInChat(new SeStringBuilder().AddCommand("profile", "Change the state of profiles. Use without arguments for help.")
.BuiltString);
return true;
}
private void ProfileCommand(string argument)
{
var argumentList = argument.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
string[]? subArgumentList = null;
if(argumentList.Length == 2)
subArgumentList = argumentList[1].Split(',', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
bool isTurningOffAllProfiles = subArgumentList != null && subArgumentList.Length != 2 && argumentList[0] == "disable";
if (argumentList.Length != 2 || subArgumentList == null || (subArgumentList.Length != 2 && !isTurningOffAllProfiles))
{
_chatService.PrintInChat(new SeStringBuilder().AddText($"Usage: /customize profile ")
.AddBlue("enable, disable or toggle", true)
.AddText(" ")
.AddRed("Character Name", true)
.AddText(",")
.AddYellow("Profile Name", true)
.BuiltString);
_chatService.PrintInChat(new SeStringBuilder().AddText(" 》 ").AddBlue("disable", true)
.AddText(" option can also be used without supplying profile name to turn off currently active profile for the character").BuiltString);
_chatService.PrintInChat(new SeStringBuilder().AddText(" 》 ")
.AddRed("Character Name", true).AddText(" can be either full character name or one of the following:").BuiltString);
_chatService.PrintInChat(new SeStringBuilder().AddText(" 》 To apply to yourself: ").AddBlue("<me>").AddText(", ").AddBlue("self").BuiltString);
_chatService.PrintInChat(new SeStringBuilder().AddText(" 》 To apply to target: ").AddBlue("<t>").AddText(", ").AddBlue("target").BuiltString);
return;
}
string characterName = "", profileName = "";
try
{
if (!_profileManager.Profiles.Any())
{
_chatService.PrintInChat(new SeStringBuilder().AddText("This command cannot be executed because no profiles exist").BuiltString);
return;
}
bool? state = null;
switch (argumentList[0].ToLowerInvariant())
{
case "enabled":
case "enable":
case "on":
case "true":
state = true;
break;
case "disabled":
case "disable":
case "off":
case "false":
state = false;
break;
case "toggle":
case "switch":
break;
}
Profile? targetProfile = null;
characterName = subArgumentList[0].Trim();
characterName = characterName switch
{
"<me>" => _gameObjectService.GetCurrentPlayerName() ?? string.Empty,
"self" => _gameObjectService.GetCurrentPlayerName() ?? string.Empty,
"<t>" => _gameObjectService.GetCurrentPlayerTargetName() ?? string.Empty,
"target" => _gameObjectService.GetCurrentPlayerTargetName() ?? string.Empty,
_ => characterName,
};
if (!isTurningOffAllProfiles)
{
profileName = subArgumentList[1].Trim();
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.Name == profileName && x.CharacterName == characterName);
}
else
targetProfile = _profileManager.Profiles.FirstOrDefault(x => x.CharacterName == characterName && x.Enabled);
if (targetProfile == null)
{
_chatService.PrintInChat(new SeStringBuilder()
.AddText("Cannot execute command because profile ")
.AddYellow(string.IsNullOrWhiteSpace(profileName) ? "[Any enabled profile]" : profileName)
.AddText(" for ")
.AddRed(characterName)
.AddText(" was not found").BuiltString);
return;
}
if (state != null)
{
if(targetProfile.Enabled == state)
{
_chatService.PrintInChat(new SeStringBuilder()
.AddText("Profile ")
.AddYellow(targetProfile.Name)
.AddText(" for ")
.AddBlue(characterName)
.AddText(" is already ")
.AddGreen((bool)state ? "enabled" : "disabled").BuiltString);
return;
}
_profileManager.SetEnabled(targetProfile, (bool)state);
}
else
_profileManager.SetEnabled(targetProfile, !targetProfile.Enabled);
if (_pluginConfiguration.CommandSettings.PrintSuccessMessages)
_chatService.PrintInChat(new SeStringBuilder()
.AddText("Profile ")
.AddYellow(targetProfile.Name)
.AddText(" was successfully ")
.AddBlue(state != null ? ((bool)state ? "enabled" : "disabled") : "toggled")
.AddText(" for ")
.AddRed(targetProfile.CharacterName).BuiltString);
}
catch (Exception e)
{
_chatService.PrintInChat(new SeStringBuilder()
.AddRed($"Error while changing state of profile, details are available in dalamud log").BuiltString);
_logger.Error($"Error while changing state of profile by command:\n" +
$"Profile name \"{(string.IsNullOrWhiteSpace(profileName) ? "empty (none provided)" : profileName)}\"\n" +
$"Character name \"{(string.IsNullOrWhiteSpace(characterName) ? "empty (none provided)" : characterName)}\"\n" +
$"Arguments: {argument}\nError: {e}");
}
}
}