Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions MMLaunch/MainWindow.axaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -377,16 +377,25 @@ type MainViewModel() as self =
| Some p -> setter p

let mutable warnedNoRoot = false
let mutable warnedNoMMDLL = false

let mutable rootInitted = false
member x.PeriodicUpdate() =
try
let currentRoot = ProcessUtil.getMMRoot ()
let regRoot = RegConfig.getMMRoot ()
if currentRoot <> regRoot then RegConfig.setMMRoot currentRoot |> ignore
with ex ->
if not warnedNoRoot then
warnedNoRoot <- true
ViewModelUtil.pushDialog (sprintf "Unable to determine root dir: %A" ex)
()
if not rootInitted then
rootInitted <- true
try
let currentRoot = ProcessUtil.getMMRoot ()
let regRoot = RegConfig.getMMRoot ()
if currentRoot <> regRoot then RegConfig.setMMRoot currentRoot |> ignore
if not warnedNoMMDLL && not (ProcessUtil.hasManagedDll currentRoot) then
warnedNoMMDLL <- true
ViewModelUtil.pushDialog
(sprintf "Warning, current root %A has no managed DLL, the native code will not be able to load from it. Consider using regedit to clear the root in the registry" currentRoot)
with ex ->
if not warnedNoRoot then
warnedNoRoot <- true
ViewModelUtil.pushDialog (sprintf "Unable to determine root dir: %A" ex)
()

x.UpdateLoaderState
<| match loaderState with
Expand Down
30 changes: 25 additions & 5 deletions MMLaunch/ProcessUtil.fs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ module ProcessUtil =

let mutable lastRoot:string option = None

// A candidate directory is only a real MM root if the native loader could
// actually load MMManaged.dll from it. This mirrors get_managed_dll_path in
// the native util crate, which searches these same subdirs. Requiring the specific
// DLL to exist reduces the risk of false positives.
let private managedDllSubdirs = [""; "Bin"; "Release"; "Debug"]
let hasManagedDll (dir:string) =
let dir = if String.IsNullOrEmpty dir then "." else dir
managedDllSubdirs
|> List.exists (fun sub -> File.Exists(Path.Combine(dir, sub, "MMManaged.dll")))

let getMMRoot() =
// MMRoot by convention its where one of the files/directories below lives.
// This value is also stored in the registry (PeriodicUpdate puts it there)
Expand All @@ -57,32 +67,42 @@ module ProcessUtil =
"Logs"
"Bin"]



// MMDotNet.sln uniquely identifies a source checkout (ModelMod-specific, so no
// risk of matching a system directory), so trust it directly. Every other
// marker must be backed by a loadable MMManaged.dll.
let isValidCandidate (markerPath:string) =
markerPath.EndsWith("MMDotNet.sln")
|| hasManagedDll (Path.GetDirectoryName(markerPath))

let root =
rootSearchPath
|> List.tryPick (fun rootpath ->
rootFiles
|> List.map (fun filepath -> Path.Combine(rootpath, filepath))
|> List.tryPick (fun filepath ->
//printfn "try %A" (Path.GetFullPath(filepath))
if (Directory.Exists(filepath) || File.Exists(filepath)) then Some(filepath) else None)
if (Directory.Exists(filepath) || File.Exists(filepath)) && isValidCandidate filepath then Some(filepath) else None)
)

let fullRoot =
match root with
| None ->
let regRoot = RegConfig.getMMRoot ()
if Directory.Exists(regRoot)
then regRoot
then
regRoot
else
failwithf "Unable to find MM Root in filesystem from working dir %A, and reg root not set in register or does not exist: %A"
failwithf "Unable to find MM Root in filesystem from working dir %A, and reg root (%A) not set in registry or does not exist. Consider restarting this program in ModelMod root dir."
(System.Environment.CurrentDirectory) regRoot

//failwithf "Unable to find MM root from working dir %A" (System.Environment.CurrentDirectory)
| Some(dir) -> Path.GetFullPath(Path.GetDirectoryName(dir))

if lastRoot <> Some(fullRoot) then
if lastRoot <> Some(fullRoot) then
lastRoot <- Some(fullRoot)
printfn "MM root changed: %A" root
printfn "MM root changed: %A" fullRoot
fullRoot

/// Loader isn't used anymore so this is just a placeholder until I remove the related code.
Expand Down
Loading