From 647193f9335e06dae1c24f71bd4a8478a8b188fd Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Thu, 30 Aug 2018 10:26:27 -0600 Subject: [PATCH] Changes for issues #148 and#149 --- GBM/Classes/clsGame.vb | 5 +- GBM/Forms/frmMain.vb | 19 +++++- GBM/Managers/mgrPath.vb | 101 ++++++++++++++++++++++++++++ GBM/Managers/mgrProcessDetection.vb | 13 ++-- 4 files changed, 131 insertions(+), 7 deletions(-) diff --git a/GBM/Classes/clsGame.vb b/GBM/Classes/clsGame.vb index 1ee3906..a4a0fbd 100644 --- a/GBM/Classes/clsGame.vb +++ b/GBM/Classes/clsGame.vb @@ -257,7 +257,10 @@ Public Class clsGame End Set End Property - ReadOnly Property TruePath As String + Property TruePath As String + Set(value As String) + sPath = value + End Set Get Return sPath End Get diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index eb4c039..8ce92fd 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -1894,11 +1894,12 @@ Public Class frmMain Private Sub ScanTimerEventProcessor(myObject As Object, ByVal myEventArgs As EventArgs) Handles tmScanTimer.Tick Dim bNeedsPath As Boolean = False + Dim bWineProcess As Boolean = False Dim bContinue As Boolean = True Dim iErrorCode As Integer = 0 Dim sErrorMessage As String = String.Empty - If oProcess.SearchRunningProcesses(hshScanList, bNeedsPath, iErrorCode, bProcessDebugMode) Then + If oProcess.SearchRunningProcesses(hshScanList, bNeedsPath, bWineProcess, iErrorCode, bProcessDebugMode) Then PauseScan(True) If bNeedsPath Then @@ -1928,6 +1929,22 @@ Public Class frmMain End If End If + If bWineProcess Then + 'Attempt a path conversion if the game configuration is using an absolute windows path + If oProcess.GameInfo.AbsolutePath And oProcess.GameInfo.TruePath.Contains("\") Then + Dim sWinePrefix As String = mgrPath.GetWinePrefix(oProcess.FoundProcess) + Dim sWineSavePath As String + If Not sWinePrefix = String.Empty Then + UpdateLog(oProcess.GameInfo.Name & " Wine Prefix: " & sWinePrefix, False) + sWineSavePath = mgrPath.GetWineSavePath(sWinePrefix, oProcess.GameInfo.TruePath) + If Not sWineSavePath = oProcess.GameInfo.TruePath Then + oProcess.GameInfo.TruePath = sWineSavePath + UpdateLog(oProcess.GameInfo.Name & " Converted Save Path: " & sWineSavePath, False) + End If + End If + End If + End If + If bContinue = True Then CheckForSavedDuplicate() If oProcess.Duplicate Then diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 340ab22..29d8fb5 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -202,6 +202,107 @@ Public Class mgrPath Return sResult End Function + Private Shared Function BuildWinePath(ByVal sPath As String, ByVal sWinePrefix As String) As String + Dim sRealPath As String + Dim cDriveLetter As Char + Dim sWineDrive As String + + Try + 'Grab Path + sRealPath = sPath.Split("=")(1) + + 'Remove Quotes + sRealPath = sRealPath.TrimStart("""") + sRealPath = sRealPath.TrimEnd("""") + + 'Flip Seperators + sRealPath = sRealPath.Replace("\\", "/") + + 'Change Wine Drive + cDriveLetter = sRealPath.Chars(sRealPath.IndexOf(":") - 1) + sWineDrive = "drive_" & cDriveLetter + sRealPath = sRealPath.Replace(cDriveLetter & ":", sWineDrive.ToLower) + + Return sWinePrefix & Path.DirectorySeparatorChar & sRealPath + Catch ex As Exception + MsgBox(ex.Message) + Return String.Empty + End Try + End Function + + Public Shared Function GetWineSavePath(ByVal sPrefix As String, ByVal sPath As String) As String + Dim sRegistry As String + Dim sWinePath As String + Dim sReplace As String + Dim oParse As Regex + Dim oMatch As Match + + Try + If sPath.Contains("*appdatalocal*") Then + sReplace = "*appdatalocal*" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""Local AppData""="".+?(?=\n)") + ElseIf sPath.Contains("*appdataroaming*") Then + sReplace = "*appdataroaming*" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""AppData""="".+?(?=\n)") + ElseIf sPath.Contains("*mydocs*") Then + sReplace = "*mydocs*" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""Personal""="".+?(?=\n)") + ElseIf sPath.Contains("*publicdocs*") Then + sReplace = "*publicdocs*" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "system.reg") + oParse = New Regex("""Common Documents""="".+?(?=\n)") + ElseIf sPath.Contains("*currentuser*") Then + sReplace = "*currentuser*" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""Personal""="".+?(?=\\\\My Documents)") + Else + Return sPath + End If + + If oParse.IsMatch(sRegistry) Then + oMatch = oParse.Match(sRegistry) + sWinePath = BuildWinePath(oMatch.Value, sPrefix) + sPath = sPath.Replace("\", Path.DirectorySeparatorChar) + Return sPath.Replace(sReplace, sWinePath) + End If + + Return sPath + Catch ex As Exception + MsgBox(ex.Message) + Return sPath + End Try + End Function + + Public Shared Function GetWinePrefix(ByVal prs As Process) As String + Dim prps As Process + Dim sPsinfo As String + Dim oParse As New Regex("WINEPREFIX=.+?(?= )") + Dim oMatch As Match + + Try + prps = New Process + prps.StartInfo.FileName = "/bin/ps" + prps.StartInfo.Arguments = "e " & prs.Id.ToString + prps.StartInfo.UseShellExecute = False + prps.StartInfo.RedirectStandardOutput = True + prps.StartInfo.CreateNoWindow = True + prps.Start() + sPsinfo = prps.StandardOutput.ReadToEnd() + If oParse.IsMatch(sPsinfo) Then + oMatch = oParse.Match(sPsinfo) + Return oMatch.Value.Trim("/").Split("=")(1) + Else + Return String.Empty + End If + Catch ex As Exception + MsgBox(ex.Message) + Return String.Empty + End Try + End Function + Public Shared Function CheckSpecialPaths() As Boolean Dim hshEnvs As New Hashtable Dim bNoError As Boolean = True diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index cfc4216..44dd103 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -202,11 +202,10 @@ Public Class mgrProcessDetection Return False End Function - Public Function SearchRunningProcesses(ByVal hshScanList As Hashtable, ByRef bNeedsPath As Boolean, ByRef iErrorCode As Integer, ByVal bDebugMode As Boolean) As Boolean + Public Function SearchRunningProcesses(ByVal hshScanList As Hashtable, ByRef bNeedsPath As Boolean, ByRef bWineProcess As Boolean, ByRef iErrorCode As Integer, ByVal bDebugMode As Boolean) As Boolean Dim prsList() As Process = Process.GetProcesses Dim sProcessCheck As String = String.Empty Dim sProcessList As String = String.Empty - Dim bWineProcess As Boolean = False Dim bPass As Boolean For Each prsCurrent As Process In prsList @@ -219,9 +218,13 @@ Public Class mgrProcessDetection 'Unix Handler 'We need some special handling for Wine processes If mgrCommon.IsUnix And (sProcessCheck.ToLower = "wine-preloader" Or sProcessCheck.ToLower = "wine64-preloader") Then - Dim sWinePath As String() - 'We can't use Path.GetFileName here, Wine uses the Windows seperator in arguments and Mono expects a different one in Unix. - sWinePath = GetUnixProcessArguments(prsCurrent)(0).Split("\") + Dim sWinePath As String() = GetUnixProcessArguments(prsCurrent) + 'The wine-preloader parameters can refer to a path on the host system or a windows based path within in the prefix, we need to handle both. + If sWinePath(0).Contains("\") Then + sWinePath = GetUnixProcessArguments(prsCurrent)(0).Split("\") + ElseIf sWinePath(0).Contains("/") Then + sWinePath = GetUnixProcessArguments(prsCurrent)(0).Split("/") + End If sProcessCheck = sWinePath(sWinePath.Length - 1).Replace(".exe", "") bWineProcess = True Else