diff --git a/Dalamud.DrunkenToad/Helpers/PluginInstanceLock.cs b/Dalamud.DrunkenToad/Helpers/PluginInstanceLock.cs
new file mode 100644
index 0000000..14011aa
--- /dev/null
+++ b/Dalamud.DrunkenToad/Helpers/PluginInstanceLock.cs
@@ -0,0 +1,102 @@
+namespace Dalamud.DrunkenToad.Helpers;
+
+using System;
+using System.IO;
+using Core;
+
+///
+/// Provides functionality to acquire and release a lock file, allowing features to be restricted to a single instance of the plugin.
+///
+public static class PluginInstanceLock
+{
+ private static FileStream? lockFile;
+ private static string? lockFilePath;
+ private static bool isInitialized;
+
+ ///
+ /// Acquires a lock to prevent multiple instances of the plugin from running.
+ ///
+ /// True if the lock was acquired successfully; otherwise, false.
+ public static bool AcquireLock()
+ {
+ Initialize();
+ if (TryDeleteExistingLockFile())
+ {
+ return TryCreateAndLockFile();
+ }
+
+ DalamudContext.PluginLog.Warning("Failed to delete existing lock file. Another instance might be running.");
+ return false;
+ }
+
+ ///
+ /// Releases the lock.
+ ///
+ public static void ReleaseLock() => UnlockAndDisposeFile();
+
+ private static void Initialize()
+ {
+ if (isInitialized)
+ {
+ return;
+ }
+
+ lockFilePath = Path.Combine(DalamudContext.PluginInterface.GetPluginConfigDirectory(), "lockfile");
+ isInitialized = true;
+ }
+
+ private static bool TryDeleteExistingLockFile()
+ {
+ if (!File.Exists(lockFilePath))
+ {
+ return true;
+ }
+
+ try
+ {
+ File.Delete(lockFilePath);
+ DalamudContext.PluginLog.Debug("Existing lock file deleted.");
+ return true;
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+ }
+
+ private static bool TryCreateAndLockFile()
+ {
+ try
+ {
+ lockFile = new FileStream(lockFilePath!, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
+ lockFile.Lock(0, 0);
+ DalamudContext.PluginLog.Debug("Instance is running. Lock acquired.");
+ return true;
+ }
+ catch (IOException)
+ {
+ DalamudContext.PluginLog.Warning("Another instance is already running.");
+ return false;
+ }
+ }
+
+ private static void UnlockAndDisposeFile()
+ {
+ try
+ {
+ if (lockFile == null)
+ {
+ return;
+ }
+
+ lockFile.Unlock(0, 0);
+ lockFile.Close();
+ lockFile.Dispose();
+ DalamudContext.PluginLog.Debug("Lock released and lock file deleted.");
+ }
+ catch (Exception ex)
+ {
+ DalamudContext.PluginLog.Warning($"Error releasing lock file: {ex.Message}");
+ }
+ }
+}