diff --git a/Robust.Client.WebView/Cef/WebViewManagerCef.Lock.cs b/Robust.Client.WebView/Cef/WebViewManagerCef.Lock.cs new file mode 100644 index 000000000..0ba757775 --- /dev/null +++ b/Robust.Client.WebView/Cef/WebViewManagerCef.Lock.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using Robust.Client.Utility; + +namespace Robust.Client.WebView.Cef; + +internal sealed partial class WebViewManagerCef +{ + private const string BaseCacheName = "cef_cache"; + private const string LockFileName = "robust.lock"; + private FileStream? _lockFileStream; + private const int MaxAttempts = 15; // This probably shouldn't be a cvar because the only reason you'd need it change for legit just botting the game. + + private string FindAndLockCacheDirectory() + { + var rootDir = Path.Combine(UserDataDir.GetRootUserDataDir(_gameController), BaseCacheName); + + for (var i = 0; i < MaxAttempts; i++) + { + var cacheDirPath = Path.Combine(rootDir, i.ToString()); + + if (TryLockCacheDir(i, cacheDirPath)) + return cacheDirPath; + } + + throw new Exception("Unable to locate available CEF cache directory!"); + } + + private bool TryLockCacheDir(int attempt, string path) + { + _sawmill.Verbose($"Trying to lock cache directory {attempt}"); + + // Does not fail if directory already exists. + Directory.CreateDirectory(path); + + var lockFilePath = Path.Combine(path, LockFileName); + + try + { + var file = File.Open(lockFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); + _lockFileStream = file; + _sawmill.Debug($"Successfully locked CEF cache directory {attempt}"); + return true; + } + catch (IOException ex) + { + _sawmill.Error($"Failed to lock cache directory {attempt}: {ex}"); + return false; + } + } +} diff --git a/Robust.Client.WebView/Cef/WebViewManagerCef.cs b/Robust.Client.WebView/Cef/WebViewManagerCef.cs index 98bb31982..3edb3ee73 100644 --- a/Robust.Client.WebView/Cef/WebViewManagerCef.cs +++ b/Robust.Client.WebView/Cef/WebViewManagerCef.cs @@ -61,12 +61,9 @@ namespace Robust.Client.WebView.Cef if (cefResourcesPath == null) throw new InvalidOperationException("Unable to locate cef_resources directory!"); - var cachePath = ""; - if (_resourceManager.UserData is WritableDirProvider userData) - { - var rootDir = UserDataDir.GetRootUserDataDir(_gameController); - cachePath = Path.Combine(rootDir, "cef_cache", "0"); - } + var remoteDebugPort = _cfg.GetCVar(WCVars.WebRemoteDebugPort); + + var cachePath = FindAndLockCacheDirectory(); var settings = new CefSettings() { @@ -76,7 +73,7 @@ namespace Robust.Client.WebView.Cef BrowserSubprocessPath = subProcessPath, LocalesDirPath = Path.Combine(cefResourcesPath, "locales"), ResourcesDirPath = cefResourcesPath, - RemoteDebuggingPort = 9222, + RemoteDebuggingPort = remoteDebugPort, CookieableSchemesList = "usr,res", CachePath = cachePath, }; diff --git a/Robust.Client.WebView/WCVars.cs b/Robust.Client.WebView/WCVars.cs index f314727a5..b694fde6d 100644 --- a/Robust.Client.WebView/WCVars.cs +++ b/Robust.Client.WebView/WCVars.cs @@ -26,4 +26,16 @@ public static class WCVars /// public static readonly CVarDef WebHeadless = CVarDef.Create("web.headless", false, CVar.CLIENTONLY); + +#if TOOLS + private const int DefaultRemoteDebugPort = 9222; +#else + private const int DefaultRemoteDebugPort = 0; +#endif + + /// + /// If not 0, the port number used for Chromium's remote debugging. + /// + public static readonly CVarDef WebRemoteDebugPort = + CVarDef.Create("web.remote_debug_port", DefaultRemoteDebugPort, CVar.CLIENTONLY); }