using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using Pal.Client.Rendering;
using Pal.Client.Windows;
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Pal.Client.Properties;
using ECommons;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Pal.Client.Commands;
using Pal.Client.Configuration;
using Pal.Client.DependencyInjection;
namespace Pal.Client
{
///
/// With all DI logic elsewhere, this plugin shell really only takes care of a few things around events that
/// need to be sent to different receivers depending on priority or configuration .
///
///
internal sealed class Plugin : IDisposable
{
private readonly DalamudPluginInterface _pluginInterface;
private readonly ILogger _logger;
private readonly CommandManager _commandManager;
private readonly Chat _chat;
private readonly WindowSystem _windowSystem;
private readonly ClientState _clientState;
private readonly IServiceScope _rootScope;
private readonly DependencyInjectionLoader _loader;
private Action? _loginAction = null;
public Plugin(
DalamudPluginInterface pluginInterface,
IServiceProvider serviceProvider,
CancellationToken cancellationToken)
{
_pluginInterface = pluginInterface;
_logger = serviceProvider.GetRequiredService>();
_commandManager = serviceProvider.GetRequiredService();
_chat = serviceProvider.GetRequiredService();
_windowSystem = serviceProvider.GetRequiredService();
_clientState = serviceProvider.GetRequiredService();
_rootScope = serviceProvider.CreateScope();
_loader = _rootScope.ServiceProvider.GetRequiredService();
_loader.InitCompleted += InitCompleted;
var _ = Task.Run(async () => await _loader.InitializeAsync(cancellationToken));
pluginInterface.UiBuilder.Draw += Draw;
pluginInterface.UiBuilder.OpenConfigUi += OpenConfigUi;
pluginInterface.LanguageChanged += LanguageChanged;
_clientState.Login += Login;
_commandManager.AddHandler("/pal", new CommandInfo(OnCommand)
{
HelpMessage = Localization.Command_pal_HelpText
});
}
private void InitCompleted(Action? loginAction)
{
LanguageChanged(_pluginInterface.UiLanguage);
if (_clientState.IsLoggedIn)
{
loginAction?.Invoke();
_loginAction = null;
}
else
_loginAction = loginAction;
}
private void Login(object? sender, EventArgs eventArgs)
{
_loginAction?.Invoke();
_loginAction = null;
}
private void OnCommand(string command, string arguments)
{
arguments = arguments.Trim();
IPalacePalConfiguration configuration =
_rootScope.ServiceProvider.GetRequiredService();
if (configuration.FirstUse && arguments != "" && arguments != "config")
{
_chat.Error(Localization.Error_FirstTimeSetupRequired);
return;
}
try
{
var sp = _rootScope.ServiceProvider;
switch (arguments)
{
case "":
case "config":
sp.GetRequiredService().Execute();
break;
case "stats":
sp.GetRequiredService().Execute();
break;
case "tc":
case "test-connection":
sp.GetRequiredService().Execute();
break;
case "near":
case "tnear":
case "hnear":
sp.GetRequiredService().Execute(arguments);
break;
default:
_chat.Error(string.Format(Localization.Command_pal_UnknownSubcommand, arguments,
command));
break;
}
}
catch (Exception e)
{
_chat.Error(e.ToString());
}
}
private void OpenConfigUi()
=> _rootScope.ServiceProvider.GetRequiredService().Execute();
private void LanguageChanged(string languageCode)
{
_logger.LogInformation("Language set to '{Language}'", languageCode);
Localization.Culture = new CultureInfo(languageCode);
_windowSystem.Windows.OfType()
.Each(w => w.LanguageChanged());
}
private void Draw()
{
if (_loader.LoadState == DependencyInjectionLoader.ELoadState.Loaded)
{
_rootScope.ServiceProvider.GetRequiredService().DrawLayers();
_windowSystem.Draw();
}
}
public void Dispose()
{
_commandManager.RemoveHandler("/pal");
_pluginInterface.UiBuilder.Draw -= Draw;
_pluginInterface.UiBuilder.OpenConfigUi -= OpenConfigUi;
_pluginInterface.LanguageChanged -= LanguageChanged;
_clientState.Login -= Login;
_loader.InitCompleted -= InitCompleted;
_rootScope.Dispose();
}
}
}