From 647193f9335e06dae1c24f71bd4a8478a8b188fd Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Thu, 30 Aug 2018 10:26:27 -0600 Subject: [PATCH 01/32] 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 From b04c1bc18b794c39727c6b00cecadf15d8969ef2 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Thu, 30 Aug 2018 10:53:29 -0600 Subject: [PATCH 02/32] Added new strings for issue #148 and #149 --- GBM/Forms/frmMain.vb | 4 +-- GBM/Managers/mgrPath.vb | 6 ++-- GBM/My Project/Resources.Designer.vb | 45 ++++++++++++++++++++++++++++ GBM/My Project/Resources.resx | 15 ++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index 8ce92fd..37d3eab 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -1935,11 +1935,11 @@ Public Class frmMain 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) + UpdateLog(mgrCommon.FormatString(frmMain_WinePrefix, New String() {oProcess.GameInfo.Name, 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) + UpdateLog(mgrCommon.FormatString(frmMain_WineSavePath, New String() {oProcess.GameInfo.Name, sWineSavePath}), False) End If End If End If diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 29d8fb5..9cfe373 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -225,7 +225,7 @@ Public Class mgrPath Return sWinePrefix & Path.DirectorySeparatorChar & sRealPath Catch ex As Exception - MsgBox(ex.Message) + mgrCommon.ShowMessage(mgrPath_ErrorBuildingWinePath, ex.Message, MsgBoxStyle.Exclamation) Return String.Empty End Try End Function @@ -271,7 +271,7 @@ Public Class mgrPath Return sPath Catch ex As Exception - MsgBox(ex.Message) + mgrCommon.ShowMessage(mgrPath_ErrorConvertWineSavePath, ex.Message, MsgBoxStyle.Exclamation) Return sPath End Try End Function @@ -298,7 +298,7 @@ Public Class mgrPath Return String.Empty End If Catch ex As Exception - MsgBox(ex.Message) + mgrCommon.ShowMessage(mgrPath_ErrorWinePrefix, ex.Message, MsgBoxStyle.Exclamation) Return String.Empty End Try End Function diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index def094c..504fcd7 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -3876,6 +3876,24 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to [PARAM] Wine Prefix: [PARAM]. + ''' + Friend ReadOnly Property frmMain_WinePrefix() As String + Get + Return ResourceManager.GetString("frmMain_WinePrefix", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to [PARAM] Converted Save Path: [PARAM]. + ''' + Friend ReadOnly Property frmMain_WineSavePath() As String + Get + Return ResourceManager.GetString("frmMain_WineSavePath", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to +. ''' @@ -6087,6 +6105,33 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to An error occured when building a Wine path.[BR][BR][PARAM]. + ''' + Friend ReadOnly Property mgrPath_ErrorBuildingWinePath() As String + Get + Return ResourceManager.GetString("mgrPath_ErrorBuildingWinePath", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to An error occured when converting to a Wine save path.[BR][BR][PARAM]. + ''' + Friend ReadOnly Property mgrPath_ErrorConvertWineSavePath() As String + Get + Return ResourceManager.GetString("mgrPath_ErrorConvertWineSavePath", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to An error occured when determining a Wine prefix.[BR][BR][PARAM]. + ''' + Friend ReadOnly Property mgrPath_ErrorWinePrefix() As String + Get + Return ResourceManager.GetString("mgrPath_ErrorWinePrefix", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to An error occured while determining a required system path. [BR][BR]The environment value for [PARAM] is empty.[BR][BR]The application will now exit.. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 8f16cb6..056b5e8 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2203,4 +2203,19 @@ The backup folder [PARAM] cannot be renamed to [PARAM] because a folder with that name already exists.[BR][BR]Do you want to continue and remove the existing folder? + + [PARAM] Wine Prefix: [PARAM] + + + [PARAM] Converted Save Path: [PARAM] + + + An error occured when building a Wine path.[BR][BR][PARAM] + + + An error occured when converting to a Wine save path.[BR][BR][PARAM] + + + An error occured when determining a Wine prefix.[BR][BR][PARAM] + \ No newline at end of file From 52c9fe506f8ad3eda22330651a04083b63f36d55 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 31 Aug 2018 08:54:54 -0600 Subject: [PATCH 03/32] More detection fixes for issue #149 --- GBM/Managers/mgrProcessDetection.vb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index 44dd103..3a11d11 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -218,14 +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() = 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", "") + Dim sArgs As String() = GetUnixProcessArguments(prsCurrent) + Dim sParameter As String + Dim sWinePath As String() + 'The wine-preloader parameters can refer to a path on the host system, windows based path within in the prefix, or mixed notation. + sParameter = sArgs(0).Replace("\", "/") + sWinePath = sParameter.Split("/") + sProcessCheck = Path.GetFileNameWithoutExtension(sWinePath(sWinePath.Length - 1)) bWineProcess = True Else bWineProcess = False From 3e141cebb5eb3aa7b98e07e711f6a94f3b111430 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 1 Sep 2018 14:40:05 -0600 Subject: [PATCH 04/32] Changes for issue #153 --- GBM/Managers/mgrMonitorList.vb | 2 +- GBM/Managers/mgrProcessDetection.vb | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/GBM/Managers/mgrMonitorList.vb b/GBM/Managers/mgrMonitorList.vb index 8141ab9..0544a00 100644 --- a/GBM/Managers/mgrMonitorList.vb +++ b/GBM/Managers/mgrMonitorList.vb @@ -78,7 +78,7 @@ Public Class mgrMonitorList Dim oCompareGame As clsGame Dim bIsDupe As Boolean - sSQL = "Select * FROM monitorlist ORDER BY Name Asc" + sSQL = "SELECT * FROM monitorlist ORDER BY IsRegEx DESC" oData = oDatabase.ReadParamData(sSQL, New Hashtable) For Each dr As DataRow In oData.Tables(0).Rows diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index 3a11d11..35c6116 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -94,8 +94,14 @@ Public Class mgrProcessDetection For Each o As clsGame In hshScanList.Values sProcess = o.ProcessName.Split(":")(0) - If o.Duplicate = True And (sProcess = oGame.TrueProcess Or Regex.IsMatch(sProcess, oGame.TrueProcess)) Then - oInitialDupes.Add(o.ShallowCopy) + If o.Duplicate And o.IsRegEx Then + If Regex.IsMatch(prsFoundProcess.ProcessName, sProcess) Then + oInitialDupes.Add(o.ShallowCopy) + End If + ElseIf o.Duplicate And Not o.IsRegEx Then + If sProcess = prsFoundProcess.ProcessName Then + oInitialDupes.Add(o.ShallowCopy) + End If End If Next From 63da6eba190d30e867ef1329ae97d0a862ec8844 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Mon, 3 Sep 2018 12:36:25 -0600 Subject: [PATCH 05/32] Detection rewrite for issue #153 - Pass 1 --- GBM/Classes/clsGame.vb | 34 ----- GBM/Forms/frmAdvancedImport.vb | 4 +- GBM/Forms/frmGameManager.vb | 4 +- GBM/Forms/frmMain.vb | 12 +- GBM/Managers/mgrCommon.vb | 2 +- GBM/Managers/mgrMonitorList.vb | 42 +----- GBM/Managers/mgrProcessDetection.vb | 213 +++++++++++++--------------- GBM/Managers/mgrRestore.vb | 2 +- 8 files changed, 110 insertions(+), 203 deletions(-) diff --git a/GBM/Classes/clsGame.vb b/GBM/Classes/clsGame.vb index a4a0fbd..0ea8ec7 100644 --- a/GBM/Classes/clsGame.vb +++ b/GBM/Classes/clsGame.vb @@ -21,7 +21,6 @@ Public Class clsGame Private bMonitorOnly As Boolean = False Private sComments As String = String.Empty Private bIsRegEx As Boolean = False - Private bDuplicate As Boolean = False Private oImportTags As New List(Of Tag) Private bImportUpdate As Boolean = False @@ -46,12 +45,6 @@ Public Class clsGame End Get End Property - ReadOnly Property CompoundKey As String - Get - Return ProcessName & ":" & ID - End Get - End Property - ReadOnly Property CroppedName As String Get If Name.Length > 40 Then @@ -248,15 +241,6 @@ Public Class clsGame End Set End Property - Property Duplicate As Boolean - Get - Return bDuplicate - End Get - Set(value As Boolean) - bDuplicate = value - End Set - End Property - Property TruePath As String Set(value As String) sPath = value @@ -266,12 +250,6 @@ Public Class clsGame End Get End Property - ReadOnly Property TrueProcess As String - Get - Return HandleProcessDuplicates() - End Get - End Property - Property ImportTags As List(Of Tag) Get Return oImportTags @@ -460,18 +438,6 @@ Public Class clsGame Return DirectCast(Me.MemberwiseClone(), clsGame) End Function - Private Function HandleProcessDuplicates() As String - Dim sProcessName As String - - 'Handle Duplicates - sProcessName = Me.ProcessName - If Me.Duplicate Then - sProcessName = Me.ProcessName.Split(":")(0) - End If - - Return sProcessName - End Function - Public Shared Function SetSyncField(ByVal eSyncFields As eOptionalSyncFields, ByVal eSyncField As eOptionalSyncFields) As eOptionalSyncFields Return eSyncFields Or eSyncField End Function diff --git a/GBM/Forms/frmAdvancedImport.vb b/GBM/Forms/frmAdvancedImport.vb index f9202e1..c6a6d35 100644 --- a/GBM/Forms/frmAdvancedImport.vb +++ b/GBM/Forms/frmAdvancedImport.vb @@ -82,7 +82,7 @@ Public Class frmAdvancedImport Next sTags = sTags.TrimEnd(New Char() {",", " "}) - oListViewItem = New ListViewItem(New String() {oApp.Name, oApp.TrueProcess, sTags}) + oListViewItem = New ListViewItem(New String() {oApp.Name, oApp.ProcessName, sTags}) oListViewItem.Tag = oApp.ID If FinalData.ContainsKey(oApp.ID) Then @@ -114,7 +114,7 @@ Public Class frmAdvancedImport If sFilter = String.Empty Then bAddItem = True Else - If oApp.Name.ToLower.Contains(sFilter.ToLower) Or oApp.TrueProcess.ToLower.Contains(sFilter.ToLower) Or sTags.ToLower.Contains(sFilter.ToLower) Then + If oApp.Name.ToLower.Contains(sFilter.ToLower) Or oApp.ProcessName.ToLower.Contains(sFilter.ToLower) Or sTags.ToLower.Contains(sFilter.ToLower) Then bAddItem = True End If End If diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index e1656ae..98ebc8c 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -574,7 +574,7 @@ Public Class frmGameManager If CurrentGame.ProcessPath <> String.Empty Then CurrentBackupItem.RelativeRestorePath = CurrentGame.ProcessPath & Path.DirectorySeparatorChar & CurrentBackupItem.RestorePath Else - sProcess = CurrentGame.TrueProcess + sProcess = CurrentGame.ProcessName If mgrCommon.IsProcessNotSearchable(CurrentGame) Then bNoAuto = True sRestorePath = mgrPath.ProcessPathSearch(CurrentBackupItem.Name, sProcess, mgrCommon.FormatString(frmGameManager_ErrorPathNotSet, CurrentBackupItem.Name), bNoAuto) @@ -864,7 +864,7 @@ Public Class frmGameManager 'Core txtID.Text = oApp.ID txtName.Text = oApp.Name - txtProcess.Text = oApp.TrueProcess + txtProcess.Text = oApp.ProcessName chkRegEx.Checked = oApp.IsRegEx txtParameter.Text = oApp.Parameter txtSavePath.Text = oApp.Path diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index 37d3eab..5fe1357 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -228,7 +228,7 @@ Public Class frmMain If oGame.AbsolutePath = False Then If oGame.ProcessPath = String.Empty Then If mgrCommon.IsProcessNotSearchable(oGame) Then bNoAuto = True - oGame.ProcessPath = mgrPath.ProcessPathSearch(oGame.Name, oGame.TrueProcess, mgrCommon.FormatString(frmMain_ErrorRelativePath, oGame.Name), bNoAuto) + oGame.ProcessPath = mgrPath.ProcessPathSearch(oGame.Name, oGame.ProcessName, mgrCommon.FormatString(frmMain_ErrorRelativePath, oGame.Name), bNoAuto) End If If oGame.ProcessPath <> String.Empty Then @@ -1689,15 +1689,6 @@ Public Class frmMain End Function - Private Sub CheckForSavedDuplicate() - For Each o As clsGame In oProcess.DuplicateList - If o.ProcessPath.ToLower = oProcess.GameInfo.ProcessPath.ToLower Then - oProcess.GameInfo = o - oProcess.Duplicate = False - End If - Next - End Sub - Private Function CheckForSavedPath() As Boolean If oProcess.GameInfo.ProcessPath <> String.Empty Then Return True @@ -1946,7 +1937,6 @@ Public Class frmMain End If If bContinue = True Then - CheckForSavedDuplicate() If oProcess.Duplicate Then UpdateLog(frmMain_MultipleGamesDetected, oSettings.ShowDetectionToolTips) UpdateStatus(frmMain_MultipleGamesDetected) diff --git a/GBM/Managers/mgrCommon.vb b/GBM/Managers/mgrCommon.vb index 07379bc..74a533e 100644 --- a/GBM/Managers/mgrCommon.vb +++ b/GBM/Managers/mgrCommon.vb @@ -225,7 +225,7 @@ Public Class mgrCommon If oGame.ProcessName.ToLower.Contains(s) Then bFound = True Next - If bFound Or oGame.Duplicate = True Then + If bFound Then Return True Else Return False diff --git a/GBM/Managers/mgrMonitorList.vb b/GBM/Managers/mgrMonitorList.vb index 0544a00..28096b3 100644 --- a/GBM/Managers/mgrMonitorList.vb +++ b/GBM/Managers/mgrMonitorList.vb @@ -45,7 +45,7 @@ Public Class mgrMonitorList hshParams.Add("ID", oGame.ID) hshParams.Add("Name", oGame.Name) - hshParams.Add("Process", oGame.TrueProcess) + hshParams.Add("Process", oGame.ProcessName) hshParams.Add("Path", oGame.TruePath) hshParams.Add("AbsolutePath", oGame.AbsolutePath) hshParams.Add("FolderSave", oGame.FolderSave) @@ -75,10 +75,8 @@ Public Class mgrMonitorList Dim hshList As New Hashtable Dim hshDupeList As New Hashtable Dim oGame As clsGame - Dim oCompareGame As clsGame - Dim bIsDupe As Boolean - sSQL = "SELECT * FROM monitorlist ORDER BY IsRegEx DESC" + sSQL = "SELECT * FROM monitorlist ORDER BY Name ASC" oData = oDatabase.ReadParamData(sSQL, New Hashtable) For Each dr As DataRow In oData.Tables(0).Rows @@ -87,39 +85,7 @@ Public Class mgrMonitorList Case eListTypes.FullList hshList.Add(oGame.ID, oGame) Case eListTypes.ScanList - For Each de As DictionaryEntry In hshList - bIsDupe = False - oCompareGame = DirectCast(de.Value, clsGame) - - If oCompareGame.IsRegEx Then - If oGame.IsRegEx Then - If oCompareGame.ProcessName = oGame.ProcessName Then - bIsDupe = True - End If - Else - If Regex.IsMatch(oGame.ProcessName, oCompareGame.ProcessName) Then - bIsDupe = True - End If - End If - Else - If oGame.IsRegEx Then - If Regex.IsMatch(oCompareGame.ProcessName, oGame.ProcessName) Then - bIsDupe = True - End If - Else - If oGame.ProcessName = oCompareGame.ProcessName Then - bIsDupe = True - End If - End If - End If - - If bIsDupe Then - DirectCast(hshList.Item(oCompareGame.ProcessName), clsGame).Duplicate = True - oGame.ProcessName = oGame.CompoundKey - oGame.Duplicate = True - End If - Next - If oGame.Enabled Then hshList.Add(oGame.ProcessName, oGame) + If oGame.Enabled Then hshList.Add(oGame.ID, oGame) End Select Next @@ -413,7 +379,7 @@ Public Class mgrMonitorList 'Core Parameters hshParams.Add("ID", oGame.ID) hshParams.Add("Name", oGame.Name) - hshParams.Add("Process", oGame.TrueProcess) + hshParams.Add("Process", oGame.ProcessName) hshParams.Add("Path", oGame.TruePath) hshParams.Add("AbsolutePath", oGame.AbsolutePath) hshParams.Add("FolderSave", oGame.FolderSave) diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index 35c6116..d04b4b0 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -10,8 +10,6 @@ Public Class mgrProcessDetection Private oGame As clsGame Private oDuplicateGames As New ArrayList Private bDuplicates As Boolean - Private bVerified As Boolean = False - Private sFullCommand As String = String.Empty Property FoundProcess As Process Get @@ -73,91 +71,32 @@ Public Class mgrProcessDetection End Set End Property - Property FullCommand As String - Get - Return sFullCommand - End Get - Set(value As String) - sFullCommand = value - End Set - End Property - - Private Function HandleDuplicates(hshScanList As Hashtable) As Boolean - Dim sProcess As String - Dim sParameter As String = String.Empty - Dim bParameter As Boolean = False - Dim oInitialDupes As New ArrayList - - bDuplicates = True - oDuplicateGames.Clear() - - - For Each o As clsGame In hshScanList.Values - sProcess = o.ProcessName.Split(":")(0) - If o.Duplicate And o.IsRegEx Then - If Regex.IsMatch(prsFoundProcess.ProcessName, sProcess) Then - oInitialDupes.Add(o.ShallowCopy) - End If - ElseIf o.Duplicate And Not o.IsRegEx Then - If sProcess = prsFoundProcess.ProcessName Then - oInitialDupes.Add(o.ShallowCopy) - End If - End If - Next - - For Each o As clsGame In oInitialDupes - If (o.Parameter <> String.Empty And FullCommand.Contains(o.Parameter)) Then - sParameter = o.Parameter - bParameter = True - Exit For - End If - Next - - If bParameter Then - For Each o As clsGame In oInitialDupes - If (o.Parameter = sParameter) Then - oDuplicateGames.Add(o.ShallowCopy) - End If - Next - Else - For Each o As clsGame In oInitialDupes - If (o.Parameter = String.Empty) Then - oDuplicateGames.Add(o.ShallowCopy) - End If - Next - End If - - If oDuplicateGames.Count = 1 Then - oGame = DirectCast(oDuplicateGames(0), clsGame).ShallowCopy - Return True - End If - - Return False - End Function - 'This function will only work correctly on Windows - Private Sub GetWindowsCommand(ByVal prs As Process) - FullCommand = String.Empty + Private Function GetWindowsCommand(ByVal prs As Process) As String + Dim sFullCommand As String = String.Empty Try Using searcher As New ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + prs.Id.ToString) For Each o As ManagementObject In searcher.Get() - FullCommand &= o("CommandLine") & " " + sFullCommand &= o("CommandLine") & " " Next End Using - Catch ex As Exception + Catch 'Do Nothing End Try - End Sub + Return sFullCommand + End Function 'This function will only work correctly on Unix - Private Sub GetUnixCommand(ByVal prs As Process) - FullCommand = String.Empty + Private Function GetUnixCommand(ByVal prs As Process) As String + Dim sFullCommand As String = String.Empty Try - FullCommand = File.ReadAllText("/proc/" & prs.Id.ToString() & "/cmdline").Replace(vbNullChar, " ") + sFullCommand = File.ReadAllText("/proc/" & prs.Id.ToString() & "/cmdline").Replace(vbNullChar, " ") Catch ex As Exception 'Do Nothing End Try - End Sub + + Return sFullCommand + End Function 'This function will only work correctly on Unix Private Function GetUnixProcessArguments(ByVal prs As Process) As String() @@ -208,14 +147,89 @@ Public Class mgrProcessDetection Return False End Function + Private Function GetProcessPath(ByVal bWineProcess As Boolean) As String + Try + If Not bWineProcess Then + Return Path.GetDirectoryName(FoundProcess.MainModule.FileName) + Else + Return GetUnixSymLinkDirectory(FoundProcess) + End If + Catch + Return String.Empty + End Try + End Function + + Private Sub FilterDetected(ByVal oDetectedGames As ArrayList, ByVal bWineProcess As Boolean) + Dim bMatch As Boolean = False + Dim sProcessPath As String + Dim sFullCommand As String + Dim oNotDetectedWithParameters As New ArrayList + Dim oDetectedWithParameters As New ArrayList + Dim oDetectedWithProcessPath As New ArrayList + + 'Get parameters of the found process + If mgrCommon.IsUnix Then + sFullCommand = GetUnixCommand(FoundProcess) + Else + sFullCommand = GetWindowsCommand(FoundProcess) + End If + + 'Look for any games using parameters and any matches + For Each oDetectedGame As clsGame In oDetectedGames + If oDetectedGame.Parameter <> String.Empty Then + If sFullCommand.Contains(oDetectedGame.Parameter) Then + oDetectedWithParameters.Add(oDetectedGame) + Else + oNotDetectedWithParameters.Add(oDetectedGame) + End If + + End If + Next + + 'If we detected at least one parameter match, replace full detected list with the detected with parameter list + If oDetectedWithParameters.Count > 0 Then + oDetectedGames = oDetectedWithParameters + Else + 'If there is no parameter match, remove any games using parameters from the detected list + For Each oGameNotDetected As clsGame In oNotDetectedWithParameters + oDetectedGames.Remove(oGameNotDetected) + Next + End If + + 'If there's only one match after parameter detection, set it as current game and we're done. + If oDetectedGames.Count = 1 Then + GameInfo = oDetectedGames(0) + Duplicate = False + Else + 'Get Process Path + sProcessPath = GetProcessPath(bWineProcess) + + 'Check if we have any exact matches based on process path + For Each oDetectedGame As clsGame In oDetectedGames + If oDetectedGame.ProcessPath = sProcessPath Then + oDetectedWithProcessPath.Add(oDetectedGame) + End If + Next + + 'If there's only one match after process detection, set it as current game and we're done + If oDetectedWithProcessPath.Count = 1 Then + GameInfo = oDetectedWithProcessPath(0) + Duplicate = False + Else + 'We've done all we can, the user must selected which game they were playing when the process ends + Duplicate = True + oDuplicateGames = oDetectedGames + End If + End If + End Sub + 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 bPass As Boolean + Dim oDetectedGames As New ArrayList For Each prsCurrent As Process In prsList - bPass = False 'This needs to be wrapped due to issues with Mono. Try @@ -245,39 +259,20 @@ Public Class mgrProcessDetection 'Do Nothing End Try - 'Detection Pass 1 For Each oCurrentGame As clsGame In hshScanList.Values If IsMatch(oCurrentGame, sProcessCheck) Then prsFoundProcess = prsCurrent oGame = oCurrentGame.ShallowCopy - bPass = True - - If mgrCommon.IsUnix Then - GetUnixCommand(prsCurrent) - Else - GetWindowsCommand(prsCurrent) - End If - - If oGame.Duplicate = True Then - If HandleDuplicates(hshScanList) Then - bDuplicates = False - oDuplicateGames.Clear() - End If - Else - bDuplicates = False - oDuplicateGames.Clear() - End If - - If Duplicate And DuplicateList.Count = 0 Then bPass = False - - If oGame.Parameter <> String.Empty And Not Duplicate And Not FullCommand.Contains(oGame.Parameter) Then bPass = False + oDetectedGames.Add(oGame.ShallowCopy) End If Next - 'Detection Pass 2 - If bPass Then - 'Determine the process path if we need it - If Not oGame.AbsolutePath Or oGame.Duplicate Then + If oDetectedGames.Count > 0 Then + FilterDetected(oDetectedGames, bWineProcess) + End If + + If oDetectedGames.Count > 0 Then + If Not oGame.AbsolutePath And Not oGame.MonitorOnly Then Try If Not bWineProcess Then oGame.ProcessPath = Path.GetDirectoryName(prsCurrent.MainModule.FileName) @@ -296,24 +291,14 @@ Public Class mgrProcessDetection iErrorCode = 299 Else If bDebugMode Then mgrCommon.ShowMessage(exWin32.NativeErrorCode & " " & exWin32.Message & vbCrLf & vbCrLf & exWin32.StackTrace, MsgBoxStyle.Critical) - 'A different failure occured, drop out and continue to scan. - bPass = False + Return False End If Catch exAll As Exception If bDebugMode Then mgrCommon.ShowMessage(exAll.Message & vbCrLf & vbCrLf & exAll.StackTrace, MsgBoxStyle.Critical) - 'A different failure occured, drop out and continue to scan. - bPass = False + Return False End Try End If - - 'This will force two cycles for detection to try and prevent issues with UAC prompt - If Not bVerified Then - bVerified = True - Return False - Else - bVerified = False - Return True - End If + Return True End If Next diff --git a/GBM/Managers/mgrRestore.vb b/GBM/Managers/mgrRestore.vb index 91dd280..3f89ac9 100644 --- a/GBM/Managers/mgrRestore.vb +++ b/GBM/Managers/mgrRestore.vb @@ -37,7 +37,7 @@ Public Class mgrRestore If oGame.ProcessPath <> String.Empty Then oRestoreInfo.RelativeRestorePath = oGame.ProcessPath & Path.DirectorySeparatorChar & oRestoreInfo.RestorePath Else - sProcess = oGame.TrueProcess + sProcess = oGame.ProcessName If mgrCommon.IsProcessNotSearchable(oGame) Then bNoAuto = True sRestorePath = mgrPath.ProcessPathSearch(oRestoreInfo.Name, sProcess, mgrCommon.FormatString(mgrRestore_RelativeNeedPath, oRestoreInfo.Name), bNoAuto) From 7ca4178631baf48ecf6c6bc3c3ccfb6ac582885a Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Mon, 3 Sep 2018 15:57:01 -0600 Subject: [PATCH 06/32] Detection rewrite for issue #153 - Pass 2 --- GBM/Forms/frmChooseGame.vb | 2 +- GBM/Forms/frmMain.vb | 5 ---- GBM/Managers/mgrProcessDetection.vb | 45 ++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/GBM/Forms/frmChooseGame.vb b/GBM/Forms/frmChooseGame.vb index ef6f040..3a9a18a 100644 --- a/GBM/Forms/frmChooseGame.vb +++ b/GBM/Forms/frmChooseGame.vb @@ -38,7 +38,7 @@ Public Class frmChooseGame End Sub Private Sub SaveSelection() - oGame.ProcessPath = oProcess.GameInfo.ProcessPath + oGame.ProcessPath = oProcess.ProcessPath mgrMonitorList.DoListUpdate(oGame) End Sub diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index 5fe1357..e284f5c 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -266,14 +266,9 @@ Public Class frmMain frm.Process = oProcess oResult = frm.ShowDialog() If oResult = DialogResult.OK Then - Dim sProcessPath As String 'Reload settings LoadGameSettings() - 'Retain the process path from old object - sProcessPath = oProcess.GameInfo.ProcessPath oProcess.GameInfo = frm.Game - 'Set the process path into the new object - oProcess.GameInfo.ProcessPath = sProcessPath 'A game was set, return and continue Return True Else diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index d04b4b0..776fa16 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -5,6 +5,7 @@ Imports System.Text.RegularExpressions Public Class mgrProcessDetection Private prsFoundProcess As Process + Private sProcessPath As String Private dStartTime As DateTime = Now, dEndTime As DateTime = Now Private lTimeSpent As Long = 0 Private oGame As clsGame @@ -20,6 +21,15 @@ Public Class mgrProcessDetection End Set End Property + Property ProcessPath As String + Get + Return sProcessPath + End Get + Set(value As String) + sProcessPath = value + End Set + End Property + Property StartTime As DateTime Get Return dStartTime @@ -91,7 +101,7 @@ Public Class mgrProcessDetection Dim sFullCommand As String = String.Empty Try sFullCommand = File.ReadAllText("/proc/" & prs.Id.ToString() & "/cmdline").Replace(vbNullChar, " ") - Catch ex As Exception + Catch 'Do Nothing End Try @@ -161,10 +171,10 @@ Public Class mgrProcessDetection Private Sub FilterDetected(ByVal oDetectedGames As ArrayList, ByVal bWineProcess As Boolean) Dim bMatch As Boolean = False - Dim sProcessPath As String Dim sFullCommand As String Dim oNotDetectedWithParameters As New ArrayList Dim oDetectedWithParameters As New ArrayList + Dim oNotDetectedWithProcessPath As New ArrayList Dim oDetectedWithProcessPath As New ArrayList 'Get parameters of the found process @@ -174,6 +184,9 @@ Public Class mgrProcessDetection sFullCommand = GetWindowsCommand(FoundProcess) End If + 'Get Process Path + ProcessPath = GetProcessPath(bWineProcess) + 'Look for any games using parameters and any matches For Each oDetectedGame As clsGame In oDetectedGames If oDetectedGame.Parameter <> String.Empty Then @@ -201,13 +214,14 @@ Public Class mgrProcessDetection GameInfo = oDetectedGames(0) Duplicate = False Else - 'Get Process Path - sProcessPath = GetProcessPath(bWineProcess) - 'Check if we have any exact matches based on process path For Each oDetectedGame As clsGame In oDetectedGames - If oDetectedGame.ProcessPath = sProcessPath Then - oDetectedWithProcessPath.Add(oDetectedGame) + If oDetectedGame.ProcessPath <> String.Empty Then + If oDetectedGame.ProcessPath = ProcessPath Then + oDetectedWithProcessPath.Add(oDetectedGame) + Else + oNotDetectedWithProcessPath.Add(oDetectedGame) + End If End If Next @@ -216,9 +230,20 @@ Public Class mgrProcessDetection GameInfo = oDetectedWithProcessPath(0) Duplicate = False Else - 'We've done all we can, the user must selected which game they were playing when the process ends - Duplicate = True - oDuplicateGames = oDetectedGames + 'Remove any games with a process path that does not match the current process + For Each oGameNotDetected As clsGame In oNotDetectedWithProcessPath + oDetectedGames.Remove(oGameNotDetected) + Next + + 'If only a single game remains, set it as current game and we're done + If oDetectedGames.Count = 1 Then + GameInfo = oDetectedGames(0) + Duplicate = False + Else + 'We've done all we can, the user must selected which game they were playing when the process ends + Duplicate = True + oDuplicateGames = oDetectedGames + End If End If End If End Sub From d74a6d50b103ee827c24de5884da3bc11a65318d Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Tue, 4 Sep 2018 09:16:49 -0600 Subject: [PATCH 07/32] Detection rewrite for issue #153 - Pass 3 --- GBM/Managers/mgrProcessDetection.vb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/GBM/Managers/mgrProcessDetection.vb b/GBM/Managers/mgrProcessDetection.vb index 776fa16..3d4f3e7 100644 --- a/GBM/Managers/mgrProcessDetection.vb +++ b/GBM/Managers/mgrProcessDetection.vb @@ -11,6 +11,7 @@ Public Class mgrProcessDetection Private oGame As clsGame Private oDuplicateGames As New ArrayList Private bDuplicates As Boolean + Private bVerified As Boolean = False Property FoundProcess As Process Get @@ -305,9 +306,6 @@ Public Class mgrProcessDetection oGame.ProcessPath = GetUnixSymLinkDirectory(prsCurrent) End If Catch exWin32 As System.ComponentModel.Win32Exception - 'If an exception occurs the process is: - 'Running as administrator and the app isn't. - 'The process is 64-bit and the process folder is required, shouldn't happen often. If exWin32.NativeErrorCode = 5 Then bNeedsPath = True iErrorCode = 5 @@ -323,12 +321,20 @@ Public Class mgrProcessDetection Return False End Try End If - Return True + + If bDebugMode Then mgrCommon.SaveText(sProcessList, mgrPath.SettingsRoot & "/gbm_process_list.txt") + + 'This will force two cycles for detection to try and prevent issues with UAC prompt + If Not bVerified Then + bVerified = True + Return False + Else + bVerified = False + Return True + End If End If Next - If bDebugMode Then mgrCommon.SaveText(sProcessList, mgrPath.SettingsRoot & "/gbm_process_list.txt") - Return False End Function From 748a921d1c8bed858b195ba34a21b46d88b53a7b Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Thu, 6 Sep 2018 12:35:14 -0600 Subject: [PATCH 08/32] Changes for issue #152 - Pass 1 --- GBM/Classes/clsBackup.vb | 2 +- GBM/Classes/clsGame.vb | 2 +- GBM/Classes/clsPathVariable.vb | 2 +- GBM/Forms/frmMain.vb | 2 +- GBM/Managers/mgrPath.vb | 137 ++++++++++++++++----------- GBM/Managers/mgrSQLite.vb | 35 +++++++ GBM/My Project/Resources.Designer.vb | 9 ++ GBM/My Project/Resources.resx | 3 + 8 files changed, 134 insertions(+), 58 deletions(-) diff --git a/GBM/Classes/clsBackup.vb b/GBM/Classes/clsBackup.vb index f790844..d353ce4 100644 --- a/GBM/Classes/clsBackup.vb +++ b/GBM/Classes/clsBackup.vb @@ -74,7 +74,7 @@ Property RestorePath As String Get - Return mgrPath.ReplaceSpecialPaths(sRestorePath) + Return Environment.ExpandEnvironmentVariables(sRestorePath) End Get Set(value As String) sRestorePath = mgrPath.ReverseSpecialPaths(value) diff --git a/GBM/Classes/clsGame.vb b/GBM/Classes/clsGame.vb index 0ea8ec7..3aecc69 100644 --- a/GBM/Classes/clsGame.vb +++ b/GBM/Classes/clsGame.vb @@ -93,7 +93,7 @@ Public Class clsGame sPath = mgrPath.ReverseSpecialPaths(value) End Set Get - Return mgrPath.ReplaceSpecialPaths(sPath) + Return Environment.ExpandEnvironmentVariables(sPath) End Get End Property diff --git a/GBM/Classes/clsPathVariable.vb b/GBM/Classes/clsPathVariable.vb index 014bcef..70319d4 100644 --- a/GBM/Classes/clsPathVariable.vb +++ b/GBM/Classes/clsPathVariable.vb @@ -24,7 +24,7 @@ ReadOnly Property FormattedName As String Get - Return "*" & sVariableName & "*" + Return "%" & sVariableName & "%" End Get End Property diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index e284f5c..05a056c 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -935,7 +935,7 @@ Public Class frmMain Dim frm As New frmVariableManager PauseScan() frm.ShowDialog() - mgrPath.CustomVariablesReload() + mgrPath.LoadCustomVariables() mgrMonitorList.SyncMonitorLists(oSettings) ResumeScan() End Sub diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 9cfe373..262769a 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -12,10 +12,12 @@ Public Class mgrPath Private Shared sLogFile As String = sSettingsRoot & Path.DirectorySeparatorChar & "gbm_log_" & Date.Now.ToString("dd-MM-yyyy-HH-mm-ss") & ".txt" Private Shared sRemoteDatabaseLocation As String Private Shared hshCustomVariables As Hashtable + Private Shared hshUnixEnv As Hashtable Private Shared oReleaseType As ProcessorArchitecture = AssemblyName.GetAssemblyName(Application.ExecutablePath()).ProcessorArchitecture Shared Sub New() - hshCustomVariables = mgrVariables.ReadVariables + SetEnv() + LoadCustomVariables() End Sub Shared ReadOnly Property ReleaseType As Integer @@ -238,24 +240,24 @@ Public Class mgrPath Dim oMatch As Match Try - If sPath.Contains("*appdatalocal*") Then - sReplace = "*appdatalocal*" + If sPath.Contains("%LOCALAPPDATA%") Then + sReplace = "%LOCALAPPDATA%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") oParse = New Regex("""Local AppData""="".+?(?=\n)") - ElseIf sPath.Contains("*appdataroaming*") Then - sReplace = "*appdataroaming*" + ElseIf sPath.Contains("%APPDATA%") Then + sReplace = "%APPDATA%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") oParse = New Regex("""AppData""="".+?(?=\n)") - ElseIf sPath.Contains("*mydocs*") Then - sReplace = "*mydocs*" + ElseIf sPath.Contains("%USERDOCUMENTS%") Then + sReplace = "%USERDOCUMENTS%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") oParse = New Regex("""Personal""="".+?(?=\n)") - ElseIf sPath.Contains("*publicdocs*") Then - sReplace = "*publicdocs*" + ElseIf sPath.Contains("%COMMONDOCUMENTS%") Then + sReplace = "%COMMONDOCUMENTS%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "system.reg") oParse = New Regex("""Common Documents""="".+?(?=\n)") - ElseIf sPath.Contains("*currentuser*") Then - sReplace = "*currentuser*" + ElseIf sPath.Contains("%USERPROFILE%") Then + sReplace = "%USERPROFILE%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") oParse = New Regex("""Personal""="".+?(?=\\\\My Documents)") Else @@ -325,61 +327,84 @@ Public Class mgrPath Return bNoError End Function - Public Shared Function ReplaceSpecialPaths(sValue As String) As String - Dim sMyDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) - Dim sPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) - Dim sAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) - Dim sAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) - Dim sCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) - Dim oCustomVariable As clsPathVariable - - - For Each oCustomVariable In hshCustomVariables.Values - If sValue.Contains(oCustomVariable.FormattedName) Then - Return sValue.Replace(oCustomVariable.FormattedName, oCustomVariable.Path) - End If - Next - - If sValue.Contains("*appdatalocal*") Then - Return sValue.Replace("*appdatalocal*", sAppDataLocal) - End If - - If sValue.Contains("*appdataroaming*") Then - Return sValue.Replace("*appdataroaming*", sAppDataRoaming) - End If - - 'This needs to be tested last for Unix compatability - If sValue.Contains("*mydocs*") Then - Return sValue.Replace("*mydocs*", sMyDocs) - End If - - 'Don't use these in Unix + Private Shared Sub SetEnv() If Not mgrCommon.IsUnix Then - If sValue.Contains("*publicdocs*") Then - Return sValue.Replace("*publicdocs*", sPublicDocs) + Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) + Environment.SetEnvironmentVariable("COMMONDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)) + Else + GetUnixEnv() + Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) + Environment.SetEnvironmentVariable("APPDATA", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + Environment.SetEnvironmentVariable("LOCALAPPDATA", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + End If + + End Sub + + Private Shared Sub GetUnixEnv() + Dim prEnv As Process + Dim sEnv As String() + + Try + hshUnixEnv = New Hashtable + prEnv = New Process + prEnv.StartInfo.FileName = "/usr/bin/env" + prEnv.StartInfo.UseShellExecute = False + prEnv.StartInfo.RedirectStandardOutput = True + prEnv.StartInfo.CreateNoWindow = True + prEnv.Start() + + Using swEnv As StreamReader = prEnv.StandardOutput + While Not swEnv.EndOfStream + sEnv = swEnv.ReadLine().Split("=") + If Not hshUnixEnv.Contains(sEnv(0)) Then + hshUnixEnv.Add(sEnv(0), sEnv(1)) + End If + End While + End Using + Catch ex As Exception + mgrCommon.ShowMessage(mgrPath_ErrorUnixEnv, ex.Message, MsgBoxStyle.Exclamation) + End Try + End Sub + + Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String + Dim sUnixShortHome As String = "~" + Dim sEnvUnixHome As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Dim sCurrentUnixVar As String + + If mgrCommon.IsUnix Then + 'Replace ~ for HOME + If sValue.Contains(sUnixShortHome) Then + Return sValue.Replace(sUnixShortHome, sEnvUnixHome) End If - If sValue.Contains("*currentuser*") Then - Return sValue.Replace("*currentuser*", sCurrentUser) - End If + 'Replace any other environemnt variable + For Each de As DictionaryEntry In hshUnixEnv + sCurrentUnixVar = "$" & de.Key + If sValue.Contains(sCurrentUnixVar) Then + sValue = sValue.Replace(sCurrentUnixVar, de.Value) + End If + Next + Else + sValue = Environment.ExpandEnvironmentVariables(sValue) End If Return sValue End Function Public Shared Function ReverseSpecialPaths(sValue As String) As String - Dim sMyDocs As String = "*mydocs*" + Dim sMyDocs As String = "%USERDOCUMENTS%" Dim sEnvMyDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) - Dim sPublicDocs As String = "*publicdocs*" + Dim sPublicDocs As String = "%COMMONDOCUMENTS%" Dim sEnvPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) - Dim sAppDataLocal As String = "*appdatalocal*" + Dim sAppDataLocal As String = "%LOCALAPPDATA%" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) - Dim sAppDataRoaming As String = "*appdataroaming*" + Dim sAppDataRoaming As String = "%APPDATA%" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) - Dim sCurrentUser As String = "*currentuser*" + Dim sCurrentUser As String = "%USERPROFILE%" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable + sValue = ProcessEnvironmentVariables(sValue) For Each oCustomVariable In hshCustomVariables.Values If sValue.Contains(oCustomVariable.Path) Then @@ -400,7 +425,7 @@ Public Class mgrPath Return sValue.Replace(sEnvMyDocs, sMyDocs) End If - 'Don't use these in Unix + 'Mono doesn't set a path for these folders If Not mgrCommon.IsUnix Then If sValue.Contains(sEnvPublicDocs) Then Return sValue.Replace(sEnvPublicDocs, sPublicDocs) @@ -447,7 +472,7 @@ Public Class mgrPath Public Shared Function VerifyCustomVariables(ByVal hshScanlist As Hashtable, ByRef sGames As String) As Boolean Dim hshCustomVariables As Hashtable = mgrVariables.ReadVariables Dim sVariableCheck As String - Dim sPattern As String = "\*(.*)\*" + Dim sPattern As String = "\%(.*)\%" Dim oGame As clsGame Dim oMatch As Match Dim bClean As Boolean = True @@ -455,7 +480,7 @@ Public Class mgrPath For Each oGame In hshScanlist.Values oMatch = Regex.Match(oGame.Path, sPattern) If oMatch.Success Then - sVariableCheck = oMatch.Value.Replace("*", String.Empty) + sVariableCheck = oMatch.Value.Replace("%", String.Empty) If Not hshCustomVariables.ContainsKey(sVariableCheck) Then sGames &= vbCrLf & oGame.Name & " (" & sVariableCheck & ")" bClean = False @@ -466,8 +491,12 @@ Public Class mgrPath Return bClean End Function - Public Shared Sub CustomVariablesReload() + Public Shared Sub LoadCustomVariables() hshCustomVariables = mgrVariables.ReadVariables + + For Each oVariable As clsPathVariable In hshCustomVariables.Values + Environment.SetEnvironmentVariable(oVariable.Name, oVariable.Path) + Next End Sub Public Shared Function SetManualGamePath() As String diff --git a/GBM/Managers/mgrSQLite.vb b/GBM/Managers/mgrSQLite.vb index 17d9b66..0431200 100644 --- a/GBM/Managers/mgrSQLite.vb +++ b/GBM/Managers/mgrSQLite.vb @@ -848,6 +848,41 @@ Public Class mgrSQLite CompactDatabase() End If End If + + '1.15 Upgrade + If GetDatabaseVersion() < 115 Then + If eDatabase = Database.Local Then + 'Backup DB before starting + BackupDB("v110") + + sSQL = "PRAGMA user_version=115" + + RunParamQuery(sSQL, New Hashtable) + End If + If eDatabase = Database.Remote Then + 'Backup DB before starting + BackupDB("v110") + + 'Convert core path variables to new standard + sSQL = "UPDATE monitorlist SET Path = Replace(Path,'*appdatalocal*','%LOCALAPPDATA%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*appdataroaming*','%APPDATA%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*mydocs*','%USERDOCUMENTS%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*currentuser*','%USERPROFILE%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*publicdocs*','%COMMONDOCUMENTS%');" + + 'Convert custom variables to new standard + Dim hshVariables As Hashtable = mgrVariables.ReadVariables() + Dim sOldVariable As String + For Each oVariable As clsPathVariable In hshVariables.Values + sOldVariable = "*" & oVariable.Name & "*" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'" & sOldVariable & "','" & oVariable.FormattedName & "');" + Next + + sSQL &= "PRAGMA user_version=115" + + RunParamQuery(sSQL, New Hashtable) + End If + End If End Sub Public Function GetDBSize() As Long diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 504fcd7..4ce4134 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -6123,6 +6123,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to An error occured while building a list of environment variables.[BR][BR][PARAM]. + ''' + Friend ReadOnly Property mgrPath_ErrorUnixEnv() As String + Get + Return ResourceManager.GetString("mgrPath_ErrorUnixEnv", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to An error occured when determining a Wine prefix.[BR][BR][PARAM]. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 056b5e8..65d3277 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2218,4 +2218,7 @@ An error occured when determining a Wine prefix.[BR][BR][PARAM] + + An error occured while building a list of environment variables.[BR][BR][PARAM] + \ No newline at end of file From cc8d16f4a9240e9c16a95d092902c559cb0b89ee Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 05:11:13 +0200 Subject: [PATCH 09/32] Export with Linux variables for #152 --- GBM/Managers/mgrPath.vb | 140 +++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 262769a..88fa2ab 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -12,7 +12,6 @@ Public Class mgrPath Private Shared sLogFile As String = sSettingsRoot & Path.DirectorySeparatorChar & "gbm_log_" & Date.Now.ToString("dd-MM-yyyy-HH-mm-ss") & ".txt" Private Shared sRemoteDatabaseLocation As String Private Shared hshCustomVariables As Hashtable - Private Shared hshUnixEnv As Hashtable Private Shared oReleaseType As ProcessorArchitecture = AssemblyName.GetAssemblyName(Application.ExecutablePath()).ProcessorArchitecture Shared Sub New() @@ -331,61 +330,54 @@ Public Class mgrPath If Not mgrCommon.IsUnix Then Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) Environment.SetEnvironmentVariable("COMMONDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)) - Else - GetUnixEnv() - Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) - Environment.SetEnvironmentVariable("APPDATA", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) - Environment.SetEnvironmentVariable("LOCALAPPDATA", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) End If End Sub - Private Shared Sub GetUnixEnv() - Dim prEnv As Process - Dim sEnv As String() - - Try - hshUnixEnv = New Hashtable - prEnv = New Process - prEnv.StartInfo.FileName = "/usr/bin/env" - prEnv.StartInfo.UseShellExecute = False - prEnv.StartInfo.RedirectStandardOutput = True - prEnv.StartInfo.CreateNoWindow = True - prEnv.Start() - - Using swEnv As StreamReader = prEnv.StandardOutput - While Not swEnv.EndOfStream - sEnv = swEnv.ReadLine().Split("=") - If Not hshUnixEnv.Contains(sEnv(0)) Then - hshUnixEnv.Add(sEnv(0), sEnv(1)) - End If - End While - End Using - Catch ex As Exception - mgrCommon.ShowMessage(mgrPath_ErrorUnixEnv, ex.Message, MsgBoxStyle.Exclamation) - End Try - End Sub - Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String - Dim sUnixShortHome As String = "~" - Dim sEnvUnixHome As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) - Dim sCurrentUnixVar As String + Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Dim sCurrentUserLinux As String = "${HOME}" + Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then - 'Replace ~ for HOME - If sValue.Contains(sUnixShortHome) Then - Return sValue.Replace(sUnixShortHome, sEnvUnixHome) + Dim oParse As new Regex("\$([a-zA-Z0-9_]+?)") + Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + End If + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) End If - 'Replace any other environemnt variable - For Each de As DictionaryEntry In hshUnixEnv - sCurrentUnixVar = "$" & de.Key - If sValue.Contains(sCurrentUnixVar) Then - sValue = sValue.Replace(sCurrentUnixVar, de.Value) - End If - Next - Else - sValue = Environment.ExpandEnvironmentVariables(sValue) + '$HOME to ${HOME} + sValue = oParse.Replace(sValue, "${$1}") + 'Special notations for home directory + sValue = sValue.Replace("~", "${HOME}") + 'XDG Base Directory Specification has default values + sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") + sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") + + 'Replace with paths + sValue = sValue.Replace(sAppDataLocalLinux, sEnvAppDataLocal) + sValue = sValue.Replace(sAppDataRoamingLinux, sEnvAppDataRoaming) + sValue = sValue.Replace(sCurrentUserLinux, sEnvCurrentUser) + + 'Transform Linux variables to Windows variables + 'More complex syntax couldn't be converted back + sValue = oParseBracketed.Replace(sValue, "%$1%") + End If + 'On Linux real Linux environmental variables are used + sValue = Environment.ExpandEnvironmentVariables(sValue) + + If mgrCommon.IsUnix Then + 'TODO: breaks support of Windows variables on Linux + Dim oParse As new Regex("%([a-zA-Z0-9_]+?)%") + sValue = oParse.Replace(sValue, "${$1}") End If Return sValue @@ -397,36 +389,40 @@ Public Class mgrPath Dim sPublicDocs As String = "%COMMONDOCUMENTS%" Dim sEnvPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) Dim sAppDataLocal As String = "%LOCALAPPDATA%" + Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) Dim sAppDataRoaming As String = "%APPDATA%" + Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Dim sCurrentUser As String = "%USERPROFILE%" + Dim sCurrentUserLinux As String = "~" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable sValue = ProcessEnvironmentVariables(sValue) + For Each oCustomVariable In hshCustomVariables.Values If sValue.Contains(oCustomVariable.Path) Then Return sValue.Replace(oCustomVariable.Path, oCustomVariable.FormattedName) End If Next - If sValue.Contains(sEnvAppDataRoaming) Then - Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoaming) - End If - - If sValue.Contains(sEnvAppDataLocal) Then - Return sValue.Replace(sEnvAppDataLocal, sAppDataLocal) - End If - - 'This needs to be tested last for Unix compatability - If sValue.Contains(sEnvMyDocs) Then - Return sValue.Replace(sEnvMyDocs, sMyDocs) - End If - - 'Mono doesn't set a path for these folders If Not mgrCommon.IsUnix Then + If sValue.Contains(sEnvAppDataRoaming) Then + Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoaming) + End If + + If sValue.Contains(sEnvAppDataLocal) Then + Return sValue.Replace(sEnvAppDataLocal, sAppDataLocal) + End If + + 'This needs to be tested last for Unix compatability + If sValue.Contains(sEnvMyDocs) Then + Return sValue.Replace(sEnvMyDocs, sMyDocs) + End If + + 'Mono doesn't set a path for these folders If sValue.Contains(sEnvPublicDocs) Then Return sValue.Replace(sEnvPublicDocs, sPublicDocs) End If @@ -434,6 +430,28 @@ Public Class mgrPath If sValue.Contains(sEnvCurrentUser) Then Return sValue.Replace(sEnvCurrentUser, sCurrentUser) End If + Else + 'Use different paths on Linux + If sValue.Contains(sEnvAppDataRoaming) Then + Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoamingLinux) + End If + + If sValue.Contains(sEnvAppDataLocal) Then + Return sValue.Replace(sEnvAppDataLocal, sAppDataLocalLinux) + End If + + 'Must be last + If sValue.Contains(sEnvCurrentUser) Then + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + End If + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = sMyDocs + End If + Return sValue.Replace(sEnvCurrentUser, sCurrentUserLinux) + End If End If Return sValue From 874dfd4c86c459d0df75d94c69ac0bcb9f1e8567 Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 06:11:50 +0200 Subject: [PATCH 10/32] Replace ~ only outside of variables --- GBM/Managers/mgrPath.vb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 88fa2ab..4fd8ce3 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -343,8 +343,9 @@ Public Class mgrPath Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then - Dim oParse As new Regex("\$([a-zA-Z0-9_]+?)") + Dim oParse As new Regex("\$([a-zA-Z0-9_]+)") Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + Dim oParseTilde As new Regex("~(?![^\$\{]*\})") If sEnvCurrentUser = String.Empty Then 'Fall back sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) @@ -357,7 +358,8 @@ Public Class mgrPath '$HOME to ${HOME} sValue = oParse.Replace(sValue, "${$1}") 'Special notations for home directory - sValue = sValue.Replace("~", "${HOME}") + 'Don't replace inside variables + sValue = oParseTilde.Replace(sValue,"${HOME}") 'XDG Base Directory Specification has default values sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") From 9b89af931f48548c53c6648baf68623ff7d3fdba Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 06:31:46 +0200 Subject: [PATCH 11/32] Keep Windows variables untouched on Linux --- GBM/Managers/mgrPath.vb | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 4fd8ce3..b2c9e88 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -335,16 +335,19 @@ Public Class mgrPath End Sub Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String - Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sXdgData As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) - Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sXdgConfig As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) - Dim sCurrentUserLinux As String = "${HOME}" + Dim sHomeDir As String = "${HOME}" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then + '$VAR_iable Dim oParse As new Regex("\$([a-zA-Z0-9_]+)") + '${VAR_iable} but not advanced syntax like ${VAR:-iable} Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + '~ not inside ${...} Dim oParseTilde As new Regex("~(?![^\$\{]*\})") If sEnvCurrentUser = String.Empty Then 'Fall back @@ -358,28 +361,31 @@ Public Class mgrPath '$HOME to ${HOME} sValue = oParse.Replace(sValue, "${$1}") 'Special notations for home directory - 'Don't replace inside variables sValue = oParseTilde.Replace(sValue,"${HOME}") 'XDG Base Directory Specification has default values - sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") - sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") + sValue = sValue.Replace("${XDG_DATA_HOME}", sXdgData) + sValue = sValue.Replace("${XDG_CONFIG_HOME}", sXdgConfig) 'Replace with paths - sValue = sValue.Replace(sAppDataLocalLinux, sEnvAppDataLocal) - sValue = sValue.Replace(sAppDataRoamingLinux, sEnvAppDataRoaming) - sValue = sValue.Replace(sCurrentUserLinux, sEnvCurrentUser) + sValue = sValue.Replace(sXdgData, sEnvAppDataLocal) + sValue = sValue.Replace(sXdgConfig, sEnvAppDataRoaming) + sValue = sValue.Replace(sHomeDir, sEnvCurrentUser) + 'Escape real Windows variables + sValue = sValue.Replace("%", "\%") 'Transform Linux variables to Windows variables - 'More complex syntax couldn't be converted back sValue = oParseBracketed.Replace(sValue, "%$1%") End If + 'On Linux real Linux environmental variables are used sValue = Environment.ExpandEnvironmentVariables(sValue) If mgrCommon.IsUnix Then - 'TODO: breaks support of Windows variables on Linux + 'Transform missing variables back Dim oParse As new Regex("%([a-zA-Z0-9_]+?)%") sValue = oParse.Replace(sValue, "${$1}") + 'Unscape real Windows variables + sValue = sValue.Replace("\%", "%") End If Return sValue @@ -391,13 +397,13 @@ Public Class mgrPath Dim sPublicDocs As String = "%COMMONDOCUMENTS%" Dim sEnvPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) Dim sAppDataLocal As String = "%LOCALAPPDATA%" - Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sXdgData As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) Dim sAppDataRoaming As String = "%APPDATA%" - Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sXdgConfig As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Dim sCurrentUser As String = "%USERPROFILE%" - Dim sCurrentUserLinux As String = "~" + Dim sHomeDir As String = "~" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable @@ -435,11 +441,11 @@ Public Class mgrPath Else 'Use different paths on Linux If sValue.Contains(sEnvAppDataRoaming) Then - Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoamingLinux) + Return sValue.Replace(sEnvAppDataRoaming, sXdgConfig) End If If sValue.Contains(sEnvAppDataLocal) Then - Return sValue.Replace(sEnvAppDataLocal, sAppDataLocalLinux) + Return sValue.Replace(sEnvAppDataLocal, sXdgData) End If 'Must be last @@ -452,7 +458,7 @@ Public Class mgrPath 'Fall back sEnvCurrentUser = sMyDocs End If - Return sValue.Replace(sEnvCurrentUser, sCurrentUserLinux) + Return sValue.Replace(sEnvCurrentUser, sHomeDir) End If End If From fd6ddd4b8568c59497fba06d833d518623432a50 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 08:16:34 -0600 Subject: [PATCH 12/32] Updated path replacing for #152 --- .gitignore | 4 +--- GBM/Classes/clsBackup.vb | 2 +- GBM/Classes/clsGame.vb | 2 +- GBM/Managers/mgrPath.vb | 15 ++++++--------- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 38ad4fd..b2d328c 100644 --- a/.gitignore +++ b/.gitignore @@ -186,6 +186,4 @@ FakesAssemblies/ GeneratedArtifacts/ _Pvt_Extensions/ ModelManifest.xml -/.vs/slnx.sqlite -/.vs/VSWorkspaceState.json -/.vs/Game Backup Monitor/v15 +/.vs diff --git a/GBM/Classes/clsBackup.vb b/GBM/Classes/clsBackup.vb index d353ce4..f790844 100644 --- a/GBM/Classes/clsBackup.vb +++ b/GBM/Classes/clsBackup.vb @@ -74,7 +74,7 @@ Property RestorePath As String Get - Return Environment.ExpandEnvironmentVariables(sRestorePath) + Return mgrPath.ReplaceSpecialPaths(sRestorePath) End Get Set(value As String) sRestorePath = mgrPath.ReverseSpecialPaths(value) diff --git a/GBM/Classes/clsGame.vb b/GBM/Classes/clsGame.vb index 3aecc69..0ea8ec7 100644 --- a/GBM/Classes/clsGame.vb +++ b/GBM/Classes/clsGame.vb @@ -93,7 +93,7 @@ Public Class clsGame sPath = mgrPath.ReverseSpecialPaths(value) End Set Get - Return Environment.ExpandEnvironmentVariables(sPath) + Return mgrPath.ReplaceSpecialPaths(sPath) End Get End Property diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index b2c9e88..5bf13ae 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -334,7 +334,7 @@ Public Class mgrPath End Sub - Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String + Public Shared Function ReplaceSpecialPaths(ByVal sValue As String) As String Dim sXdgData As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) Dim sXdgConfig As String = "${XDG_CONFIG_HOME:-~/.config}" @@ -344,11 +344,11 @@ Public Class mgrPath If mgrCommon.IsUnix Then '$VAR_iable - Dim oParse As new Regex("\$([a-zA-Z0-9_]+)") + Dim oParse As New Regex("\$([a-zA-Z0-9_]+)") '${VAR_iable} but not advanced syntax like ${VAR:-iable} - Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + Dim oParseBracketed As New Regex("\$\{([a-zA-Z0-9_]+?)\}") '~ not inside ${...} - Dim oParseTilde As new Regex("~(?![^\$\{]*\})") + Dim oParseTilde As New Regex("~(?![^\$\{]*\})") If sEnvCurrentUser = String.Empty Then 'Fall back sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) @@ -361,7 +361,7 @@ Public Class mgrPath '$HOME to ${HOME} sValue = oParse.Replace(sValue, "${$1}") 'Special notations for home directory - sValue = oParseTilde.Replace(sValue,"${HOME}") + sValue = oParseTilde.Replace(sValue, "${HOME}") 'XDG Base Directory Specification has default values sValue = sValue.Replace("${XDG_DATA_HOME}", sXdgData) sValue = sValue.Replace("${XDG_CONFIG_HOME}", sXdgConfig) @@ -382,7 +382,7 @@ Public Class mgrPath If mgrCommon.IsUnix Then 'Transform missing variables back - Dim oParse As new Regex("%([a-zA-Z0-9_]+?)%") + Dim oParse As New Regex("%([a-zA-Z0-9_]+?)%") sValue = oParse.Replace(sValue, "${$1}") 'Unscape real Windows variables sValue = sValue.Replace("\%", "%") @@ -407,9 +407,6 @@ Public Class mgrPath Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable - sValue = ProcessEnvironmentVariables(sValue) - - For Each oCustomVariable In hshCustomVariables.Values If sValue.Contains(oCustomVariable.Path) Then Return sValue.Replace(oCustomVariable.Path, oCustomVariable.FormattedName) From 9fc53e74b1987fa9d719852d6fb368a0c0a3f5c8 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 09:35:46 -0600 Subject: [PATCH 13/32] Use linux variables in db upgrade for issue #152 --- GBM/Managers/mgrSQLite.vb | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/GBM/Managers/mgrSQLite.vb b/GBM/Managers/mgrSQLite.vb index 0431200..65db77a 100644 --- a/GBM/Managers/mgrSQLite.vb +++ b/GBM/Managers/mgrSQLite.vb @@ -863,12 +863,18 @@ Public Class mgrSQLite 'Backup DB before starting BackupDB("v110") - 'Convert core path variables to new standard - sSQL = "UPDATE monitorlist SET Path = Replace(Path,'*appdatalocal*','%LOCALAPPDATA%');" - sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*appdataroaming*','%APPDATA%');" - sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*mydocs*','%USERDOCUMENTS%');" - sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*currentuser*','%USERPROFILE%');" - sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*publicdocs*','%COMMONDOCUMENTS%');" + 'Convert core path variables to new standard + If Not mgrCommon.IsUnix Then + sSQL = "UPDATE monitorlist SET Path = Replace(Path,'*appdatalocal*','%LOCALAPPDATA%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*appdataroaming*','%APPDATA%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*mydocs*','%USERDOCUMENTS%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*currentuser*','%USERPROFILE%');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*publicdocs*','%COMMONDOCUMENTS%');" + Else + sSQL = "UPDATE monitorlist SET Path = Replace(Path,'*appdatalocal*','${XDG_DATA_HOME:-~/.local/share}');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*appdataroaming*','${XDG_CONFIG_HOME:-~/.config}');" + sSQL &= "UPDATE monitorlist SET Path = Replace(Path,'*mydocs*','~');" + End If 'Convert custom variables to new standard Dim hshVariables As Hashtable = mgrVariables.ReadVariables() @@ -880,9 +886,9 @@ Public Class mgrSQLite sSQL &= "PRAGMA user_version=115" - RunParamQuery(sSQL, New Hashtable) + RunParamQuery(sSQL, New Hashtable) + End If End If - End If End Sub Public Function GetDBSize() As Long From b674e4e82b233093e36ab7e7083dac8aaa22ecc9 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 11:30:55 -0600 Subject: [PATCH 14/32] Display variable path on Game Manager for #152 --- GBM/Forms/frmGameManager.vb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 98ebc8c..3f16a01 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -162,14 +162,16 @@ Public Class frmGameManager oLocalBackupData = mgrManifest.ReadLatestManifest(mgrSQLite.Database.Local) End Sub - Private Function ConvertToRelativePath(ByVal sSavePath As String, ByVal sAppPath As String) As String + Private Function HandleSavePath(ByVal sSavePath As String, ByVal sAppPath As String) As String Dim sPath As String = sSavePath - 'Determine a relative path if possible - If sAppPath <> String.Empty And sSavePath <> String.Empty Then - If Not mgrPath.IsAbsolute(sSavePath) Then + If Not mgrPath.IsAbsolute(sSavePath) Then + 'Determine a relative path if possible + If sAppPath <> String.Empty And sSavePath <> String.Empty Then sPath = mgrPath.DetermineRelativePath(sAppPath, sSavePath) End If + Else + sPath = mgrPath.ReverseSpecialPaths(sPath) End If Return sPath @@ -380,7 +382,7 @@ Public Class frmGameManager If sNewPath <> String.Empty Then txtSavePath.Text = sNewPath - txtSavePath.Text = ConvertToRelativePath(txtSavePath.Text, txtAppPath.Text) + txtSavePath.Text = HandleSavePath(txtSavePath.Text, txtAppPath.Text) End If End Sub @@ -867,7 +869,7 @@ Public Class frmGameManager txtProcess.Text = oApp.ProcessName chkRegEx.Checked = oApp.IsRegEx txtParameter.Text = oApp.Parameter - txtSavePath.Text = oApp.Path + txtSavePath.Text = oApp.TruePath txtFileType.Text = oApp.FileType txtExclude.Text = oApp.ExcludeList chkFolderSave.Checked = oApp.FolderSave From 8ab209c1a906823837b6873cd8a0e4b2fc798836 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 13:20:02 -0600 Subject: [PATCH 15/32] Added path display tooltip and options for #152 --- GBM/Forms/frmGameManager.Designer.vb | 8 ++++++++ GBM/Forms/frmGameManager.resx | 3 +++ GBM/Forms/frmGameManager.vb | 15 +++++++++++++-- GBM/Forms/frmSettings.Designer.vb | 21 +++++++++++++++++---- GBM/Forms/frmSettings.vb | 3 +++ GBM/Managers/mgrSQLite.vb | 7 +++++-- GBM/Managers/mgrSettings.vb | 14 +++++++++++++- GBM/My Project/Resources.Designer.vb | 9 +++++++++ GBM/My Project/Resources.resx | 3 +++ 9 files changed, 74 insertions(+), 9 deletions(-) diff --git a/GBM/Forms/frmGameManager.Designer.vb b/GBM/Forms/frmGameManager.Designer.vb index 09f743d..0191fc4 100644 --- a/GBM/Forms/frmGameManager.Designer.vb +++ b/GBM/Forms/frmGameManager.Designer.vb @@ -103,6 +103,7 @@ Partial Class frmGameManager Me.cmsDeleteOne = New System.Windows.Forms.ToolStripMenuItem() Me.cmsDeleteAll = New System.Windows.Forms.ToolStripMenuItem() Me.btnProcesses = New System.Windows.Forms.Button() + Me.ttFullPath = New System.Windows.Forms.ToolTip(Me.components) Me.grpConfig.SuspendLayout() CType(Me.nudLimit, System.ComponentModel.ISupportInitialize).BeginInit() Me.grpExtra.SuspendLayout() @@ -892,6 +893,12 @@ Partial Class frmGameManager Me.btnProcesses.Text = "Processes..." Me.btnProcesses.UseVisualStyleBackColor = True ' + 'ttFullPath + ' + Me.ttFullPath.AutoPopDelay = 5000 + Me.ttFullPath.InitialDelay = 300 + Me.ttFullPath.ReshowDelay = 60 + ' 'frmGameManager ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -1022,4 +1029,5 @@ Partial Class frmGameManager Friend WithEvents chkRegEx As CheckBox Friend WithEvents btnGameID As Button Friend WithEvents btnProcesses As Button + Friend WithEvents ttFullPath As ToolTip End Class diff --git a/GBM/Forms/frmGameManager.resx b/GBM/Forms/frmGameManager.resx index aa8299a..30ad1df 100644 --- a/GBM/Forms/frmGameManager.resx +++ b/GBM/Forms/frmGameManager.resx @@ -123,4 +123,7 @@ 127, 17 + + 275, 17 + \ No newline at end of file diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 3f16a01..10d9112 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -171,7 +171,9 @@ Public Class frmGameManager sPath = mgrPath.DetermineRelativePath(sAppPath, sSavePath) End If Else - sPath = mgrPath.ReverseSpecialPaths(sPath) + If Not oSettings.ShowResolvedPaths Then + sPath = mgrPath.ReverseSpecialPaths(sPath) + End If End If Return sPath @@ -862,6 +864,7 @@ Public Class frmGameManager Dim oData As KeyValuePair(Of String, String) = lstGames.SelectedItems(0) Dim oApp As clsGame = DirectCast(GameData(oData.Key), clsGame) + Dim sttPath As String 'Core txtID.Text = oApp.ID @@ -869,7 +872,14 @@ Public Class frmGameManager txtProcess.Text = oApp.ProcessName chkRegEx.Checked = oApp.IsRegEx txtParameter.Text = oApp.Parameter - txtSavePath.Text = oApp.TruePath + If oSettings.ShowResolvedPaths Then + txtSavePath.Text = oApp.Path + sttPath = oApp.TruePath + Else + txtSavePath.Text = oApp.TruePath + sttPath = oApp.Path + End If + If oApp.AbsolutePath Then ttFullPath.SetToolTip(txtSavePath, sttPath) txtFileType.Text = oApp.FileType txtExclude.Text = oApp.ExcludeList chkFolderSave.Checked = oApp.FolderSave @@ -1906,6 +1916,7 @@ Public Class frmGameManager End Sub Private Sub txtSavePath_TextChanged(sender As Object, e As EventArgs) Handles txtSavePath.TextChanged + ttFullPath.RemoveAll() VerifyCleanFolder() End Sub diff --git a/GBM/Forms/frmSettings.Designer.vb b/GBM/Forms/frmSettings.Designer.vb index 3f9a80a..fba3c43 100644 --- a/GBM/Forms/frmSettings.Designer.vb +++ b/GBM/Forms/frmSettings.Designer.vb @@ -73,6 +73,7 @@ Partial Class frmSettings Me.chkStartWindows = New System.Windows.Forms.CheckBox() Me.chkStartToTray = New System.Windows.Forms.CheckBox() Me.chkMonitorOnStartup = New System.Windows.Forms.CheckBox() + Me.chkShowResolvedPaths = New System.Windows.Forms.CheckBox() Me.grpFolderOptions.SuspendLayout() Me.grp7zGeneral.SuspendLayout() Me.pnlBackup.SuspendLayout() @@ -102,7 +103,7 @@ Partial Class frmSettings ' 'btnOptionalFields ' - Me.btnOptionalFields.Location = New System.Drawing.Point(6, 65) + Me.btnOptionalFields.Location = New System.Drawing.Point(6, 88) Me.btnOptionalFields.Name = "btnOptionalFields" Me.btnOptionalFields.Size = New System.Drawing.Size(216, 23) Me.btnOptionalFields.TabIndex = 3 @@ -443,7 +444,7 @@ Partial Class frmSettings Me.grpGameMonitoringOptions.Controls.Add(Me.lblMinutes) Me.grpGameMonitoringOptions.Controls.Add(Me.chkShowDetectionTips) Me.grpGameMonitoringOptions.Controls.Add(Me.nudSuppressBackupThreshold) - Me.grpGameMonitoringOptions.Location = New System.Drawing.Point(6, 115) + Me.grpGameMonitoringOptions.Location = New System.Drawing.Point(6, 141) Me.grpGameMonitoringOptions.Name = "grpGameMonitoringOptions" Me.grpGameMonitoringOptions.Size = New System.Drawing.Size(354, 65) Me.grpGameMonitoringOptions.TabIndex = 1 @@ -481,7 +482,7 @@ Partial Class frmSettings ' Me.grpLogOptions.Controls.Add(Me.chkDisableSyncMessages) Me.grpLogOptions.Controls.Add(Me.chkAutoSaveLog) - Me.grpLogOptions.Location = New System.Drawing.Point(6, 186) + Me.grpLogOptions.Location = New System.Drawing.Point(6, 212) Me.grpLogOptions.Name = "grpLogOptions" Me.grpLogOptions.Size = New System.Drawing.Size(354, 65) Me.grpLogOptions.TabIndex = 2 @@ -500,12 +501,13 @@ Partial Class frmSettings ' 'grpGameData ' + Me.grpGameData.Controls.Add(Me.chkShowResolvedPaths) Me.grpGameData.Controls.Add(Me.chkSessionTracking) Me.grpGameData.Controls.Add(Me.chkTimeTracking) Me.grpGameData.Controls.Add(Me.btnOptionalFields) Me.grpGameData.Location = New System.Drawing.Point(6, 12) Me.grpGameData.Name = "grpGameData" - Me.grpGameData.Size = New System.Drawing.Size(354, 97) + Me.grpGameData.Size = New System.Drawing.Size(354, 123) Me.grpGameData.TabIndex = 0 Me.grpGameData.TabStop = False Me.grpGameData.Text = "Game Data Options" @@ -598,6 +600,16 @@ Partial Class frmSettings Me.chkMonitorOnStartup.Text = "Start monitoring on launch" Me.chkMonitorOnStartup.UseVisualStyleBackColor = True ' + 'chkShowResolvedPaths + ' + Me.chkShowResolvedPaths.AutoSize = True + Me.chkShowResolvedPaths.Location = New System.Drawing.Point(6, 65) + Me.chkShowResolvedPaths.Name = "chkShowResolvedPaths" + Me.chkShowResolvedPaths.Size = New System.Drawing.Size(154, 17) + Me.chkShowResolvedPaths.TabIndex = 3 + Me.chkShowResolvedPaths.Text = "Show resolved save paths " + Me.chkShowResolvedPaths.UseVisualStyleBackColor = True + ' 'frmSettings ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -698,4 +710,5 @@ Partial Class frmSettings Friend WithEvents chkStartToTray As CheckBox Friend WithEvents chkMonitorOnStartup As CheckBox Friend WithEvents grpGameMonitoringOptions As GroupBox + Friend WithEvents chkShowResolvedPaths As CheckBox End Class diff --git a/GBM/Forms/frmSettings.vb b/GBM/Forms/frmSettings.vb index 59584ae..49a0443 100644 --- a/GBM/Forms/frmSettings.vb +++ b/GBM/Forms/frmSettings.vb @@ -60,6 +60,7 @@ Public Class frmSettings oSettings.AutoMark = chkAutoMark.Checked oSettings.TimeTracking = chkTimeTracking.Checked oSettings.SessionTracking = chkSessionTracking.Checked + oSettings.ShowResolvedPaths = chkShowResolvedPaths.Checked oSettings.SuppressBackup = chkSuppressBackup.Checked oSettings.SuppressBackupThreshold = nudSuppressBackupThreshold.Value oSettings.CompressionLevel = cboCompression.SelectedValue @@ -189,6 +190,7 @@ Public Class frmSettings txtBackupFolder.Text = oSettings.BackupFolder chkTimeTracking.Checked = oSettings.TimeTracking chkSessionTracking.Checked = oSettings.SessionTracking + chkShowResolvedPaths.Checked = oSettings.ShowResolvedPaths chkSuppressBackup.Checked = oSettings.SuppressBackup nudSuppressBackupThreshold.Value = oSettings.SuppressBackupThreshold nudSuppressBackupThreshold.Enabled = chkSuppressBackup.Checked @@ -322,6 +324,7 @@ Public Class frmSettings grpLogOptions.Text = frmSettings_grpLogOptions chkDisableSyncMessages.Text = frmSettings_chkDisableSyncMessages grpGameMonitoringOptions.Text = frmSettings_grpGameMonitoringOptions + chkShowResolvedPaths.Text = frmSettings_chkShowResolvedPaths 'Unix Handler If mgrCommon.IsUnix Then diff --git a/GBM/Managers/mgrSQLite.vb b/GBM/Managers/mgrSQLite.vb index 65db77a..7ead303 100644 --- a/GBM/Managers/mgrSQLite.vb +++ b/GBM/Managers/mgrSQLite.vb @@ -75,7 +75,7 @@ Public Class mgrSQLite "BackupFolder TEXT NOT NULL, StartWithWindows BOOLEAN NOT NULL, TimeTracking BOOLEAN NOT NULL, " & "SuppressBackup BOOLEAN NOT NULL, SuppressBackupThreshold INTEGER NOT NULL, CompressionLevel INTEGER NOT NULL, Custom7zArguments TEXT, " & "Custom7zLocation TEXT, SyncFields INTEGER NOT NULL, AutoSaveLog BOOLEAN NOT NULL, AutoRestore BOOLEAN NOT NULL, AutoMark BOOLEAN NOT NULL, SessionTracking BOOLEAN NOT NULL, " & - "SuppressMessages INTEGER NOT NULL, BackupOnLaunch BOOLEAN NOT NULL, UseGameID BOOLEAN NOT NULL, DisableSyncMessages BOOLEAN NOT NULL);" + "SuppressMessages INTEGER NOT NULL, BackupOnLaunch BOOLEAN NOT NULL, UseGameID BOOLEAN NOT NULL, DisableSyncMessages BOOLEAN NOT NULL, ShowResolvedPaths BOOLEAN NOT NULL);" 'Add Tables (SavedPath) sSql &= "CREATE TABLE savedpath (PathName TEXT NOT NULL PRIMARY KEY, Path TEXT NOT NULL);" @@ -855,7 +855,10 @@ Public Class mgrSQLite 'Backup DB before starting BackupDB("v110") - sSQL = "PRAGMA user_version=115" + 'Add new setting + sSQL = "ALTER TABLE settings ADD COLUMN ShowResolvedPaths BOOLEAN NOT NULL DEFAULT 1;" + + sSQL &= "PRAGMA user_version=115" RunParamQuery(sSQL, New Hashtable) End If diff --git a/GBM/Managers/mgrSettings.vb b/GBM/Managers/mgrSettings.vb index d7706b1..c4c6311 100644 --- a/GBM/Managers/mgrSettings.vb +++ b/GBM/Managers/mgrSettings.vb @@ -25,6 +25,7 @@ Public Class mgrSettings Private bBackupOnLaunch As Boolean = True Private bUseGameID As Boolean = False Private bDisableSyncMessages As Boolean = True + Private bShowResolvedPaths As Boolean = True Public Enum eSuppressMessages None = 0 @@ -175,6 +176,15 @@ Public Class mgrSettings End Set End Property + Property ShowResolvedPaths As Boolean + Get + Return bShowResolvedPaths + End Get + Set(value As Boolean) + bShowResolvedPaths = value + End Set + End Property + ReadOnly Property Prepared7zArguments As String Get 'Prepare custom 7z arguments @@ -309,7 +319,7 @@ Public Class mgrSettings sSQL &= "@CreateSubFolder, @ShowOverwriteWarning, @RestoreOnLaunch, @BackupFolder, @StartWithWindows, " sSQL &= "@TimeTracking, @SuppressBackup, @SuppressBackupThreshold, @CompressionLevel, @Custom7zArguments, @Custom7zLocation, " sSQL &= "@SyncFields, @AutoSaveLog, @AutoRestore, @AutoMark, @SessionTracking, @SuppressMessages, @BackupOnLaunch, @UseGameID, " - sSQL &= "@DisableSyncMessages)" + sSQL &= "@DisableSyncMessages, @ShowResolvedPaths)" hshParams.Add("MonitorOnStartup", MonitorOnStartup) hshParams.Add("StartToTray", StartToTray) @@ -335,6 +345,7 @@ Public Class mgrSettings hshParams.Add("BackupOnLaunch", BackupOnLaunch) hshParams.Add("UseGameID", UseGameID) hshParams.Add("DisableSyncMessages", DisableSyncMessages) + hshParams.Add("ShowResolvedPaths", ShowResolvedPaths) oDatabase.RunParamQuery(sSQL, hshParams) End Sub @@ -374,6 +385,7 @@ Public Class mgrSettings BackupOnLaunch = CBool(dr("BackupOnLaunch")) UseGameID = CBool(dr("UseGameID")) DisableSyncMessages = CBool(dr("DisableSyncMessages")) + ShowResolvedPaths = CBool(dr("ShowResolvedPaths")) Next oDatabase.Disconnect() diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 4ce4134..90b5240 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -4560,6 +4560,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Show resolved save paths. + ''' + Friend ReadOnly Property frmSettings_chkShowResolvedPaths() As String + Get + Return ResourceManager.GetString("frmSettings_chkShowResolvedPaths", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Start to system tray. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 65d3277..f3a1ed0 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2221,4 +2221,7 @@ An error occured while building a list of environment variables.[BR][BR][PARAM] + + Show resolved save paths + \ No newline at end of file From dcbfad7513e8eb5ad075a0c1829f984694171cd1 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 13:44:58 -0600 Subject: [PATCH 16/32] Add path display support to "Restore Path" field for #152 --- GBM/Forms/frmGameManager.vb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 10d9112..47389ba 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -749,6 +749,7 @@ Public Class frmGameManager Dim oComboItems As New List(Of KeyValuePair(Of String, String)) Dim bLocalData As Boolean = False Dim bRemoteData As Boolean = False + Dim sttRestorePath As String 'cboRemoteBackup cboRemoteBackup.ValueMember = "Key" @@ -777,7 +778,18 @@ Public Class frmGameManager lblBackupFileData.Text = frmGameManager_ErrorNoBackupExists End If - lblRestorePathData.Text = CurrentBackupItem.RestorePath + If Not CurrentBackupItem.AbsolutePath And oApp.ProcessPath <> String.Empty Then + lblRestorePathData.Text = oApp.ProcessPath & Path.DirectorySeparatorChar & CurrentBackupItem.RestorePath + Else + If oSettings.ShowResolvedPaths Then + lblRestorePathData.Text = CurrentBackupItem.RestorePath + sttRestorePath = CurrentBackupItem.TruePath + Else + lblRestorePathData.Text = CurrentBackupItem.TruePath + sttRestorePath = CurrentBackupItem.RestorePath + End If + If CurrentBackupItem.AbsolutePath Then ttFullPath.SetToolTip(lblRestorePathData, sttRestorePath) + End If Else oComboItems.Add(New KeyValuePair(Of String, String)(String.Empty, frmGameManager_None)) lblBackupFileData.Text = String.Empty From 26d33206df16540e5c752512901c24e5f355f6fb Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 23:35:11 -0600 Subject: [PATCH 17/32] Changes for issue #150 - Pass 1 --- GBM/Forms/frmAddWizard.vb | 2 +- GBM/Forms/frmGameManager.Designer.vb | 14 +++++- GBM/Forms/frmGameManager.vb | 57 +++++++++++++++++++++-- GBM/Forms/frmMain.vb | 11 +++++ GBM/Forms/frmProcessManager.vb | 2 +- GBM/Managers/mgrBackup.vb | 67 +++++++++++++++++++++++----- GBM/Managers/mgrCommon.vb | 60 +++++++++++++++++++------ GBM/My Project/Resources.Designer.vb | 65 ++++++++++++++++++++++++++- GBM/My Project/Resources.resx | 23 +++++++++- 9 files changed, 269 insertions(+), 32 deletions(-) diff --git a/GBM/Forms/frmAddWizard.vb b/GBM/Forms/frmAddWizard.vb index eadf9c0..6066c0d 100644 --- a/GBM/Forms/frmAddWizard.vb +++ b/GBM/Forms/frmAddWizard.vb @@ -416,7 +416,7 @@ Public Class frmAddWizard End If sNewPath = mgrCommon.OpenFileBrowser("Wizard_Process_Path", frmAddWizard_ChooseProcess, "exe", - frmAddWizard_Executable, sDefaultFolder, False, False) + frmAddWizard_Executable, sDefaultFolder, False) If sNewPath <> String.Empty Then txtProcessPath.Text = sNewPath End Sub diff --git a/GBM/Forms/frmGameManager.Designer.vb b/GBM/Forms/frmGameManager.Designer.vb index 0191fc4..a437865 100644 --- a/GBM/Forms/frmGameManager.Designer.vb +++ b/GBM/Forms/frmGameManager.Designer.vb @@ -104,6 +104,7 @@ Partial Class frmGameManager Me.cmsDeleteAll = New System.Windows.Forms.ToolStripMenuItem() Me.btnProcesses = New System.Windows.Forms.Button() Me.ttFullPath = New System.Windows.Forms.ToolTip(Me.components) + Me.btnImportBackup = New System.Windows.Forms.Button() Me.grpConfig.SuspendLayout() CType(Me.nudLimit, System.ComponentModel.ISupportInitialize).BeginInit() Me.grpExtra.SuspendLayout() @@ -573,6 +574,7 @@ Partial Class frmGameManager 'grpStats ' Me.grpStats.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) + Me.grpStats.Controls.Add(Me.btnImportBackup) Me.grpStats.Controls.Add(Me.cboRemoteBackup) Me.grpStats.Controls.Add(Me.lblRestorePathData) Me.grpStats.Controls.Add(Me.lblBackupFileData) @@ -665,7 +667,7 @@ Partial Class frmGameManager Me.btnDeleteBackup.Location = New System.Drawing.Point(129, 125) Me.btnDeleteBackup.Name = "btnDeleteBackup" Me.btnDeleteBackup.Size = New System.Drawing.Size(114, 23) - Me.btnDeleteBackup.TabIndex = 8 + Me.btnDeleteBackup.TabIndex = 9 Me.btnDeleteBackup.Text = "&Delete Backup" Me.btnDeleteBackup.UseVisualStyleBackColor = True ' @@ -899,6 +901,15 @@ Partial Class frmGameManager Me.ttFullPath.InitialDelay = 300 Me.ttFullPath.ReshowDelay = 60 ' + 'btnImportBackup + ' + Me.btnImportBackup.Location = New System.Drawing.Point(9, 125) + Me.btnImportBackup.Name = "btnImportBackup" + Me.btnImportBackup.Size = New System.Drawing.Size(114, 23) + Me.btnImportBackup.TabIndex = 8 + Me.btnImportBackup.Text = "Import B&ackup Files" + Me.btnImportBackup.UseVisualStyleBackColor = True + ' 'frmGameManager ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -1030,4 +1041,5 @@ Partial Class frmGameManager Friend WithEvents btnGameID As Button Friend WithEvents btnProcesses As Button Friend WithEvents ttFullPath As ToolTip + Friend WithEvents btnImportBackup As Button End Class diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 47389ba..dea6062 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -14,8 +14,10 @@ Public Class frmGameManager Private bDisableExternalFunctions As Boolean = False Private bTriggerBackup As Boolean = False Private bTriggerRestore As Boolean = False + Private bTriggerImportBackup As Boolean = False Private oBackupList As New List(Of clsGame) Private oRestoreList As New Hashtable + Private oImportBackupList As New Hashtable Private oGameData As OrderedDictionary Private oLocalBackupData As SortedList Private oRemoteBackupData As SortedList @@ -121,6 +123,15 @@ Public Class frmGameManager End Set End Property + Property TriggerImportBackup As Boolean + Get + Return bTriggerImportBackup + End Get + Set(value As Boolean) + bTriggerImportBackup = value + End Set + End Property + Property BackupList As List(Of clsGame) Get Return oBackupList @@ -139,6 +150,15 @@ Public Class frmGameManager End Set End Property + Property ImportBackupList As Hashtable + Get + Return oImportBackupList + End Get + Set(value As Hashtable) + oImportBackupList = value + End Set + End Property + Private Property IsDirty As Boolean Get Return bIsDirty @@ -344,7 +364,7 @@ Public Class frmGameManager End If sNewPath = mgrCommon.OpenFileBrowser("GM_Process", frmGameManager_ChooseExe, "exe", - frmGameManager_Executable, sDefaultFolder, False, False) + frmGameManager_Executable, sDefaultFolder, False) If sNewPath <> String.Empty Then txtAppPath.Text = Path.GetDirectoryName(sNewPath) @@ -402,10 +422,10 @@ Public Class frmGameManager 'Unix Handler If Not mgrCommon.IsUnix Then sNewPath = mgrCommon.OpenFileBrowser("GM_Icon", frmGameManager_ChooseCustomIcon, "ico", - frmGameManager_Icon, sDefaultFolder, False, False) + frmGameManager_Icon, sDefaultFolder, False) Else sNewPath = mgrCommon.OpenFileBrowser("GM_Icon", frmGameManager_ChooseCustomIcon, "png", - "PNG", sDefaultFolder, False, False) + "PNG", sDefaultFolder, False) End If If sNewPath <> String.Empty Then @@ -1524,6 +1544,31 @@ Public Class frmGameManager End If End Sub + Private Sub TriggerSelectedImportBackup() + Dim sDefaultFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Dim oBackup As New mgrBackup + Dim sFile As String + Dim sFiles As String() + + ImportBackupList.Clear() + + sFiles = mgrCommon.OpenMultiFileBrowser("GM_ImportBackup", frmGameManager_Choose7zImport, "7z", + frmGameManager_7zBackup, sDefaultFolder, True) + + If sFiles.Length > 0 Then + For Each sFile In sFiles + If Not ImportBackupList.Contains(sFile) Then + ImportBackupList.Add(sFile, oCurrentGame) + End If + Next + + If mgrCommon.ShowMessage(frmGameManager_ConfirmBackupImport, oCurrentGame.CroppedName, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then + Me.TriggerImportBackup = True + Me.Close() + End If + End If + End Sub + Private Sub TriggerSelectedBackup(Optional ByVal bPrompt As Boolean = True) Dim oData As KeyValuePair(Of String, String) Dim sMsg As String = String.Empty @@ -1722,6 +1767,7 @@ Public Class frmGameManager lblComments.Text = frmGameManager_lblComments chkRegEx.Text = frmGameManager_chkRegEx btnGameID.Text = frmGameManager_btnGameID + btnImportBackup.Text = frmGameManager_btnImportBackup 'Init Filter Timer tmFilterTimer = New Timer() @@ -1875,6 +1921,10 @@ Public Class frmGameManager UpdateBuilderButtonLabel(txtExclude.Text, frmGameManager_ExcludeShortcut, btnExclude, (sExclude <> txtExclude.Text)) End Sub + Private Sub btnImportBackup_Click(sender As Object, e As EventArgs) Handles btnImportBackup.Click + TriggerSelectedImportBackup() + End Sub + Private Sub chkFolderSave_CheckedChanged(sender As Object, e As EventArgs) Handles chkFolderSave.CheckedChanged FolderSaveModeChange() End Sub @@ -1947,5 +1997,4 @@ Public Class frmGameManager Private Sub chkMonitorOnly_CheckedChanged(sender As Object, e As EventArgs) Handles chkMonitorOnly.CheckedChanged MonitorOnlyModeChange() End Sub - End Class diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index 05a056c..f839c58 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -258,6 +258,12 @@ Public Class frmMain End Sub + Private Sub RunImportBackup(ByVal oImportBackupList As Hashtable) + PauseScan() + oBackup.ImportBackupFiles(oImportBackupList) + ResumeScan() + End Sub + Private Function DoMultiGameCheck() As Boolean Dim oResult As DialogResult @@ -889,6 +895,11 @@ Public Class frmMain If frm.TriggerRestore Then RunRestore(frm.RestoreList) End If + + 'Handle import backup trigger + If frm.TriggerImportBackup Then + RunImportBackup(frm.ImportBackupList) + End If End Sub Private Sub OpenSettings() diff --git a/GBM/Forms/frmProcessManager.vb b/GBM/Forms/frmProcessManager.vb index cc56904..60a6d75 100644 --- a/GBM/Forms/frmProcessManager.vb +++ b/GBM/Forms/frmProcessManager.vb @@ -56,7 +56,7 @@ Public Class frmProcessManager End If sNewPath = mgrCommon.OpenFileBrowser("PM_Process", frmProcessManager_ChooseProcess, "exe", - frmProcessManager_Executable, sDefaultFolder, False, True) + frmProcessManager_Executable, sDefaultFolder, True) If sNewPath <> String.Empty Then txtPath.Text = sNewPath diff --git a/GBM/Managers/mgrBackup.vb b/GBM/Managers/mgrBackup.vb index 1163fcf..8d3eb30 100644 --- a/GBM/Managers/mgrBackup.vb +++ b/GBM/Managers/mgrBackup.vb @@ -42,7 +42,7 @@ Public Class mgrBackup 'Create manifest item oItem.MonitorID = oGameInfo.ID 'Keep the path relative to the manifest location - oItem.FileName = sBackupFile.Replace(Path.GetDirectoryName(mgrPath.RemoteDatabaseLocation) & Path.DirectorySeparatorChar, "") + oItem.FileName = sBackupFile.Replace(Settings.BackupFolder & Path.DirectorySeparatorChar, String.Empty) oItem.DateUpdated = dTimeStamp oItem.UpdatedBy = My.Computer.Name oItem.CheckSum = sCheckSum @@ -196,6 +196,60 @@ Public Class mgrBackup End If End Sub + Private Function BuildFileTimeStamp(ByVal dDate As Date) As String + Return " " & dDate.Month & "-" & dDate.Day & "-" & dDate.Year & "-" & dDate.Hour & "-" & dDate.Minute & "-" & dDate.Second + End Function + + Private Function HandleSubFolder(ByVal oGame As clsGame, ByVal sPath As String) As Boolean + Try + If Not Directory.Exists(sPath) Then + Directory.CreateDirectory(sPath) + End If + Catch ex As Exception + RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorSubFolderCreate, New String() {oGame.Name, ex.Message}), False, ToolTipIcon.Error, True) + Return False + End Try + + Return True + End Function + + Public Sub ImportBackupFiles(ByVal hshImportList As Hashtable) + Dim oGame As clsGame + Dim bContinue As Boolean = True + Dim sFileToImport As String + Dim sBackupFile As String + Dim oBackup As clsBackup + + For Each de As DictionaryEntry In hshImportList + sFileToImport = CStr(de.Key) + oGame = DirectCast(de.Value, clsGame) + If File.Exists(sFileToImport) Then + + sBackupFile = oSettings.BackupFolder + If oSettings.CreateSubFolder Then + sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) + bContinue = HandleSubFolder(oGame, sBackupFile) + End If + + If bContinue Then + oBackup = New clsBackup + oBackup.MonitorID = oGame.ID + oBackup.DateUpdated = File.GetLastWriteTime(sFileToImport) + oBackup.UpdatedBy = mgrBackup_ImportedFile + sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & BuildFileTimeStamp(oBackup.DateUpdated) & ".7z" + oBackup.FileName = sBackupFile.Replace(Settings.BackupFolder & Path.DirectorySeparatorChar, String.Empty) + If mgrCommon.CopyFile(sFileToImport, sBackupFile, False) Then + oBackup.CheckSum = mgrHash.Generate_SHA256_Hash(sBackupFile) + mgrManifest.DoManifestAdd(oBackup, mgrSQLite.Database.Remote) + RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ImportSuccess, New String() {sFileToImport, oGame.Name}), False, ToolTipIcon.Error, True) + Else + RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorImportBackupCopy, sFileToImport), False, ToolTipIcon.Error, True) + End If + End If + End If + Next + End Sub + Public Sub DoBackup(ByVal oBackupList As List(Of clsGame)) Dim oGame As clsGame Dim bDoBackup As Boolean @@ -213,7 +267,7 @@ Public Class mgrBackup sBackupFile = oSettings.BackupFolder sSavePath = String.Empty dTimeStamp = Date.Now - sTimeStamp = " " & dTimeStamp.Month & "-" & dTimeStamp.Day & "-" & dTimeStamp.Year & "-" & dTimeStamp.Hour & "-" & dTimeStamp.Minute & "-" & dTimeStamp.Second + sTimeStamp = BuildFileTimeStamp(dTimeStamp) sHash = String.Empty bDoBackup = True bBackupCompleted = False @@ -222,14 +276,7 @@ Public Class mgrBackup If oSettings.CreateSubFolder Then sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) - Try - If Not Directory.Exists(sBackupFile) Then - Directory.CreateDirectory(sBackupFile) - End If - Catch ex As Exception - RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorSubFolderCreate, New String() {oGame.Name, ex.Message}), False, ToolTipIcon.Error, True) - bDoBackup = False - End Try + bDoBackup = HandleSubFolder(oGame, sBackupFile) End If If oGame.AppendTimeStamp Then diff --git a/GBM/Managers/mgrCommon.vb b/GBM/Managers/mgrCommon.vb index 74a533e..e49592d 100644 --- a/GBM/Managers/mgrCommon.vb +++ b/GBM/Managers/mgrCommon.vb @@ -144,9 +144,9 @@ Public Class mgrCommon Return String.Empty End Function - Public Shared Function OpenFileBrowser(ByVal sName As String, ByVal sTitle As String, ByVal sExtension As String, ByVal sFileType As String, ByVal sDefaultFolder As String, - ByVal bMulti As Boolean, Optional ByVal bSavedPath As Boolean = True) As String - Dim fbBrowser As New OpenFileDialog + Private Shared Function BuildFileBrowser(ByVal sName As String, ByVal sTitle As String, ByVal sExtension As String, ByVal sFileType As String, ByVal sDefaultFolder As String, + ByVal bMulti As Boolean, ByRef fbBrowser As OpenFileDialog, Optional ByVal bSavedPath As Boolean = True) As Boolean + Dim oSavedPath As New clsSavedPath fbBrowser.Title = sTitle @@ -171,21 +171,40 @@ Public Class mgrCommon mgrSavedPath.AddUpdatePath(oSavedPath) End If - If bMulti Then - Dim sFileNames As String = String.Empty - For Each sFileName As String In fbBrowser.FileNames - sFileNames &= sFileName & "|" - Next - sFileNames = sFileNames.TrimEnd("|") - Return sFileNames - Else - Return fbBrowser.FileName - End If + Return True + End If + + Return False + End Function + + Public Shared Function OpenFileBrowser(ByVal sName As String, ByVal sTitle As String, ByVal sExtension As String, ByVal sFileType As String, ByVal sDefaultFolder As String, + Optional ByVal bSavedPath As Boolean = True) As String + Dim fbBrowser As New OpenFileDialog + Dim bResult As Boolean + + bResult = BuildFileBrowser(sName, sTitle, sExtension, sFileType, sDefaultFolder, False, fbBrowser, bSavedPath) + + If bResult Then + Return fbBrowser.FileName End If Return String.Empty End Function + Public Shared Function OpenMultiFileBrowser(ByVal sName As String, ByVal sTitle As String, ByVal sExtension As String, ByVal sFileType As String, ByVal sDefaultFolder As String, + Optional ByVal bSavedPath As Boolean = True) As String() + Dim fbBrowser As New OpenFileDialog + Dim bResult As Boolean + + bResult = BuildFileBrowser(sName, sTitle, sExtension, sFileType, sDefaultFolder, True, fbBrowser, bSavedPath) + + If bResult Then + Return fbBrowser.FileNames + End If + + Return New String() {} + End Function + Public Shared Function OpenFolderBrowser(ByVal sName As String, ByVal sTitle As String, ByVal sDefaultFolder As String, ByVal bEnableNewFolder As Boolean, Optional ByVal bSavedPath As Boolean = True) As String Dim fbBrowser As New FolderBrowserDialog @@ -415,6 +434,21 @@ Public Class mgrCommon End If End Function + 'Copy a file + Public Shared Function CopyFile(ByVal sSourcePath As String, ByVal sDestinationPath As String, ByVal bOverWrite As Boolean) As Boolean + Try + If File.Exists(sSourcePath) Then + File.Copy(sSourcePath, sDestinationPath, bOverWrite) + Else + Return False + End If + Catch + Return False + End Try + + Return True + End Function + 'Delete file based on OS type Public Shared Sub DeleteFile(ByVal sPath As String, Optional ByVal bRecycle As Boolean = True) If File.Exists(sPath) Then diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 90b5240..3fa755c 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -1410,6 +1410,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to 7-Zip. + ''' + Friend ReadOnly Property frmGameManager_7zBackup() As String + Get + Return ResourceManager.GetString("frmGameManager_7zBackup", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to [PARAM] ([PARAM]). ''' @@ -1554,6 +1563,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Import B&ackup Files. + ''' + Friend ReadOnly Property frmGameManager_btnImportBackup() As String + Get + Return ResourceManager.GetString("frmGameManager_btnImportBackup", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to In&clude Items.... ''' @@ -1689,6 +1707,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Choose compatible backup file(s). + ''' + Friend ReadOnly Property frmGameManager_Choose7zImport() As String + Get + Return ResourceManager.GetString("frmGameManager_Choose7zImport", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Choose a custom icon for the game. ''' @@ -1824,6 +1851,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Are you sure you want to import the selected file(s) for [PARAM]. This will close the form.. + ''' + Friend ReadOnly Property frmGameManager_ConfirmBackupImport() As String + Get + Return ResourceManager.GetString("frmGameManager_ConfirmBackupImport", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Are you sure you want to delete [PARAM]? This cannot be undone.[BR][BR]This will not delete any backup files that already exist for this game.. ''' @@ -5727,6 +5763,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Failed to import [PARAM], the file could not be copied.. + ''' + Friend ReadOnly Property mgrBackup_ErrorImportBackupCopy() As String + Get + Return ResourceManager.GetString("mgrBackup_ErrorImportBackupCopy", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Backup aborted by user due to manifest conflict.. ''' @@ -5773,7 +5818,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to Backup aborted. A failure occured while creating a backup sub-folder for [PARAM].[BR][PARAM]. + ''' Looks up a localized string similar to A failure occured while creating a backup sub-folder for [PARAM].[BR][PARAM]. ''' Friend ReadOnly Property mgrBackup_ErrorSubFolderCreate() As String Get @@ -5790,6 +5835,24 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Imported Backup. + ''' + Friend ReadOnly Property mgrBackup_ImportedFile() As String + Get + Return ResourceManager.GetString("mgrBackup_ImportedFile", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to Imported backup file [PARAM] for [PARAM].. + ''' + Friend ReadOnly Property mgrBackup_ImportSuccess() As String + Get + Return ResourceManager.GetString("mgrBackup_ImportSuccess", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Available Disk Space: [PARAM]. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index f3a1ed0..9eaed84 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -1307,7 +1307,7 @@ [PARAM] backup aborted by user due to overwrite. - Backup aborted. A failure occured while creating a backup sub-folder for [PARAM].[BR][PARAM] + A failure occured while creating a backup sub-folder for [PARAM].[BR][PARAM] Generating SHA-256 hash for [PARAM] backup file. @@ -2224,4 +2224,25 @@ Show resolved save paths + + 7-Zip + + + Import B&ackup Files + + + Choose compatible backup file(s) + + + Are you sure you want to import the selected file(s) for [PARAM]. This will close the form. + + + Failed to import [PARAM], the file could not be copied. + + + Imported Backup + + + Imported backup file [PARAM] for [PARAM]. + \ No newline at end of file From 0fcbfbe430900c450b643c9f4eaa5e97667633f6 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 8 Sep 2018 23:52:06 -0600 Subject: [PATCH 18/32] Minor form design fixes --- GBM/Forms/frmGameManager.Designer.vb | 46 ++++++++++++++-------------- GBM/Forms/frmGameManager.vb | 4 +++ GBM/Forms/frmSettings.Designer.vb | 22 ++++++------- GBM/My Project/Resources.Designer.vb | 15 +++++++-- GBM/My Project/Resources.resx | 9 ++++-- 5 files changed, 56 insertions(+), 40 deletions(-) diff --git a/GBM/Forms/frmGameManager.Designer.vb b/GBM/Forms/frmGameManager.Designer.vb index a437865..8bdc418 100644 --- a/GBM/Forms/frmGameManager.Designer.vb +++ b/GBM/Forms/frmGameManager.Designer.vb @@ -70,6 +70,7 @@ Partial Class frmGameManager Me.lblHours = New System.Windows.Forms.Label() Me.btnTags = New System.Windows.Forms.Button() Me.grpStats = New System.Windows.Forms.GroupBox() + Me.btnImportBackup = New System.Windows.Forms.Button() Me.cboRemoteBackup = New System.Windows.Forms.ComboBox() Me.lblRestorePathData = New System.Windows.Forms.Label() Me.lblBackupFileData = New System.Windows.Forms.Label() @@ -104,7 +105,6 @@ Partial Class frmGameManager Me.cmsDeleteAll = New System.Windows.Forms.ToolStripMenuItem() Me.btnProcesses = New System.Windows.Forms.Button() Me.ttFullPath = New System.Windows.Forms.ToolTip(Me.components) - Me.btnImportBackup = New System.Windows.Forms.Button() Me.grpConfig.SuspendLayout() CType(Me.nudLimit, System.ComponentModel.ISupportInitialize).BeginInit() Me.grpExtra.SuspendLayout() @@ -144,7 +144,7 @@ Partial Class frmGameManager Me.btnBackup.Location = New System.Drawing.Point(616, 626) Me.btnBackup.Name = "btnBackup" Me.btnBackup.Size = New System.Drawing.Size(75, 23) - Me.btnBackup.TabIndex = 18 + Me.btnBackup.TabIndex = 19 Me.btnBackup.Text = "&Backup" Me.btnBackup.UseVisualStyleBackColor = True ' @@ -154,7 +154,7 @@ Partial Class frmGameManager Me.btnClose.Location = New System.Drawing.Point(697, 626) Me.btnClose.Name = "btnClose" Me.btnClose.Size = New System.Drawing.Size(75, 23) - Me.btnClose.TabIndex = 19 + Me.btnClose.TabIndex = 20 Me.btnClose.Text = "C&lose" Me.btnClose.UseVisualStyleBackColor = True ' @@ -289,7 +289,7 @@ Partial Class frmGameManager Me.btnInclude.Name = "btnInclude" Me.btnInclude.Size = New System.Drawing.Size(175, 23) Me.btnInclude.TabIndex = 12 - Me.btnInclude.Text = "In&clude Items..." + Me.btnInclude.Text = "Incl&ude Items..." Me.btnInclude.UseVisualStyleBackColor = True ' 'txtID @@ -567,8 +567,8 @@ Partial Class frmGameManager Me.btnTags.Location = New System.Drawing.Point(535, 437) Me.btnTags.Name = "btnTags" Me.btnTags.Size = New System.Drawing.Size(75, 23) - Me.btnTags.TabIndex = 12 - Me.btnTags.Text = "Tags..." + Me.btnTags.TabIndex = 13 + Me.btnTags.Text = "&Tags..." Me.btnTags.UseVisualStyleBackColor = True ' 'grpStats @@ -589,10 +589,19 @@ Partial Class frmGameManager Me.grpStats.Location = New System.Drawing.Point(248, 466) Me.grpStats.Name = "grpStats" Me.grpStats.Size = New System.Drawing.Size(525, 154) - Me.grpStats.TabIndex = 15 + Me.grpStats.TabIndex = 16 Me.grpStats.TabStop = False Me.grpStats.Text = "Backup Information" ' + 'btnImportBackup + ' + Me.btnImportBackup.Location = New System.Drawing.Point(9, 125) + Me.btnImportBackup.Name = "btnImportBackup" + Me.btnImportBackup.Size = New System.Drawing.Size(114, 23) + Me.btnImportBackup.TabIndex = 8 + Me.btnImportBackup.Text = "Import B&ackup Files" + Me.btnImportBackup.UseVisualStyleBackColor = True + ' 'cboRemoteBackup ' Me.cboRemoteBackup.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList @@ -704,7 +713,7 @@ Partial Class frmGameManager Me.btnMarkAsRestored.Location = New System.Drawing.Point(429, 626) Me.btnMarkAsRestored.Name = "btnMarkAsRestored" Me.btnMarkAsRestored.Size = New System.Drawing.Size(100, 23) - Me.btnMarkAsRestored.TabIndex = 16 + Me.btnMarkAsRestored.TabIndex = 17 Me.btnMarkAsRestored.Text = "&Mark as Restored" Me.btnMarkAsRestored.UseVisualStyleBackColor = True ' @@ -714,7 +723,7 @@ Partial Class frmGameManager Me.btnRestore.Location = New System.Drawing.Point(535, 626) Me.btnRestore.Name = "btnRestore" Me.btnRestore.Size = New System.Drawing.Size(75, 23) - Me.btnRestore.TabIndex = 17 + Me.btnRestore.TabIndex = 18 Me.btnRestore.Text = "&Restore" Me.btnRestore.UseVisualStyleBackColor = True ' @@ -724,7 +733,7 @@ Partial Class frmGameManager Me.btnSave.Location = New System.Drawing.Point(616, 437) Me.btnSave.Name = "btnSave" Me.btnSave.Size = New System.Drawing.Size(75, 23) - Me.btnSave.TabIndex = 13 + Me.btnSave.TabIndex = 14 Me.btnSave.Text = "&Save" Me.btnSave.UseVisualStyleBackColor = True ' @@ -743,8 +752,8 @@ Partial Class frmGameManager Me.btnCancel.Location = New System.Drawing.Point(697, 437) Me.btnCancel.Name = "btnCancel" Me.btnCancel.Size = New System.Drawing.Size(75, 23) - Me.btnCancel.TabIndex = 14 - Me.btnCancel.Text = "&Cancel" + Me.btnCancel.TabIndex = 15 + Me.btnCancel.Text = "Ca&ncel" Me.btnCancel.UseVisualStyleBackColor = True ' 'chkEnabled @@ -891,8 +900,8 @@ Partial Class frmGameManager Me.btnProcesses.Location = New System.Drawing.Point(454, 437) Me.btnProcesses.Name = "btnProcesses" Me.btnProcesses.Size = New System.Drawing.Size(75, 23) - Me.btnProcesses.TabIndex = 20 - Me.btnProcesses.Text = "Processes..." + Me.btnProcesses.TabIndex = 12 + Me.btnProcesses.Text = "Pro&cesses..." Me.btnProcesses.UseVisualStyleBackColor = True ' 'ttFullPath @@ -901,15 +910,6 @@ Partial Class frmGameManager Me.ttFullPath.InitialDelay = 300 Me.ttFullPath.ReshowDelay = 60 ' - 'btnImportBackup - ' - Me.btnImportBackup.Location = New System.Drawing.Point(9, 125) - Me.btnImportBackup.Name = "btnImportBackup" - Me.btnImportBackup.Size = New System.Drawing.Size(114, 23) - Me.btnImportBackup.TabIndex = 8 - Me.btnImportBackup.Text = "Import B&ackup Files" - Me.btnImportBackup.UseVisualStyleBackColor = True - ' 'frmGameManager ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index dea6062..6bb27ba 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -1048,6 +1048,7 @@ Public Class frmGameManager btnBackup.Enabled = False btnMarkAsRestored.Enabled = False btnRestore.Enabled = False + btnImportBackup.Enabled = False btnDeleteBackup.Enabled = False btnOpenBackupFile.Enabled = False btnOpenRestorePath.Enabled = False @@ -1078,6 +1079,7 @@ Public Class frmGameManager btnBackup.Enabled = False btnMarkAsRestored.Enabled = False btnRestore.Enabled = False + btnImportBackup.Enabled = False btnDeleteBackup.Enabled = False btnOpenBackupFile.Enabled = False btnOpenRestorePath.Enabled = False @@ -1106,6 +1108,7 @@ Public Class frmGameManager lblTags.Visible = True btnImport.Enabled = True btnExport.Enabled = True + btnImportBackup.Enabled = True Case eModes.Disabled grpFilter.Enabled = True lstGames.Enabled = True @@ -1768,6 +1771,7 @@ Public Class frmGameManager chkRegEx.Text = frmGameManager_chkRegEx btnGameID.Text = frmGameManager_btnGameID btnImportBackup.Text = frmGameManager_btnImportBackup + btnProcesses.Text = frmGameManager_btnProcesses 'Init Filter Timer tmFilterTimer = New Timer() diff --git a/GBM/Forms/frmSettings.Designer.vb b/GBM/Forms/frmSettings.Designer.vb index fba3c43..1b21cb5 100644 --- a/GBM/Forms/frmSettings.Designer.vb +++ b/GBM/Forms/frmSettings.Designer.vb @@ -64,6 +64,7 @@ Partial Class frmSettings Me.grpLogOptions = New System.Windows.Forms.GroupBox() Me.chkDisableSyncMessages = New System.Windows.Forms.CheckBox() Me.grpGameData = New System.Windows.Forms.GroupBox() + Me.chkShowResolvedPaths = New System.Windows.Forms.CheckBox() Me.chkSessionTracking = New System.Windows.Forms.CheckBox() Me.lstSettings = New System.Windows.Forms.ListBox() Me.btnResetMessages = New System.Windows.Forms.Button() @@ -73,7 +74,6 @@ Partial Class frmSettings Me.chkStartWindows = New System.Windows.Forms.CheckBox() Me.chkStartToTray = New System.Windows.Forms.CheckBox() Me.chkMonitorOnStartup = New System.Windows.Forms.CheckBox() - Me.chkShowResolvedPaths = New System.Windows.Forms.CheckBox() Me.grpFolderOptions.SuspendLayout() Me.grp7zGeneral.SuspendLayout() Me.pnlBackup.SuspendLayout() @@ -512,6 +512,16 @@ Partial Class frmSettings Me.grpGameData.TabStop = False Me.grpGameData.Text = "Game Data Options" ' + 'chkShowResolvedPaths + ' + Me.chkShowResolvedPaths.AutoSize = True + Me.chkShowResolvedPaths.Location = New System.Drawing.Point(6, 65) + Me.chkShowResolvedPaths.Name = "chkShowResolvedPaths" + Me.chkShowResolvedPaths.Size = New System.Drawing.Size(154, 17) + Me.chkShowResolvedPaths.TabIndex = 2 + Me.chkShowResolvedPaths.Text = "Show resolved save paths " + Me.chkShowResolvedPaths.UseVisualStyleBackColor = True + ' 'chkSessionTracking ' Me.chkSessionTracking.AutoSize = True @@ -600,16 +610,6 @@ Partial Class frmSettings Me.chkMonitorOnStartup.Text = "Start monitoring on launch" Me.chkMonitorOnStartup.UseVisualStyleBackColor = True ' - 'chkShowResolvedPaths - ' - Me.chkShowResolvedPaths.AutoSize = True - Me.chkShowResolvedPaths.Location = New System.Drawing.Point(6, 65) - Me.chkShowResolvedPaths.Name = "chkShowResolvedPaths" - Me.chkShowResolvedPaths.Size = New System.Drawing.Size(154, 17) - Me.chkShowResolvedPaths.TabIndex = 3 - Me.chkShowResolvedPaths.Text = "Show resolved save paths " - Me.chkShowResolvedPaths.UseVisualStyleBackColor = True - ' 'frmSettings ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 3fa755c..6be4b02 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -1474,7 +1474,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to &Cancel. + ''' Looks up a localized string similar to Ca&ncel. ''' Friend ReadOnly Property frmGameManager_btnCancel() As String Get @@ -1573,7 +1573,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to In&clude Items.... + ''' Looks up a localized string similar to Incl&ude Items.... ''' Friend ReadOnly Property frmGameManager_btnInclude() As String Get @@ -1617,6 +1617,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Pro&cesses.... + ''' + Friend ReadOnly Property frmGameManager_btnProcesses() As String + Get + Return ResourceManager.GetString("frmGameManager_btnProcesses", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to &Restore. ''' @@ -1645,7 +1654,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to Tags.... + ''' Looks up a localized string similar to &Tags.... ''' Friend ReadOnly Property frmGameManager_btnTags() As String Get diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 9eaed84..a85b237 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -431,7 +431,7 @@ &Backup - &Cancel + Ca&ncel C&lose @@ -455,7 +455,7 @@ &Import - In&clude Items... + Incl&ude Items... &Mark as Restored @@ -479,7 +479,7 @@ ... - Tags... + &Tags... Monitor this game @@ -2245,4 +2245,7 @@ Imported backup file [PARAM] for [PARAM]. + + Pro&cesses... + \ No newline at end of file From c1b81585a01838580fd5133e0a19f61377129d47 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sun, 9 Sep 2018 09:11:58 -0600 Subject: [PATCH 19/32] Fixed Include button shortcut key --- GBM/My Project/Resources.Designer.vb | 2 +- GBM/My Project/Resources.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 6be4b02..96f0194 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -2203,7 +2203,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to In&clude. + ''' Looks up a localized string similar to Incl&ude. ''' Friend ReadOnly Property frmGameManager_IncludeShortcut() As String Get diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index a85b237..8fc2c07 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -590,7 +590,7 @@ Include - In&clude + Incl&ude Items... From 7a4caab5a546be4b1e7526adfa322f18e634097c Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sun, 9 Sep 2018 11:04:02 -0600 Subject: [PATCH 20/32] FIxed broken custom variable feature --- GBM/Managers/mgrPath.vb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 5bf13ae..3eff9e3 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -341,6 +341,13 @@ Public Class mgrPath Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Dim sHomeDir As String = "${HOME}" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + Dim oCustomVariable As clsPathVariable + + For Each oCustomVariable In hshCustomVariables.Values + If sValue.Contains(oCustomVariable.FormattedName) Then + Return sValue.Replace(oCustomVariable.FormattedName, oCustomVariable.Path) + End If + Next If mgrCommon.IsUnix Then '$VAR_iable From 0f800565fe1e59ac0b2c5a325a18f3e79270c2d4 Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sun, 9 Sep 2018 11:34:25 -0600 Subject: [PATCH 21/32] Added one-time warning for #150 --- GBM/Forms/frmGameManager.vb | 7 +++++++ GBM/Managers/mgrSettings.vb | 1 + GBM/My Project/Resources.Designer.vb | 9 +++++++++ GBM/My Project/Resources.resx | 3 +++ 4 files changed, 20 insertions(+) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 6bb27ba..d11137b 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -1553,6 +1553,13 @@ Public Class frmGameManager Dim sFile As String Dim sFiles As String() + 'Show one time warning + If Not (oSettings.SuppressMessages And mgrSettings.eSuppressMessages.BackupImport) = mgrSettings.eSuppressMessages.BackupImport Then + mgrCommon.ShowMessage(frmGameManager_WarningImportBackup, MsgBoxStyle.Information) + oSettings.SuppressMessages = oSettings.SetMessageField(oSettings.SuppressMessages, mgrSettings.eSuppressMessages.BackupImport) + oSettings.SaveSettings() + End If + ImportBackupList.Clear() sFiles = mgrCommon.OpenMultiFileBrowser("GM_ImportBackup", frmGameManager_Choose7zImport, "7z", diff --git a/GBM/Managers/mgrSettings.vb b/GBM/Managers/mgrSettings.vb index c4c6311..2366a4d 100644 --- a/GBM/Managers/mgrSettings.vb +++ b/GBM/Managers/mgrSettings.vb @@ -30,6 +30,7 @@ Public Class mgrSettings Public Enum eSuppressMessages None = 0 GameIDSync = 1 + BackupImport = 2 End Enum Property StartWithWindows As Boolean diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 96f0194..367cd36 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -2445,6 +2445,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or other compatible archives that were created using the same settings as the current game configuration.[BR][BR]This message will only be shown once.. + ''' + Friend ReadOnly Property frmGameManager_WarningImportBackup() As String + Get + Return ResourceManager.GetString("frmGameManager_WarningImportBackup", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to XML. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 8fc2c07..a4b39cb 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2248,4 +2248,7 @@ Pro&cesses... + + This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or other compatible archives that were created using the same settings as the current game configuration.[BR][BR]This message will only be shown once. + \ No newline at end of file From ace287f42a3ce2c8206175769756342bbeb1a3cc Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 09:01:56 -0600 Subject: [PATCH 22/32] Fixed restore path display issue with multiple backups for #152 --- GBM/Forms/frmGameManager.vb | 69 ++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index d11137b..3ea59db 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -712,25 +712,6 @@ Public Class frmGameManager End Sub - Private Sub UpdateBackupInfo(ByVal sManifestID As String) - Dim sFileName As String - - If sManifestID <> String.Empty Then - CurrentBackupItem = mgrManifest.DoManifestGetByManifestID(sManifestID, mgrSQLite.Database.Remote) - - sFileName = BackupFolder & CurrentBackupItem.FileName - - If File.Exists(sFileName) Then - lblBackupFileData.Text = Path.GetFileName(CurrentBackupItem.FileName) & " (" & mgrCommon.FormatDiskSpace(mgrCommon.GetFileSize(sFileName)) & ")" - Else - lblBackupFileData.Text = frmGameManager_ErrorNoBackupExists - End If - - lblRestorePathData.Text = CurrentBackupItem.RestorePath - End If - - End Sub - Public Sub VerifyBackups(ByVal oApp As clsGame) Dim oCurrentBackup As clsBackup Dim oCurrentBackups As List(Of clsBackup) @@ -761,6 +742,23 @@ Public Class frmGameManager Cursor.Current = Cursors.Default End Sub + Private Sub SetBackupRestorePath(ByVal oApp As clsGame) + Dim sttRestorePath As String + + If Not CurrentBackupItem.AbsolutePath And oApp.ProcessPath <> String.Empty Then + lblRestorePathData.Text = oApp.ProcessPath & Path.DirectorySeparatorChar & CurrentBackupItem.RestorePath + Else + If oSettings.ShowResolvedPaths Then + lblRestorePathData.Text = CurrentBackupItem.RestorePath + sttRestorePath = CurrentBackupItem.TruePath + Else + lblRestorePathData.Text = CurrentBackupItem.TruePath + sttRestorePath = CurrentBackupItem.RestorePath + End If + If CurrentBackupItem.AbsolutePath Then ttFullPath.SetToolTip(lblRestorePathData, sttRestorePath) + End If + End Sub + Private Sub GetBackupInfo(ByVal oApp As clsGame) Dim oBackupInfo As clsBackup Dim oCurrentBackup As clsBackup @@ -769,7 +767,7 @@ Public Class frmGameManager Dim oComboItems As New List(Of KeyValuePair(Of String, String)) Dim bLocalData As Boolean = False Dim bRemoteData As Boolean = False - Dim sttRestorePath As String + 'cboRemoteBackup cboRemoteBackup.ValueMember = "Key" @@ -798,18 +796,7 @@ Public Class frmGameManager lblBackupFileData.Text = frmGameManager_ErrorNoBackupExists End If - If Not CurrentBackupItem.AbsolutePath And oApp.ProcessPath <> String.Empty Then - lblRestorePathData.Text = oApp.ProcessPath & Path.DirectorySeparatorChar & CurrentBackupItem.RestorePath - Else - If oSettings.ShowResolvedPaths Then - lblRestorePathData.Text = CurrentBackupItem.RestorePath - sttRestorePath = CurrentBackupItem.TruePath - Else - lblRestorePathData.Text = CurrentBackupItem.TruePath - sttRestorePath = CurrentBackupItem.RestorePath - End If - If CurrentBackupItem.AbsolutePath Then ttFullPath.SetToolTip(lblRestorePathData, sttRestorePath) - End If + SetBackupRestorePath(oApp) Else oComboItems.Add(New KeyValuePair(Of String, String)(String.Empty, frmGameManager_None)) lblBackupFileData.Text = String.Empty @@ -846,6 +833,24 @@ Public Class frmGameManager End Sub + Private Sub UpdateBackupInfo(ByVal sManifestID As String) + Dim sFileName As String + + If sManifestID <> String.Empty Then + CurrentBackupItem = mgrManifest.DoManifestGetByManifestID(sManifestID, mgrSQLite.Database.Remote) + + sFileName = BackupFolder & CurrentBackupItem.FileName + + If File.Exists(sFileName) Then + lblBackupFileData.Text = Path.GetFileName(CurrentBackupItem.FileName) & " (" & mgrCommon.FormatDiskSpace(mgrCommon.GetFileSize(sFileName)) & ")" + Else + lblBackupFileData.Text = frmGameManager_ErrorNoBackupExists + End If + + SetBackupRestorePath(CurrentGame) + End If + End Sub + Private Sub DeleteAllBackups() Dim oBackupData As List(Of clsBackup) Dim oBackup As clsBackup From 333f7ac36ace90d60335a2440b86e66e4e19a999 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 09:50:24 -0600 Subject: [PATCH 23/32] Prevent use of reserved variable names for custom variables for #148 and #152 --- GBM/Forms/frmVariableManager.vb | 6 ++++++ GBM/Managers/mgrPath.vb | 4 +++- GBM/Managers/mgrVariables.vb | 12 ++++++++++++ GBM/My Project/Resources.Designer.vb | 9 +++++++++ GBM/My Project/Resources.resx | 3 +++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/GBM/Forms/frmVariableManager.vb b/GBM/Forms/frmVariableManager.vb index da90901..a3d18d9 100644 --- a/GBM/Forms/frmVariableManager.vb +++ b/GBM/Forms/frmVariableManager.vb @@ -289,6 +289,12 @@ Public Class frmVariableManager Return False End If + If mgrVariables.GetReservedVariables.Contains(txtName.Text.ToUpper) Then + mgrCommon.ShowMessage(frmVariableManager_ErrorVariableReserved, txtName.Text, MsgBoxStyle.Exclamation) + txtName.Focus() + Return False + End If + Return True End Function diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 3eff9e3..d3c371e 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -501,6 +501,8 @@ Public Class mgrPath Public Shared Function VerifyCustomVariables(ByVal hshScanlist As Hashtable, ByRef sGames As String) As Boolean Dim hshCustomVariables As Hashtable = mgrVariables.ReadVariables + 'Reserved variables will be resolved on Windows, but not on a Linux. Therefore we an ignore list here, otherwise GBM will bitch about them when using Windows configurations for Wine. + Dim oReservedVariables As List(Of String) = mgrVariables.GetReservedVariables Dim sVariableCheck As String Dim sPattern As String = "\%(.*)\%" Dim oGame As clsGame @@ -511,7 +513,7 @@ Public Class mgrPath oMatch = Regex.Match(oGame.Path, sPattern) If oMatch.Success Then sVariableCheck = oMatch.Value.Replace("%", String.Empty) - If Not hshCustomVariables.ContainsKey(sVariableCheck) Then + If Not hshCustomVariables.ContainsKey(sVariableCheck) And Not oReservedVariables.Contains(sVariableCheck) Then sGames &= vbCrLf & oGame.Name & " (" & sVariableCheck & ")" bClean = False End If diff --git a/GBM/Managers/mgrVariables.vb b/GBM/Managers/mgrVariables.vb index 04613a9..72befd2 100644 --- a/GBM/Managers/mgrVariables.vb +++ b/GBM/Managers/mgrVariables.vb @@ -154,4 +154,16 @@ Return hshList End Function + + Public Shared Function GetReservedVariables() As List(Of String) + Dim oList As New List(Of String) + + oList.Add("APPDATA") + oList.Add("LOCALAPPDATA") + oList.Add("USERDOCUMENTS") + oList.Add("COMMONDOCUMENTS") + oList.Add("USERPROFILE") + + Return oList + End Function End Class diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 367cd36..c41fcd1 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -5442,6 +5442,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to [PARAM] is a reserved variable, you must enter a different name.. + ''' + Friend ReadOnly Property frmVariableManager_ErrorVariableReserved() As String + Get + Return ResourceManager.GetString("frmVariableManager_ErrorVariableReserved", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Custom Variable Manager. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index a4b39cb..c4bff63 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2251,4 +2251,7 @@ This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or other compatible archives that were created using the same settings as the current game configuration.[BR][BR]This message will only be shown once. + + [PARAM] is a reserved variable, you must enter a different name. + \ No newline at end of file From 898e72f163d1202b60c5a034cd81cee8d52b2d96 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 11:46:20 -0600 Subject: [PATCH 24/32] Restricted backup import functionality for #150 --- GBM/Forms/frmGameManager.vb | 6 +++++- GBM/My Project/Resources.Designer.vb | 11 ++++++++++- GBM/My Project/Resources.resx | 5 ++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 3ea59db..59d59bd 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -1938,7 +1938,11 @@ Public Class frmGameManager End Sub Private Sub btnImportBackup_Click(sender As Object, e As EventArgs) Handles btnImportBackup.Click - TriggerSelectedImportBackup() + If CurrentGame.AppendTimeStamp Then + TriggerSelectedImportBackup() + Else + mgrCommon.ShowMessage(frmGameManager_WarningImportBackupSaveMulti, MsgBoxStyle.Information) + End If End Sub Private Sub chkFolderSave_CheckedChanged(sender As Object, e As EventArgs) Handles chkFolderSave.CheckedChanged diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index c41fcd1..f08f3bb 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -2446,7 +2446,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or other compatible archives that were created using the same settings as the current game configuration.[BR][BR]This message will only be shown once.. + ''' Looks up a localized string similar to This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or compatible archives created using the same settings as the current game configuration.[BR][BR]This message will only be shown once.. ''' Friend ReadOnly Property frmGameManager_WarningImportBackup() As String Get @@ -2454,6 +2454,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to The "Save multiple backups" option must be enabled on this configuration to import backup files.. + ''' + Friend ReadOnly Property frmGameManager_WarningImportBackupSaveMulti() As String + Get + Return ResourceManager.GetString("frmGameManager_WarningImportBackupSaveMulti", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to XML. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index c4bff63..476214d 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2249,9 +2249,12 @@ Pro&cesses... - This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or other compatible archives that were created using the same settings as the current game configuration.[BR][BR]This message will only be shown once. + This feature is intended to import 7-Zip backup archives compatible with the selected game configuration.[BR][BR]GBM does NOT verify these files, you should only use files created by GBM or compatible archives created using the same settings as the current game configuration.[BR][BR]This message will only be shown once. [PARAM] is a reserved variable, you must enter a different name. + + The "Save multiple backups" option must be enabled on this configuration to import backup files. + \ No newline at end of file From c7e3e62ce1e8b9f429f3ddda49d2d6cda40ce756 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 12:33:14 -0600 Subject: [PATCH 25/32] Fix Windows save path detection for #148 --- GBM/Forms/frmMain.vb | 5 +++-- GBM/Managers/mgrVariables.vb | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb index f839c58..ca0be18 100644 --- a/GBM/Forms/frmMain.vb +++ b/GBM/Forms/frmMain.vb @@ -1927,8 +1927,8 @@ Public Class frmMain 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 + 'Attempt a path conversion if the game configuration is using an absolute windows path that we can convert + If mgrVariables.CheckForReservedVariables(oProcess.GameInfo.TruePath) Then Dim sWinePrefix As String = mgrPath.GetWinePrefix(oProcess.FoundProcess) Dim sWineSavePath As String If Not sWinePrefix = String.Empty Then @@ -1936,6 +1936,7 @@ Public Class frmMain sWineSavePath = mgrPath.GetWineSavePath(sWinePrefix, oProcess.GameInfo.TruePath) If Not sWineSavePath = oProcess.GameInfo.TruePath Then oProcess.GameInfo.TruePath = sWineSavePath + oProcess.GameInfo.AbsolutePath = True UpdateLog(mgrCommon.FormatString(frmMain_WineSavePath, New String() {oProcess.GameInfo.Name, sWineSavePath}), False) End If End If diff --git a/GBM/Managers/mgrVariables.vb b/GBM/Managers/mgrVariables.vb index 72befd2..2198cbd 100644 --- a/GBM/Managers/mgrVariables.vb +++ b/GBM/Managers/mgrVariables.vb @@ -166,4 +166,17 @@ Return oList End Function + + Public Shared Function CheckForReservedVariables(ByVal sPath As String) As Boolean + Dim s As String + + For Each s In GetReservedVariables() + s = "%" & s & "%" + If sPath.Contains(s) Then + Return True + End If + Next + + Return False + End Function End Class From 854d2ed53774ea626f8551215399bf8e0278122a Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 12:43:57 -0600 Subject: [PATCH 26/32] Changed wine save path detection for #148 --- GBM/Managers/mgrPath.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index d3c371e..e736f2e 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -258,7 +258,7 @@ Public Class mgrPath ElseIf sPath.Contains("%USERPROFILE%") Then sReplace = "%USERPROFILE%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") - oParse = New Regex("""Personal""="".+?(?=\\\\My Documents)") + oParse = New Regex("""Desktop""="".+?(?=\\\\Desktop)") Else Return sPath End If From e325678e766b5d72376a03d4ec374dd2d5081da8 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Fri, 14 Sep 2018 14:41:54 -0600 Subject: [PATCH 27/32] Handle LocalLow save locations for #148 --- GBM/Managers/mgrPath.vb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index e736f2e..d6e03e9 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -239,14 +239,18 @@ Public Class mgrPath Dim oMatch As Match Try - If sPath.Contains("%LOCALAPPDATA%") Then - sReplace = "%LOCALAPPDATA%" - sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") - oParse = New Regex("""Local AppData""="".+?(?=\n)") - ElseIf sPath.Contains("%APPDATA%") Then + If sPath.Contains("%APPDATA%") Then sReplace = "%APPDATA%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") oParse = New Regex("""AppData""="".+?(?=\n)") + ElseIf sPath.Contains("%LOCALAPPDATA%Low") Then + sReplace = "%LOCALAPPDATA%Low" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""{A520A1A4-1780-4FF6-BD18-167343C5AF16}""="".+?(?=\n)") + ElseIf sPath.Contains("%LOCALAPPDATA%") Then + sReplace = "%LOCALAPPDATA%" + sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") + oParse = New Regex("""Local AppData""="".+?(?=\n)") ElseIf sPath.Contains("%USERDOCUMENTS%") Then sReplace = "%USERDOCUMENTS%" sRegistry = File.ReadAllText(sPrefix & Path.DirectorySeparatorChar & "user.reg") From f659edff6425a987b7b1724dd54dab3f27730ffb Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Sat, 22 Sep 2018 11:15:32 -0600 Subject: [PATCH 28/32] Updated readme.txt with current changes --- GBM/readme.txt | 61 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/GBM/readme.txt b/GBM/readme.txt index e5b5f9b..a618210 100644 --- a/GBM/readme.txt +++ b/GBM/readme.txt @@ -1,25 +1,58 @@ -Game Backup Monitor v1.1.4 Readme +Game Backup Monitor v1.1.5 Readme http://mikemaximus.github.io/gbm-web/ gamebackupmonitor@gmail.com -August 25th, 2018 +October 1st, 2018 -New in 1.1.4 +New in 1.1.5 All Platforms: -- Changed method of handling required OS environment paths and added a new path check on startup. -- Incorrect conflict warnings will no longer be shown in some situations when running a backup configuration with "Save Multiple Backups" enabled. -- Fixed the precision of "Total Hours" on the Session Viewer, it now always rounds to 2 decimal places. - -Windows: - -- GBM will no longer keep an open file handle on detected processes and custom icons. - +- Fixed a crash that could occur when renaming a game configuration. +- Rewrote portions of game detection: + - The handling of duplicate game configurations has been flawed since regular expression support was added in v1.1. This has been fixed. + - GBM is now more efficient when detecting games by parameter and/or process path. +- Changed how save path variables are handled: + - GBM no longer uses it's own format and naming scheme for path variables. + - GBM now uses Windows environment variables in game configurations. + - For example, *appdatalocal* is now %LOCALAPPDATA% in a Windows configuration. + - GBM also uses some custom environment variables, such as %USERDOCUMENTS% and %COMMONDOCUMENTS%. These are needed for compatability and to handle some limitations with how GBM interacts with 7-Zip. + - GBM now uses the XDG specification for game configurations in Linux. (Thanks basxto!) + - For example, *appdatalocal* is now ${XDG_DATA_HOME:-~/.local/share} in a Linux configuration. + - Custom Path Variables have changed. For example, *Steam User Data* will now be %Steam User Data%. + - They will appear this way in Windows and Linux. + - GBM will no longer allow the creation of variables using reserved names, such as APPDATA. + - Your configurations will be automatically updated to these new formats when upgrading to v1.1.5. + - These changes will break game list compatability with other versions of GBM. Archived lists are available at http://mikemaximus.github.io/gbm-web/archive.html for those that wish to stay on an older version. +- Added a new setting, "Show resolved save paths". + - This new setting is enabled by default. + - When enabled, GBM will display resolved save paths on the Game Manager. This is how GBM displayed paths prior to v1.1.5. + - When disabled, GBM will display save paths with their variables when applicable. +- Added a tooltip to applicable "Path" fields on the Game Manager. + - This tooltip either displays either a resolved or unresolved path. + - The behaviour is toggled by the "Show resolved save paths" setting. +-Added "Import Backup Files" feature to the Game Manager. + - This feature allows you to import one or more backup files for a specific game configuration. + - This is useful if you lost your GBM database(s), but not the backup files. It also can be used to easily move compatible saved game backups between Windows and Linux. + - GBM cannot verify that the backups being imported are compatible with the current configuration. This is up to the user! + - This feature will be expanded and refined in future releases. + Linux: -- Sorting by "Hours" in the Session Viewer will no longer crash GBM on certain systems. -- GBM no longer attempts to get icons from a Linux binary. -- Removed compression from GBM icon to prevent issues with recent versions of imagemagick. +- Fixed an issue that prevented Wine / Proton games from being detected in some cases. +- GBM can now use any Windows configuration to detect and backup games running in Wine / Proton. + - An absolute Windows save path, such "%APPDATA%\Game\Saved Games" will be automatically converted to the proper path within the detected Wine prefix. + - The converted path will be saved to the configuration once game has been detected at least once. + - You cannot restore a backup using an absolute Windows path. The game needs to be detected at least once so the correct save path can be determined. + - This feature should be considered "Beta" and may not work in all scenarios. Please report any issues you may encounter! + +Website: + +- Search features have been added to the Official Game Lists (Thanks basxto!) + - Includes advanced features such as searching by tag and excludes. + - Tags are now clickable for automatic searching of similar games. + - Searches are linkable. + - You can now link directly to a single configuration using the new link icon. + - Configurations intelligently collapse or uncollapse based on search results. The entire version history of GBM releases is available at http://mikemaximus.github.io/gbm-web/versionhistory.html \ No newline at end of file From cb49434a469a04a8fda9240f84e0813c0552915b Mon Sep 17 00:00:00 2001 From: MikeMaximus Date: Fri, 28 Sep 2018 10:34:48 -0600 Subject: [PATCH 29/32] Allow importing official Windows configurations in Linux for #148 --- GBM/Forms/frmGameManager.Designer.vb | 17 ++++++++++++ GBM/Forms/frmGameManager.vb | 40 +++++++++++++++++++--------- GBM/Managers/mgrSettings.vb | 1 + GBM/My Project/Resources.Designer.vb | 27 +++++++++++++++++++ GBM/My Project/Resources.resx | 9 +++++++ 5 files changed, 82 insertions(+), 12 deletions(-) diff --git a/GBM/Forms/frmGameManager.Designer.vb b/GBM/Forms/frmGameManager.Designer.vb index 8bdc418..2b5f370 100644 --- a/GBM/Forms/frmGameManager.Designer.vb +++ b/GBM/Forms/frmGameManager.Designer.vb @@ -97,6 +97,8 @@ Partial Class frmGameManager Me.btnExport = New System.Windows.Forms.Button() Me.cmsImport = New System.Windows.Forms.ContextMenuStrip(Me.components) Me.cmsOfficial = New System.Windows.Forms.ToolStripMenuItem() + Me.cmsOfficialWindows = New System.Windows.Forms.ToolStripMenuItem() + Me.cmsOfficialLinux = New System.Windows.Forms.ToolStripMenuItem() Me.cmsFile = New System.Windows.Forms.ToolStripMenuItem() Me.txtQuickFilter = New System.Windows.Forms.TextBox() Me.lblQuickFilter = New System.Windows.Forms.Label() @@ -850,10 +852,23 @@ Partial Class frmGameManager ' 'cmsOfficial ' + Me.cmsOfficial.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.cmsOfficialWindows, Me.cmsOfficialLinux}) Me.cmsOfficial.Name = "cmsOfficial" Me.cmsOfficial.Size = New System.Drawing.Size(117, 22) Me.cmsOfficial.Text = "&Official List..." ' + 'cmsOfficialWindows + ' + Me.cmsOfficialWindows.Name = "cmsOfficialWindows" + Me.cmsOfficialWindows.Size = New System.Drawing.Size(180, 22) + Me.cmsOfficialWindows.Text = "&Windows..." + ' + 'cmsOfficialLinux + ' + Me.cmsOfficialLinux.Name = "cmsOfficialLinux" + Me.cmsOfficialLinux.Size = New System.Drawing.Size(180, 22) + Me.cmsOfficialLinux.Text = "&Linux..." + ' 'cmsFile ' Me.cmsFile.Name = "cmsFile" @@ -1042,4 +1057,6 @@ Partial Class frmGameManager Friend WithEvents btnProcesses As Button Friend WithEvents ttFullPath As ToolTip Friend WithEvents btnImportBackup As Button + Friend WithEvents cmsOfficialWindows As ToolStripMenuItem + Friend WithEvents cmsOfficialLinux As ToolStripMenuItem End Class diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 59d59bd..913ca68 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -1704,17 +1704,9 @@ Public Class frmGameManager End Sub - Private Sub ImportOfficialGameList() - Dim sImportURL As String - - If mgrCommon.IsUnix Then - sImportURL = App_URLImportLinux - Else - sImportURL = App_URLImport - End If - + Private Sub ImportOfficialGameList(ByVal sImportUrl As String) If mgrCommon.ShowMessage(frmGameManager_ConfirmOfficialImport, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then - If mgrMonitorList.DoImport(sImportURL, True, Settings) Then + If mgrMonitorList.DoImport(sImportUrl, True, Settings) Then mgrMonitorList.SyncMonitorLists(Settings) LoadData() LoadBackupData() @@ -1774,6 +1766,8 @@ Public Class frmGameManager btnDelete.Text = frmGameManager_btnDelete btnAdd.Text = frmGameManager_btnAdd cmsOfficial.Text = frmGameManager_cmsOfficial + cmsOfficialLinux.Text = frmGameManager_cmsOfficialLinux + cmsOfficialWindows.Text = frmGameManager_cmsOfficialWindows cmsFile.Text = frmGameManager_cmsFile lblQuickFilter.Text = frmGameManager_lblQuickFilter lblLimit.Text = frmGameManager_lblLimit @@ -1785,6 +1779,15 @@ Public Class frmGameManager btnImportBackup.Text = frmGameManager_btnImportBackup btnProcesses.Text = frmGameManager_btnProcesses + 'Init Official Import Menu + If mgrCommon.IsUnix Then + cmsOfficial.Text = cmsOfficial.Text.TrimEnd(".") + RemoveHandler cmsOfficial.Click, AddressOf cmsOfficialWindows_Click + Else + cmsOfficialLinux.Visible = False + cmsOfficialWindows.Visible = False + End If + 'Init Filter Timer tmFilterTimer = New Timer() tmFilterTimer.Interval = 1000 @@ -1967,8 +1970,21 @@ Public Class frmGameManager cmsImport.Show(btnImport, New Drawing.Point(btnImport.Size.Width - Math.Floor(btnImport.Size.Width * 0.1), btnImport.Size.Height - Math.Floor(btnImport.Size.Height * 0.5)), ToolStripDropDownDirection.AboveRight) End Sub - Private Sub cmsOfficial_Click(sender As Object, e As EventArgs) Handles cmsOfficial.Click - ImportOfficialGameList() + Private Sub cmsOfficialWindows_Click(sender As Object, e As EventArgs) Handles cmsOfficialWindows.Click, cmsOfficial.Click + 'Show one time warning about Windows configs in Linux + If mgrCommon.IsUnix Then + If Not (oSettings.SuppressMessages And mgrSettings.eSuppressMessages.WinConfigsInLinux) = mgrSettings.eSuppressMessages.WinConfigsInLinux Then + mgrCommon.ShowMessage(frmGameManager_WarningWinConfigsInLinux, MsgBoxStyle.Information) + oSettings.SuppressMessages = oSettings.SetMessageField(oSettings.SuppressMessages, mgrSettings.eSuppressMessages.WinConfigsInLinux) + oSettings.SaveSettings() + End If + End If + + ImportOfficialGameList(App_URLImport) + End Sub + + Private Sub cmsOfficialLinux_Click(sender As Object, e As EventArgs) Handles cmsOfficialLinux.Click + ImportOfficialGameList(App_URLImportLinux) End Sub Private Sub cmsFile_Click(sender As Object, e As EventArgs) Handles cmsFile.Click diff --git a/GBM/Managers/mgrSettings.vb b/GBM/Managers/mgrSettings.vb index 2366a4d..a11ec1a 100644 --- a/GBM/Managers/mgrSettings.vb +++ b/GBM/Managers/mgrSettings.vb @@ -31,6 +31,7 @@ Public Class mgrSettings None = 0 GameIDSync = 1 BackupImport = 2 + WinConfigsInLinux = 4 End Enum Property StartWithWindows As Boolean diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index f08f3bb..5a8ea62 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -1815,6 +1815,24 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to &Linux.... + ''' + Friend ReadOnly Property frmGameManager_cmsOfficialLinux() As String + Get + Return ResourceManager.GetString("frmGameManager_cmsOfficialLinux", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to &Windows.... + ''' + Friend ReadOnly Property frmGameManager_cmsOfficialWindows() As String + Get + Return ResourceManager.GetString("frmGameManager_cmsOfficialWindows", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Are you sure you want to run a backup for [PARAM]? This will close the form.. ''' @@ -2463,6 +2481,15 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized string similar to Official Windows configurations can be used in Linux for games running in Wine or Proton.[BR][BR]You do not need to modify these configurations, GBM will automatically do any required path conversions the first time the game is detected.[BR][BR]This message will only be shown once.. + ''' + Friend ReadOnly Property frmGameManager_WarningWinConfigsInLinux() As String + Get + Return ResourceManager.GetString("frmGameManager_WarningWinConfigsInLinux", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to XML. ''' diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 476214d..2b1fd1d 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2257,4 +2257,13 @@ The "Save multiple backups" option must be enabled on this configuration to import backup files. + + &Linux... + + + &Windows... + + + Official Windows configurations can be used in Linux for games running in Wine or Proton.[BR][BR]You do not need to modify these configurations, GBM will automatically do any required path conversions the first time the game is detected.[BR][BR]This message will only be shown once. + \ No newline at end of file From 8d82b2efd37efef5f2de341967ab65450d484448 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Sun, 30 Sep 2018 13:37:58 -0600 Subject: [PATCH 30/32] Updated import version warning --- GBM/Managers/mgrMonitorList.vb | 2 +- GBM/My Project/Resources.Designer.vb | 2 +- GBM/My Project/Resources.resx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GBM/Managers/mgrMonitorList.vb b/GBM/Managers/mgrMonitorList.vb index 28096b3..232cc80 100644 --- a/GBM/Managers/mgrMonitorList.vb +++ b/GBM/Managers/mgrMonitorList.vb @@ -826,7 +826,7 @@ Public Class mgrMonitorList Exit Sub End If - If oExportInfo.AppVer < 110 Then + If oExportInfo.AppVer < 115 Then If mgrCommon.ShowMessage(mgrMonitorList_ImportVersionWarning, MsgBoxStyle.YesNo) = MsgBoxResult.No Then Exit Sub End If diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb index 5a8ea62..b409610 100644 --- a/GBM/My Project/Resources.Designer.vb +++ b/GBM/My Project/Resources.Designer.vb @@ -6133,7 +6133,7 @@ Namespace My.Resources End Property ''' - ''' Looks up a localized string similar to This export file was created with a version of GBM prior to 1.1.0 and does not contain unique game identifiers.[BR][BR]Do you still want to import configurations from this file? (Not Recommended). + ''' Looks up a localized string similar to This export file was created with a version of GBM prior to 1.1.5 and may contain incompatible configuration data.[BR][BR]Do you still want to import configurations from this file? (Not Recommended). ''' Friend ReadOnly Property mgrMonitorList_ImportVersionWarning() As String Get diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx index 2b1fd1d..7ab3bcf 100644 --- a/GBM/My Project/Resources.resx +++ b/GBM/My Project/Resources.resx @@ -2027,7 +2027,7 @@ This file cannot be used to sync game indentifiers. It was created with an older version of GBM. - This export file was created with a version of GBM prior to 1.1.0 and does not contain unique game identifiers.[BR][BR]Do you still want to import configurations from this file? (Not Recommended) + This export file was created with a version of GBM prior to 1.1.5 and may contain incompatible configuration data.[BR][BR]Do you still want to import configurations from this file? (Not Recommended) Do you want to sync your game identifiers with this export file?[BR][BR]You should only do this if you're managing your own game configurations. If you use GBM on multiple PCs, please see "Tools" section of the online manual before using this feature. From f9b325ae6784b641046c36fe1d767dc3906f0afc Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Sun, 30 Sep 2018 14:58:53 -0600 Subject: [PATCH 31/32] Import tag mods for #148 --- GBM/Forms/frmAdvancedImport.vb | 79 ++++++++++++++++++++++++++++++++++ GBM/Forms/frmGameManager.vb | 10 +++-- GBM/Managers/mgrMonitorList.vb | 9 ++-- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/GBM/Forms/frmAdvancedImport.vb b/GBM/Forms/frmAdvancedImport.vb index c6a6d35..60d0a6b 100644 --- a/GBM/Forms/frmAdvancedImport.vb +++ b/GBM/Forms/frmAdvancedImport.vb @@ -6,6 +6,7 @@ Public Class frmAdvancedImport Private oImportData As ExportData Private hshImportData As Hashtable Private hshFinalData As New Hashtable + Private bModWinConfigsForLinux As Boolean Private bSelectAll As Boolean = True Private bIsLoading As Boolean = False Private iCurrentSort As Integer = 0 @@ -30,12 +31,23 @@ Public Class frmAdvancedImport End Get End Property + Public Property ModWinConfigsForLinux As Boolean + Set(value As Boolean) + bModWinConfigsForLinux = value + End Set + Get + Return bModWinConfigsForLinux + End Get + End Property + Public ReadOnly Property FinalData As Hashtable Get Return hshFinalData End Get End Property + + Private Sub SelectToggle() Cursor.Current = Cursors.WaitCursor lstGames.BeginUpdate() @@ -56,6 +68,62 @@ Public Class frmAdvancedImport End If End Sub + Private Sub ModTags(ByRef oTags As List(Of Tag)) + Dim bExists As Boolean + Dim oTag As Tag + Dim oNewTag As Tag + Dim oRemoveTag As New Tag + Dim sTag As String + Dim sAddTags() As String = {"Wine"} + Dim sRemoveTags() As String = {"Official"} + + For Each sTag In sAddTags + bExists = False + For Each oTag In oTags + If oTag.Name = sTag Then + bExists = True + Exit For + End If + Next + If Not bExists Then + oNewTag = New Tag + oNewTag.Name = sTag + oTags.Add(oNewTag) + End If + Next + + For Each sTag In sRemoveTags + bExists = False + For Each oTag In oTags + If oTag.Name = sTag Then + bExists = True + oRemoveTag = oTag + Exit For + End If + Next + If bExists Then + oTags.Remove(oRemoveTag) + End If + Next + + End Sub + + Private Function CheckIgnoreTags(ByVal oTags As List(Of Tag)) As Boolean + Dim oTag As Tag + Dim sTag As String + Dim sIgnoreTags() As String = {"DOSBox", "ScummVM"} + + For Each oTag In oTags + For Each sTag In sIgnoreTags + If oTag.Name = sTag Then + Return False + End If + Next + Next + + Return True + End Function + Private Sub LoadData(Optional ByVal sFilter As String = "", Optional ByVal bAutoDetect As Boolean = False) Dim oApp As clsGame Dim oListViewItem As ListViewItem @@ -75,6 +143,12 @@ Public Class frmAdvancedImport For Each de As DictionaryEntry In ImportData bAddItem = False oApp = DirectCast(de.Value, clsGame) + + 'Run any required tag mods + If ModWinConfigsForLinux Then + ModTags(oApp.ImportTags) + End If + sTags = String.Empty oApp.ImportTags.Sort(AddressOf mgrCommon.CompareImportTagsByName) For Each oTag As Tag In oApp.ImportTags @@ -119,6 +193,11 @@ Public Class frmAdvancedImport End If End If + 'Check for hardcoded ignore tags + If ModWinConfigsForLinux Then + bAddItem = CheckIgnoreTags(oApp.ImportTags) + End If + If bAddItem Then If oListViewItem.Checked Then bResetSelectAll = True lstGames.Items.Add(oListViewItem) diff --git a/GBM/Forms/frmGameManager.vb b/GBM/Forms/frmGameManager.vb index 913ca68..d45b4b1 100644 --- a/GBM/Forms/frmGameManager.vb +++ b/GBM/Forms/frmGameManager.vb @@ -1704,9 +1704,9 @@ Public Class frmGameManager End Sub - Private Sub ImportOfficialGameList(ByVal sImportUrl As String) + Private Sub ImportOfficialGameList(ByVal sImportUrl As String, ByVal bWinConfigsInLinux As Boolean) If mgrCommon.ShowMessage(frmGameManager_ConfirmOfficialImport, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then - If mgrMonitorList.DoImport(sImportUrl, True, Settings) Then + If mgrMonitorList.DoImport(sImportUrl, True, Settings,, bWinConfigsInLinux) Then mgrMonitorList.SyncMonitorLists(Settings) LoadData() LoadBackupData() @@ -1971,6 +1971,7 @@ Public Class frmGameManager End Sub Private Sub cmsOfficialWindows_Click(sender As Object, e As EventArgs) Handles cmsOfficialWindows.Click, cmsOfficial.Click + Dim bWinConfigsinLinux As Boolean = False 'Show one time warning about Windows configs in Linux If mgrCommon.IsUnix Then If Not (oSettings.SuppressMessages And mgrSettings.eSuppressMessages.WinConfigsInLinux) = mgrSettings.eSuppressMessages.WinConfigsInLinux Then @@ -1978,13 +1979,14 @@ Public Class frmGameManager oSettings.SuppressMessages = oSettings.SetMessageField(oSettings.SuppressMessages, mgrSettings.eSuppressMessages.WinConfigsInLinux) oSettings.SaveSettings() End If + bWinConfigsinLinux = True End If - ImportOfficialGameList(App_URLImport) + ImportOfficialGameList(App_URLImport, bWinConfigsinLinux) End Sub Private Sub cmsOfficialLinux_Click(sender As Object, e As EventArgs) Handles cmsOfficialLinux.Click - ImportOfficialGameList(App_URLImportLinux) + ImportOfficialGameList(App_URLImportLinux, False) End Sub Private Sub cmsFile_Click(sender As Object, e As EventArgs) Handles cmsFile.Click diff --git a/GBM/Managers/mgrMonitorList.vb b/GBM/Managers/mgrMonitorList.vb index 232cc80..d66f33e 100644 --- a/GBM/Managers/mgrMonitorList.vb +++ b/GBM/Managers/mgrMonitorList.vb @@ -788,13 +788,13 @@ Public Class mgrMonitorList Return True End Function - Public Shared Function DoImport(ByVal sPath As String, ByVal bOfficial As Boolean, ByRef oSettings As mgrSettings, Optional ByVal bStartUpWizard As Boolean = False) As Boolean + Public Shared Function DoImport(ByVal sPath As String, ByVal bOfficial As Boolean, ByRef oSettings As mgrSettings, Optional ByVal bStartUpWizard As Boolean = False, Optional ByVal bWinConfigsInLinux As Boolean = False) As Boolean If mgrCommon.IsAddress(sPath) Then If mgrCommon.CheckAddress(sPath) Then If bOfficial And Not bStartUpWizard And Not ((oSettings.SuppressMessages And mgrSettings.eSuppressMessages.GameIDSync) = mgrSettings.eSuppressMessages.GameIDSync) Then SyncGameIDs(sPath, oSettings, True) End If - ImportMonitorList(sPath, True) + ImportMonitorList(sPath, True, bWinConfigsInLinux) Return True Else mgrCommon.ShowMessage(mgrMonitorList_WebNoReponse, sPath, MsgBoxStyle.Exclamation) @@ -802,7 +802,7 @@ Public Class mgrMonitorList End If Else If File.Exists(sPath) Then - ImportMonitorList(sPath) + ImportMonitorList(sPath,, bWinConfigsInLinux) Return True Else mgrCommon.ShowMessage(mgrMonitorList_FileNotFound, sPath, MsgBoxStyle.Exclamation) @@ -812,7 +812,7 @@ Public Class mgrMonitorList Return True End Function - Private Shared Sub ImportMonitorList(ByVal sLocation As String, Optional ByVal bWebRead As Boolean = False) + Private Shared Sub ImportMonitorList(ByVal sLocation As String, Optional ByVal bWebRead As Boolean = False, Optional ByVal bWinConfigsInLinux As Boolean = False) Dim hshCompareFrom As New Hashtable Dim hshCompareTo As Hashtable Dim hshSyncItems As Hashtable @@ -859,6 +859,7 @@ Public Class mgrMonitorList Dim frm As New frmAdvancedImport frm.ImportInfo = oExportInfo frm.ImportData = hshSyncItems + frm.ModWinConfigsForLinux = bWinConfigsInLinux If frm.ShowDialog() = DialogResult.OK Then Cursor.Current = Cursors.WaitCursor From 58ac76eba05146627e914256a9550c2bb0305569 Mon Sep 17 00:00:00 2001 From: "Michael J. Seiferling" Date: Mon, 1 Oct 2018 09:02:48 -0600 Subject: [PATCH 32/32] Fixed broken filtering on import --- GBM/Forms/frmAdvancedImport.vb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/GBM/Forms/frmAdvancedImport.vb b/GBM/Forms/frmAdvancedImport.vb index 60d0a6b..a35125b 100644 --- a/GBM/Forms/frmAdvancedImport.vb +++ b/GBM/Forms/frmAdvancedImport.vb @@ -46,8 +46,6 @@ Public Class frmAdvancedImport End Get End Property - - Private Sub SelectToggle() Cursor.Current = Cursors.WaitCursor lstGames.BeginUpdate() @@ -194,7 +192,7 @@ Public Class frmAdvancedImport End If 'Check for hardcoded ignore tags - If ModWinConfigsForLinux Then + If bAddItem And ModWinConfigsForLinux Then bAddItem = CheckIgnoreTags(oApp.ImportTags) End If