diff --git a/project/Aki.Core/Utils/ValidationUtil.cs b/project/Aki.Core/Utils/ValidationUtil.cs index ab0b24b..b51dfee 100644 --- a/project/Aki.Core/Utils/ValidationUtil.cs +++ b/project/Aki.Core/Utils/ValidationUtil.cs @@ -16,7 +16,7 @@ namespace Aki.Core.Utils var v1 = Registry.LocalMachine.OpenSubKey(c0, false).GetValue("InstallLocation"); var v2 = (v1 != null) ? v1.ToString() : string.Empty; var v3 = new DirectoryInfo(v2); - + var v4 = new FileSystemInfo[] { v3, @@ -55,4 +55,4 @@ namespace Aki.Core.Utils return File.Exists(a) ? new FileInfo(a) : null; } } -} +} \ No newline at end of file diff --git a/project/Aki.PrePatch/AkiBotsPrePatcher.cs b/project/Aki.PrePatch/AkiBotsPrePatcher.cs index ce91eee..29ed39e 100644 --- a/project/Aki.PrePatch/AkiBotsPrePatcher.cs +++ b/project/Aki.PrePatch/AkiBotsPrePatcher.cs @@ -1,4 +1,8 @@ +using System; using System.Collections.Generic; +using System.IO; +using System.Linq; +using BepInEx.Logging; using Mono.Cecil; namespace Aki.PrePatch @@ -10,8 +14,22 @@ namespace Aki.PrePatch public static int sptUsecValue = 49; public static int sptBearValue = 50; + private static string _sptPluginFolder = "plugins/spt"; + public static void Patch(ref AssemblyDefinition assembly) { + // Make sure the user hasn't deleted the SPT plugins folder + string assemblyFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + string sptPluginPath = Path.GetFullPath(Path.Combine(assemblyFolder, "..", _sptPluginFolder)); + if (!ValidateSpt(sptPluginPath)) + { + string message = $"'{sptPluginPath}' or required plugin files not found.\n\n" + + "Please re-install SPT. Exiting."; + MessageBoxHelper.Show(message, "[SPT-AKI] Missing Core Files", MessageBoxHelper.MessageBoxType.OK); + Environment.Exit(0); + return; + } + var botEnums = assembly.MainModule.GetType("EFT.WildSpawnType"); var sptUsec = new FieldDefinition("sptUsec", @@ -27,5 +45,31 @@ namespace Aki.PrePatch botEnums.Fields.Add(sptUsec); botEnums.Fields.Add(sptBear); } + + private static bool ValidateSpt(string sptPluginPath) + { + ManualLogSource logger = Logger.CreateLogSource(nameof(AkiBotsPrePatcher)); + + // Validate that the SPT plugin path exists + if (!Directory.Exists(sptPluginPath)) + { + logger.LogError($"'{sptPluginPath}' directory not found"); + return false; + } + + // Validate that the folder exists, and contains our plugins + string[] sptPlugins = new string[] { "aki-core.dll", "aki-custom.dll", "aki-singleplayer.dll" }; + string[] foundPlugins = Directory.GetFiles(sptPluginPath).Select(x => Path.GetFileName(x)).ToArray(); + + foreach (string plugin in sptPlugins) + { + if (!foundPlugins.Contains(plugin)) + { + return false; + } + } + + return true; + } } } \ No newline at end of file diff --git a/project/Aki.PrePatch/MessageBoxHelper.cs b/project/Aki.PrePatch/MessageBoxHelper.cs new file mode 100644 index 0000000..837880f --- /dev/null +++ b/project/Aki.PrePatch/MessageBoxHelper.cs @@ -0,0 +1,56 @@ +using System; +using System.Runtime.InteropServices; + +namespace Aki.PrePatch +{ + internal class MessageBoxHelper + { + public enum MessageBoxType : uint + { + ABORTRETRYIGNORE = (uint)(0x00000002L | 0x00000010L), + CANCELTRYCONTINUE = (uint)(0x00000006L | 0x00000030L), + HELP = (uint)(0x00004000L | 0x00000040L), + OK = (uint)(0x00000000L | 0x00000040L), + OKCANCEL = (uint)(0x00000001L | 0x00000040L), + RETRYCANCEL = (uint)0x00000005L, + YESNO = (uint)(0x00000004L | 0x00000040L), + YESNOCANCEL = (uint)(0x00000003L | 0x00000040L), + DEFAULT = (uint)(0x00000000L | 0x00000010L) + } + + public enum MessageBoxResult + { + ERROR = -1, + OK = 1, + CANCEL = 2, + ABORT = 3, + RETRY = 4, + IGNORE = 5, + YES = 6, + NO = 7, + TRY_AGAIN = 10 + } + + [DllImport("user32.dll")] + private static extern IntPtr GetActiveWindow(); + [DllImport("user32.dll", SetLastError = true)] + static extern int MessageBox(IntPtr hwnd, String lpText, String lpCaption, uint uType); + + public static IntPtr GetWindowHandle() + { + return GetActiveWindow(); + } + + public static MessageBoxResult Show(string text, string caption, MessageBoxType type = MessageBoxType.DEFAULT) + { + try + { + return (MessageBoxResult)MessageBox(GetWindowHandle(), text, caption, (uint)type); ; + } + catch (Exception) + { + return MessageBoxResult.ERROR; + } + } + } +}