using Dalamud.Game.Command; using Dalamud.Plugin; using MareSynchronos.Factories; using Dalamud.Game; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState; using Dalamud.Interface.ImGuiFileDialog; using MareSynchronos.Managers; using MareSynchronos.WebAPI; using Dalamud.Interface.Windowing; using MareSynchronos.UI; using MareSynchronos.Utils; using Dalamud.Game.ClientState.Conditions; using MareSynchronos.FileCache; using Dalamud.Game.Gui; using MareSynchronos.Export; using Dalamud.Data; using MareSynchronos.MareConfiguration; namespace MareSynchronos; public sealed class Plugin : IDalamudPlugin { private const string _commandName = "/mare"; private readonly ApiController _apiController; private readonly CommandManager _commandManager; private readonly PeriodicFileScanner _periodicFileScanner; private readonly IntroUi _introUi; private readonly IpcManager _ipcManager; private readonly DalamudPluginInterface _pluginInterface; private readonly SettingsUi _settingsUi; private readonly WindowSystem _windowSystem; private PlayerManager? _playerManager; private TransientResourceManager? _transientResourceManager; private readonly DalamudUtil _dalamudUtil; private OnlinePlayerManager? _characterCacheManager; private readonly DownloadUi _downloadUi; private readonly FileDialogManager _fileDialogManager; private readonly FileCacheManager _fileCacheManager; private readonly PairManager _pairManager; private readonly CompactUi _compactUi; private readonly UiShared _uiSharedComponent; private readonly Dalamud.Localization _localization; private readonly FileReplacementFactory _fileReplacementFactory; private readonly MareCharaFileManager _mareCharaFileManager; private readonly ServerConfigurationManager _serverConfigurationManager; private readonly GposeUi _gposeUi; private readonly ConfigurationService _configurationService; public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager, DataManager gameData, Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition, ChatGui chatGui) { Logger.Debug("Launching " + Name); _pluginInterface = pluginInterface; _pluginInterface.UiBuilder.DisableGposeUiHide = true; _commandManager = commandManager; _configurationService = new(_pluginInterface); _localization = new Dalamud.Localization("MareSynchronos.Localization.", "", useEmbedded: true); _localization.SetupWithLangCode("en"); _windowSystem = new WindowSystem("MareSynchronos"); // those can be initialized outside of game login _dalamudUtil = new DalamudUtil(clientState, objectTable, framework, condition, chatGui, gameData); _ipcManager = new IpcManager(_pluginInterface, _dalamudUtil); _fileDialogManager = new FileDialogManager(); _fileCacheManager = new FileCacheManager(_ipcManager, _configurationService); _serverConfigurationManager = new ServerConfigurationManager(_configurationService, _dalamudUtil); _pairManager = new PairManager(new CachedPlayerFactory(_ipcManager, _dalamudUtil, _fileCacheManager), _dalamudUtil, new PairFactory(_configurationService, _serverConfigurationManager), _pluginInterface.UiBuilder, _configurationService); _apiController = new ApiController(_configurationService, _dalamudUtil, _fileCacheManager, _pairManager, _serverConfigurationManager); _periodicFileScanner = new PeriodicFileScanner(_ipcManager, _configurationService, _fileCacheManager, _apiController, _dalamudUtil); _fileReplacementFactory = new FileReplacementFactory(_fileCacheManager, _ipcManager); _mareCharaFileManager = new(_fileCacheManager, _ipcManager, _configurationService, _dalamudUtil); _uiSharedComponent = new UiShared(_ipcManager, _apiController, _periodicFileScanner, _fileDialogManager, _configurationService, _dalamudUtil, _pluginInterface, _localization, _serverConfigurationManager); _settingsUi = new SettingsUi(_windowSystem, _uiSharedComponent, _configurationService, _mareCharaFileManager, _pairManager, _serverConfigurationManager); _compactUi = new CompactUi(_windowSystem, _uiSharedComponent, _configurationService, _apiController, _pairManager, _serverConfigurationManager); _gposeUi = new GposeUi(_windowSystem, _mareCharaFileManager, _dalamudUtil, _fileDialogManager, _configurationService); _introUi = new IntroUi(_windowSystem, _uiSharedComponent, _configurationService, _periodicFileScanner, _serverConfigurationManager); _settingsUi.SwitchToIntroUi += () => { _introUi.IsOpen = true; _settingsUi.IsOpen = false; _compactUi.IsOpen = false; }; _introUi.SwitchToMainUi += () => { _introUi.IsOpen = false; _compactUi.IsOpen = true; _periodicFileScanner.StartScan(); ReLaunchCharacterManager(); }; _compactUi.OpenSettingsUi += () => { _settingsUi.Toggle(); }; _downloadUi = new DownloadUi(_windowSystem, _configurationService, _apiController, _uiSharedComponent); _dalamudUtil.LogIn += DalamudUtilOnLogIn; _dalamudUtil.LogOut += DalamudUtilOnLogOut; if (_dalamudUtil.IsLoggedIn) { DalamudUtilOnLogIn(); } } public string Name => "Mare Synchronos"; public void Dispose() { Logger.Verbose("Disposing " + Name); _apiController?.Dispose(); _commandManager.RemoveHandler(_commandName); _dalamudUtil.LogIn -= DalamudUtilOnLogIn; _dalamudUtil.LogOut -= DalamudUtilOnLogOut; _uiSharedComponent.Dispose(); _settingsUi?.Dispose(); _introUi?.Dispose(); _downloadUi?.Dispose(); _compactUi?.Dispose(); _gposeUi?.Dispose(); _pairManager.Dispose(); _periodicFileScanner?.Dispose(); _fileCacheManager?.Dispose(); _playerManager?.Dispose(); _characterCacheManager?.Dispose(); _ipcManager?.Dispose(); _transientResourceManager?.Dispose(); _dalamudUtil.Dispose(); _configurationService?.Dispose(); Logger.Debug("Shut down"); } private void DalamudUtilOnLogIn() { Logger.Debug("Client login"); _pluginInterface.UiBuilder.Draw += Draw; _pluginInterface.UiBuilder.OpenConfigUi += OpenUi; _commandManager.AddHandler(_commandName, new CommandInfo(OnCommand) { HelpMessage = "Opens the Mare Synchronos UI", }); if (!_configurationService.Current.HasValidSetup() || !_serverConfigurationManager.HasValidConfig()) { _introUi.IsOpen = true; _compactUi.IsOpen = false; return; } _periodicFileScanner.StartScan(); ReLaunchCharacterManager(); } private void DalamudUtilOnLogOut() { Logger.Debug("Client logout"); _characterCacheManager?.Dispose(); _playerManager?.Dispose(); _transientResourceManager?.Dispose(); _pluginInterface.UiBuilder.Draw -= Draw; _pluginInterface.UiBuilder.OpenConfigUi -= OpenUi; _commandManager.RemoveHandler(_commandName); } public void ReLaunchCharacterManager() { _characterCacheManager?.Dispose(); _playerManager?.Dispose(); _transientResourceManager?.Dispose(); Task.Run(WaitForPlayerAndLaunchCharacterManager); } private async Task WaitForPlayerAndLaunchCharacterManager() { while (!_dalamudUtil.IsPlayerPresent) { await Task.Delay(100).ConfigureAwait(false); } try { Logger.Debug("Launching Managers"); _transientResourceManager = new TransientResourceManager(_ipcManager, _configurationService, _dalamudUtil, _fileReplacementFactory); var characterCacheFactory = new CharacterDataFactory(_dalamudUtil, _ipcManager, _transientResourceManager, _fileReplacementFactory); _playerManager = new PlayerManager(_apiController, _ipcManager, characterCacheFactory, _dalamudUtil, _transientResourceManager, _periodicFileScanner, _settingsUi); _characterCacheManager = new OnlinePlayerManager(_apiController, _dalamudUtil, _playerManager, _fileCacheManager, _pairManager); } catch (Exception ex) { Logger.Warn(ex.Message); } } private void Draw() { _windowSystem.Draw(); _fileDialogManager.Draw(); } private void OnCommand(string command, string args) { var splitArgs = args.ToLowerInvariant().Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries); if (splitArgs == null || splitArgs.Length == 0) { // Interpret this as toggling the UI OpenUi(); return; } if (string.Equals(splitArgs[0], "toggle", StringComparison.OrdinalIgnoreCase)) { if (_serverConfigurationManager.CurrentServer == null) return; var fullPause = splitArgs.Length > 1 ? splitArgs[1] switch { "on" => false, "off" => true, _ => !_serverConfigurationManager.CurrentServer.FullPause, } : !_serverConfigurationManager.CurrentServer.FullPause; if (fullPause != _serverConfigurationManager.CurrentServer.FullPause) { _serverConfigurationManager.CurrentServer.FullPause = fullPause; _serverConfigurationManager.Save(); _ = _apiController.CreateConnections(); } } else if (string.Equals(splitArgs[0], "gpose", StringComparison.OrdinalIgnoreCase)) { _gposeUi.Toggle(); } } private void OpenUi() { if (_configurationService.Current.HasValidSetup()) _compactUi.Toggle(); else _introUi.Toggle(); } }