Skip to content

Commit

Permalink
switch to dependency injection
Browse files Browse the repository at this point in the history
  • Loading branch information
dit-zy committed Jan 26, 2024
1 parent ece8403 commit 223ac49
Show file tree
Hide file tree
Showing 14 changed files with 723 additions and 207 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Dalamud.Configuration;
using System;
using Dalamud.Configuration;
using Dalamud.Plugin;
using System;

namespace ScoutHelper;
namespace ScoutHelper.Config;

[Serializable]
public class Configuration : IPluginConfiguration {

// the below exist just to make saving less cumbersome
// the below exists just to make saving less cumbersome
[NonSerialized]
private DalamudPluginInterface _pluginInterface = null!;

Expand Down
7 changes: 7 additions & 0 deletions ScoutHelper/Config/ScoutHelperOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Microsoft.Extensions.Options;

namespace ScoutHelper.Config;

public record ScoutHelperOptions(
string BearDataFile
) { }
1 change: 1 addition & 0 deletions ScoutHelper/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static class Constants {
#region core constants

public const string DefaultCopyTemplate = "{patch} {#}/{#max} {world} [{tracker}]({link})";
public const string BearDataFile = @"Data\Bear.json";

#endregion

Expand Down
33 changes: 20 additions & 13 deletions ScoutHelper/Managers/BearManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,27 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Plugin.Services;
using ScoutHelper.Config;

namespace ScoutHelper.Managers;

public class BearManager : IDisposable {
private readonly IPluginLog _log;
private readonly Configuration _conf;
private static HttpClient HttpClient { get; } = new();

private IDictionary<uint, (Patch patch, string name)> MobIdToBearName { get; init; }

public BearManager(string dataFilePath) {
HttpClient.BaseAddress = new Uri(Plugin.Conf.BearApiBaseUrl);
public BearManager(IPluginLog log, Configuration conf, ScoutHelperOptions options) {
_log = log;
_conf = conf;

HttpClient.BaseAddress = new Uri(_conf.BearApiBaseUrl);
HttpClient.DefaultRequestHeaders.UserAgent.Add(Constants.UserAgent);
HttpClient.Timeout = Plugin.Conf.BearApiTimeout;
HttpClient.Timeout = _conf.BearApiTimeout;

MobIdToBearName = LoadData(dataFilePath);
MobIdToBearName = LoadData(options.BearDataFile);
}

public void Dispose() {
Expand Down Expand Up @@ -93,14 +100,14 @@ IEnumerable<TrainMob> trainMobs
.Max();

var requestPayload = JsonConvert.SerializeObject(
new BearApiTrainRequest(worldName, Plugin.Conf.BearTrainName, highestPatch.BearName(), spawnPoints)
new BearApiTrainRequest(worldName, _conf.BearTrainName, highestPatch.BearName(), spawnPoints)
);
Plugin.Log.Debug("Request payload: {0}", requestPayload);
_log.Debug("Request payload: {0}", requestPayload);
var requestContent = new StringContent(requestPayload, Encoding.UTF8, Constants.MediaTypeJson);

try {
var response = await HttpClient.PostAsync(Plugin.Conf.BearApiTrainPath, requestContent);
Plugin.Log.Debug(
var response = await HttpClient.PostAsync(_conf.BearApiTrainPath, requestContent);
_log.Debug(
"Request: {0}\n\nResponse: {1}",
response.RequestMessage!.ToString(),
response.ToString()
Expand All @@ -111,22 +118,22 @@ IEnumerable<TrainMob> trainMobs
var responseJson = await response.Content.ReadAsStringAsync();
var trainInfo = JsonConvert.DeserializeObject<BearApiTrainResponse>(responseJson).Trains.First();

var url = $"{Plugin.Conf.BearSiteTrainUrl}/{trainInfo.TrainId}";
var url = $"{_conf.BearSiteTrainUrl}/{trainInfo.TrainId}";
return new BearLinkData(url, trainInfo.Password, highestPatch);
} catch (TimeoutException) {
const string message = "Timed out posting the train to Bear ;-;";
Plugin.Log.Error(message);
_log.Error(message);
return message;
} catch (OperationCanceledException e) {
const string message = "Generating the Bear link was canceled >_>";
Plugin.Log.Warning(e, message);
_log.Warning(e, message);
return message;
} catch (HttpRequestException e) {
Plugin.Log.Error(e, "Posting the train to Bear failed.");
_log.Error(e, "Posting the train to Bear failed.");
return "Something failed when communicating with Bear :T";
} catch (Exception e) {
const string message = "An unknown error happened while generating the Bear link D:";
Plugin.Log.Error(e, message);
_log.Error(e, message);
return message;
}
}
Expand Down
43 changes: 22 additions & 21 deletions ScoutHelper/Managers/HuntHelperManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;

namespace ScoutHelper.Managers;

public class HuntHelperManager : IDisposable {

private const uint SupportedVersion = 1;

private readonly IPluginLog _log;
private readonly ICallGateSubscriber<uint> _cgGetVersion;
private readonly ICallGateSubscriber<uint, bool> _cgEnable;
private readonly ICallGateSubscriber<bool> _cgDisable;
private readonly ICallGateSubscriber<List<TrainMob>> _cgGetTrainList;

public bool Available { get; private set; } = false;

public HuntHelperManager() {
_cgGetVersion = Plugin.PluginInterface.GetIpcSubscriber<uint>("HH.GetVersion");
_cgEnable = Plugin.PluginInterface.GetIpcSubscriber<uint, bool>("HH.Enable");
_cgDisable = Plugin.PluginInterface.GetIpcSubscriber<bool>("HH.Disable");
_cgGetTrainList = Plugin.PluginInterface.GetIpcSubscriber<List<TrainMob>>("HH.GetTrainList");
public HuntHelperManager(DalamudPluginInterface pluginInterface, IPluginLog log) {
_log = log;

_cgGetVersion = pluginInterface.GetIpcSubscriber<uint>("HH.GetVersion");
_cgEnable = pluginInterface.GetIpcSubscriber<uint, bool>("HH.Enable");
_cgDisable = pluginInterface.GetIpcSubscriber<bool>("HH.Disable");
_cgGetTrainList = pluginInterface.GetIpcSubscriber<List<TrainMob>>("HH.GetTrainList");

CheckVersion();
_cgEnable.Subscribe(OnEnable);
Expand All @@ -40,49 +44,46 @@ private void OnEnable(uint version) {
}

private void OnDisable() {
Plugin.Log.Info("Hunt Helper IPC has been disabled. Disabling support.");
_log.Info("Hunt Helper IPC has been disabled. Disabling support.");
Available = false;
}

private void CheckVersion(uint? version = null) {
try {
version ??= _cgGetVersion.InvokeFunc();
if (version == SupportedVersion) {
Plugin.Log.Info("Hunt Helper IPC version {0} detected. Enabling support.", version);
_log.Info("Hunt Helper IPC version {0} detected. Enabling support.", version);
Available = true;
}
else {
Plugin.Log.Warning(
} else {
_log.Warning(
"Hunt Helper IPC version {0} required, but version {1} detected. Disabling support.",
SupportedVersion,
version
);
Available = false;
}
}
catch (IpcNotReadyError) {
Plugin.Log.Info("Hunt Helper is not yet available. Disabling support until it is.");
} catch (IpcNotReadyError) {
_log.Info("Hunt Helper is not yet available. Disabling support until it is.");
Available = false;
}
}

public Result<List<TrainMob>, string> GetTrainList() {

if (!Available) {
return "Hunt Helper is not currently available ;-;";
}

try {
return _cgGetTrainList.InvokeFunc();
}
catch (IpcNotReadyError) {
Plugin.Log.Warning("Hunt Helper appears to have disappeared ;-;. Can't get the train data ;-;. Disabling support until it comes back.");
} catch (IpcNotReadyError) {
_log.Warning(
"Hunt Helper appears to have disappeared ;-;. Can't get the train data ;-;. Disabling support until it comes back."
);
Available = false;
return "Hunt Helper has disappeared from my sight ;-;";
}
catch (IpcError e) {
} catch (IpcError e) {
const string message = "Hmm...something unexpected happened while retrieving train data from Hunt Helper :T";
Plugin.Log.Error(e, message);
_log.Error(e, message);
return message;
}
}
Expand Down
137 changes: 72 additions & 65 deletions ScoutHelper/Plugin.cs
Original file line number Diff line number Diff line change
@@ -1,101 +1,108 @@
using Dalamud.Game.Command;
using System;
using System.Collections.Generic;
using System.Globalization;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using ScoutHelper.Config;
using ScoutHelper.Localization;
using ScoutHelper.Managers;
using ScoutHelper.Windows;
using System;
using System.Collections.Generic;
using System.Globalization;

namespace ScoutHelper;

// ReSharper disable once ClassNeverInstantiated.Global
public sealed class Plugin : IDalamudPlugin {

public const string Name = Constants.PluginName;

private static readonly List<string> CommandNames = new List<string>() {"/scouth", "/sch"};

public static Configuration Conf { get; private set; } = null!;

[RequiredVersion("1.0"), PluginService]
public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[RequiredVersion("1.0"), PluginService]
public static IPluginLog Log { get; private set; } = null!;
[RequiredVersion("1.0"), PluginService]
public static IChatGui ChatGui { get; private set; } = null!;
[RequiredVersion("1.0"), PluginService]
public static ICommandManager CommandManager { get; private set; } = null!;
[RequiredVersion("1.0"), PluginService]
public static IClientState ClientState { get; private set; } = null!;

private WindowSystem WindowSystem { get; } = new WindowSystem(Constants.PluginNamespace);
private HuntHelperManager HuntHelperManager { get; init; }
private BearManager BearManager { get; init; }

private ConfigWindow ConfigWindow { get; init; }
private MainWindow MainWindow { get; init; }

public Plugin() {
Conf = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
Conf.Initialize(PluginInterface);

HuntHelperManager = new HuntHelperManager();
BearManager = new BearManager(Utils.PluginFilePath(@"Data\Bear.json"));

ConfigWindow = new ConfigWindow();
MainWindow = new MainWindow(HuntHelperManager, BearManager, ConfigWindow);

PluginInterface.LanguageChanged += OnLanguageChanged;
OnLanguageChanged(PluginInterface.UiLanguage);

WindowSystem.AddWindow(ConfigWindow);
WindowSystem.AddWindow(MainWindow);

CommandNames.ForEach(commandName =>
CommandManager.AddHandler(commandName, new CommandInfo(OnCommand) {HelpMessage = "Opens the main window."})
private static readonly List<string> CommandNames = new() { "/scouth", "/sch" };

private readonly IPluginLog _log;

private readonly WindowSystem _windowSystem = new WindowSystem(Constants.PluginNamespace);
private readonly ConfigWindow _configWindow;
private readonly MainWindow _mainWindow;
private readonly Action _dispose;

public Plugin(
[RequiredVersion("1.0")] DalamudPluginInterface pluginInterface,
[RequiredVersion("1.0")] IPluginLog log,
[RequiredVersion("1.0")] IChatGui chatGui,
[RequiredVersion("1.0")] ICommandManager commandManager,
[RequiredVersion("1.0")] IClientState clientState
) {
_log = log;

var conf = pluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
conf.Initialize(pluginInterface);

var serviceProvider = new ServiceCollection()
.AddSingleton(pluginInterface)
.AddSingleton(_log)
.AddSingleton(chatGui)
.AddSingleton(commandManager)
.AddSingleton(clientState)
.AddSingleton(conf)
.AddSingleton(new ScoutHelperOptions(pluginInterface.PluginFilePath(Constants.BearDataFile)))
.AddSingleton<ConfigWindow>()
.AddSingleton<MainWindow>()
.AddSingleton<BearManager>()
.AddSingleton<HuntHelperManager>()
.BuildServiceProvider();

pluginInterface.LanguageChanged += OnLanguageChanged;
OnLanguageChanged(pluginInterface.UiLanguage);

_configWindow = serviceProvider.GetRequiredService<ConfigWindow>();
_mainWindow = serviceProvider.GetRequiredService<MainWindow>();
_windowSystem.AddWindow(_configWindow);
_windowSystem.AddWindow(_mainWindow);

CommandNames.ForEach(
commandName =>
commandManager.AddHandler(commandName, new CommandInfo(OnCommand) { HelpMessage = "Opens the main window." })
);

PluginInterface.UiBuilder.Draw += DrawUi;
PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUi;
}
pluginInterface.UiBuilder.Draw += DrawUi;
pluginInterface.UiBuilder.OpenConfigUi += DrawConfigUi;

public void Dispose() {
PluginInterface.LanguageChanged -= OnLanguageChanged;
CommandNames.ForEach(commandName => CommandManager.RemoveHandler(commandName));
// create the dispose action here, so fields don't need to be made just for disposal
_dispose = () => {
pluginInterface.LanguageChanged -= OnLanguageChanged;
CommandNames.ForEach(commandName => commandManager.RemoveHandler(commandName));
WindowSystem.RemoveAllWindows();
_windowSystem.RemoveAllWindows();
ConfigWindow.Dispose();
MainWindow.Dispose();
conf.Save();
HuntHelperManager.Dispose();

Conf.Save();
serviceProvider.Dispose();
};
}

private static void OnLanguageChanged(string languageCode) {
public void Dispose() => _dispose.Invoke();

private void OnLanguageChanged(string languageCode) {
try {
Log.Information($"Loading localization for {languageCode}");
_log.Information($"Loading localization for {languageCode}");
Strings.Culture = new CultureInfo(languageCode);
}
catch (Exception e) {
Log.Error(e, "Unable to load localization for language code: {0}", languageCode);
} catch (Exception e) {
_log.Error(e, "Unable to load localization for language code: {0}", languageCode);
}
}

private void OnCommand(string command, string args) {
MainWindow.IsOpen = true;
_mainWindow.IsOpen = true;
}

private void DrawUi() {
WindowSystem.Draw();
_windowSystem.Draw();
}

private void DrawConfigUi() {
ConfigWindow.IsOpen = true;
_configWindow.IsOpen = true;
}
}
Loading

0 comments on commit 223ac49

Please sign in to comment.