Support for all region (maybe XD)
Code:
#include 'File.au3'
Global Const $sValueTypes[12] = ["REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_LINK", "REG_MULTI_SZ", "REG_RECookedPC_LIST", "REG_FULL_RECookedPC_DESCRIPTOR", "REG_RECookedPC_REQUIREMENTS_LIST", "REG_QWORD"]
;BnS path
MsgBox(0, "BnS Path", _FindBnS(1))
;CookedPC path (effect)
MsgBox(0, "CookedPC Path (effect)", _FindBnS(2))
;CookedPC path (for mod)
MsgBox(0, "CookedPC Path (for mod)", _FindBnS(3))
Func _FindBnS($iMode)
Local $bnsDrive = '', $bnsPath = '', $bnsFileName = '', $bnsExt = '', $bnsCooked = '', $wow32 = ''
Local Const $keys[5] = ['NCWest\BnS', 'NCTaiwan\TWBNS22', 'PlayNC\BNS_JPN', 'plaync\BNS_KOR', 'plaync\BNS_KOR_TEST']
If @OSArch == 'X64' Or @OSArch == 'IA64' Then $wow32 = 'Wow6432Node\'
;BaseDir support only NA/EU TW JP KR region
For $key In $keys
$bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & $key & '\', 'BaseDir')
If $bnsPath <> '' Then ExitLoop
Next
;For other region
If $bnsPath == '' Then
;Part 1 MuiCache from Local Machine
$kList = _RegEnumValEx('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FeatureUsage\AppSwitched', 0, '*', 4)
If IsArray($kList) Then
For $i = 1 To $kList[0][0]
If StringInStr($kList[$i][1], '\bin\Client.exe') Or StringInStr($kList[$i][1], '\bin64\Client.exe') Then
_PathSplit($kList[$i][1], $bnsDrive, $bnsPath, $bnsFileName, $bnsExt)
ExitLoop
EndIf
Next
Else
;Part 2 MuiCache from USERS
;get path to MuiCache, need to know where is MuiCache
$kList = _RegEnumKeyEx('HKU', 0, 'MuiCache', '*', 4)
If IsArray($kList) Then
For $i = 1 To $kList[0]
;confirm path and find bns
If StringInStr($kList[$i], 'Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache') Then
$kList = _RegEnumValEx($kList[$i], 0, '*', 1)
If IsArray($kList) Then
For $n = 1 To $kList[0][0]
If StringInStr($kList[$n][1], '\bin\Client.exe') Or StringInStr($kList[$n][1], '\bin64\Client.exe') Then
_PathSplit($kList[$n][1], $bnsDrive, $bnsPath, $bnsFileName, $bnsExt)
ExitLoop
EndIf
Next
EndIf
ExitLoop
EndIf
Next
EndIf
EndIf
EndIf
;Build the bns path
If StringRight($bnsPath, StringLen('\bin\')) == '\bin\' Then $bnsPath = StringTrimRight($bnsPath, StringLen('\bin\'))
If StringRight($bnsPath, StringLen('\bin64\')) == '\bin64\' Then $bnsPath = StringTrimRight($bnsPath, StringLen('\bin64\'))
If StringRight($bnsPath, 1) == '\' Then $bnsPath = StringTrimRight($bnsPath, 1)
$bnsPath = $bnsDrive & $bnsPath
Switch $iMode
Case 1
If FileExists($bnsPath) Then Return $bnsPath
Case 2
$bnsCooked = $bnsPath & '\contents\bns\CookedPC'
If FileExists($bnsCooked) Then Return $bnsCooked
Case 3
$bnsCooked = _FileListToArrayEx($bnsPath & '\contents\Local', 'CookedPC', 12)
If IsArray($bnsCooked) And FileExists($bnsCooked[1]) Then Return $bnsCooked[1]
EndSwitch
;Error: Empty return
Return ''
EndFunc ;==>_FindBnS
Func _RegEnumKeyEx($KeyName, $iFlag = 0, $sFilter = "*", $vFilter = "*", $iValueTypes = 0)
If StringRegExp($sFilter, StringReplace("^\s*$|\v|\\|^\||\|\||\|$", Chr(BitAND($iFlag, 64) + 28) & "\|^\||\|\||\|$", "\\\\")) Then Return SetError(1, 0, "")
Local $indexSubKey[101] = [100], $SubKeyName, $BS = "\", $sKeyList, $i = 1, $sKeyFlag = BitAND($iFlag, 1), $sKeyFilter = StringReplace($sFilter, "*", "")
If BitAND($iFlag, 2) Then $sKeyList = @LF & $KeyName
If Not BitAND($iFlag, 64) Then $sFilter = StringRegExpReplace(BitAND($iFlag, 16) & "(?i)(", "16\(\?\i\)|\d+", "") & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($sFilter, "[^*?|]+", "\\Q$0\\E"), "\\E(?=\||$)", "$0\$"), "(?<=^|\|)\\Q", "^$0"), "\*+", ".*") & ")"
While $i
$indexSubKey[$i] += 1
$SubKeyName = RegEnumKey($KeyName, $indexSubKey[$i])
If @error Then
$indexSubKey[$i] = 0
$i -= 1
$KeyName = StringLeft($KeyName, StringInStr($KeyName, "\", 1, -1) - 1)
ContinueLoop
EndIf
If $sKeyFilter Then
If StringRegExp($SubKeyName, $sFilter) Then $sKeyList &= @LF & $KeyName & $BS & $SubKeyName
Else
$sKeyList &= @LF & $KeyName & $BS & $SubKeyName
EndIf
If $sKeyFlag Then ContinueLoop
$i += 1
If $i > $indexSubKey[0] Then
$indexSubKey[0] += 100
ReDim $indexSubKey[$indexSubKey[0] + 1]
EndIf
$KeyName &= $BS & $SubKeyName
WEnd
If Not $sKeyList Then Return SetError(2, 0, "")
If BitAND($iFlag, 128) <> 128 Then Return StringSplit(StringTrimLeft($sKeyList, 1), @LF, StringReplace(BitAND($iFlag, 32), "32", 2))
$sKeyList = _RegEnumValEx(StringSplit(StringTrimLeft($sKeyList, 1), @LF), $iFlag, $vFilter, $iValueTypes)
Return SetError(@error, 0, $sKeyList)
EndFunc ;==>_RegEnumKeyEx
Func _RegEnumValEx($aKeyList, $iFlag = 0, $sFilter = "*", $iValueTypes = 0)
If StringRegExp($sFilter, "\v") Then Return SetError(3, 0, "")
If Not IsArray($aKeyList) Then $aKeyList = StringSplit($aKeyList, @LF)
Local $aKeyValList[1954][4], $iKeyVal = Int(BitAND($iFlag, 32) = 0), $sKeyVal = 1953, $sRegEnumVal, $iRegEnumVal, $RegRead = BitAND($iFlag, 256), $vFilter = StringReplace($sFilter, "*", "")
If Not BitAND($iFlag, 64) Then $sFilter = StringRegExpReplace(BitAND($iFlag, 16) & "(?i)(", "16\(\?\i\)|\d+", "") & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($sFilter, "[^*?|]+", "\\Q$0\\E"), "\\E(?=\||$)", "$0\$"), "(?<=^|\|)\\Q", "^$0"), "\*+", ".*") & ")"
For $i = 1 To $aKeyList[0]
$iRegEnumVal = 0
While 1
If $iKeyVal = $sKeyVal Then
If $sKeyVal = 3999744 Then ExitLoop
$sKeyVal *= 2
ReDim $aKeyValList[$sKeyVal + 1][4]
EndIf
$aKeyValList[$iKeyVal][0] = $aKeyList[$i]
$iRegEnumVal += 1
$sRegEnumVal = RegEnumVal($aKeyList[$i], $iRegEnumVal)
If @error <> 0 Then
If $iRegEnumVal = 1 And $vFilter = "" Then $iKeyVal += 1
ExitLoop
EndIf
$aKeyValList[$iKeyVal][2] = $sValueTypes[@extended]
If BitAND(@extended, $iValueTypes) <> $iValueTypes Then ContinueLoop
If $vFilter And Not StringRegExp($sRegEnumVal, $sFilter) Then ContinueLoop
$aKeyValList[$iKeyVal][1] = $sRegEnumVal
If $RegRead Then $aKeyValList[$iKeyVal][3] = RegRead($aKeyList[$i], $sRegEnumVal)
$iKeyVal += 1
WEnd
Next
$sRegEnumVal = $iKeyVal - Int(BitAND($iFlag, 32) = 0)
If Not $sRegEnumVal Or ($sRegEnumVal = 1 And $vFilter = "" And $aKeyValList[$iKeyVal - $sRegEnumVal][2] = "") Then Return SetError(4, 0, "")
ReDim $aKeyValList[$iKeyVal][4]
If Not BitAND($iFlag, 32) Then $aKeyValList[0][0] = $iKeyVal - 1
Return $aKeyValList
EndFunc ;==>_RegEnumValEx
Func _FileListToArrayEx($sPath, $sFilter = "*", $iFlag = 0)
Local $hSearch, $sFile, $sFileList, $iFlags = StringReplace(BitAND($iFlag, 1) + BitAND($iFlag, 2), "3", "0"), $sSubDir = BitAND($iFlag, 4), $DirPath = ""
$sPath = StringRegExpReplace($sPath, "[\\/]+\z", "") & "\" ; ensure single trailing backslash
If Not FileExists($sPath) Then Return SetError(1, 1, "")
If StringRegExp($sFilter, "[\\/:><]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
If BitAND($iFlag, 8) Then $DirPath = $sPath
If Not ($iFlags = 0 Or $iFlags = 1 Or $iFlags = 2 Or $sSubDir = 4 Or $DirPath <> "") Then Return SetError(3, 3, "")
$hSearch = FileFindFirstFile($sPath & "*")
If @error Then Return SetError(4, 4, "")
Local $hWSearch = $hSearch, $hWSTMP = $hSearch, $SearchWD, $Extended, $sDelim = "|", $sDirFilter = StringReplace($sFilter, "*", "")
$sFilter = StringRegExpReplace(BitAND($iFlag, 16) & "(?i)", "16\(\?\i\)|\d+", "") & "(" & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace("|" & $sFilter & "|", '\|\h*\|[\|\h]*', "\|"), '[\^\$\(\)\+\[\]\{\}\,\.\]', "\\$0"), "\|([^\*])", "\|^$1"), "([^\*])\|", "$1\$\|"), '\*', ".*"), '^\||\|$', "") & ")"
While 1
$sFile = FileFindNextFile($hWSearch)
If @error Then
If $hWSearch = $hSearch Then ExitLoop
FileClose($hWSearch)
$hWSearch -= 1
$SearchWD = StringLeft($SearchWD, StringInStr(StringTrimRight($SearchWD, 1), "\", 1, -1))
ElseIf $sSubDir Then
$Extended = @extended
If ($iFlags + $Extended <> 2) Then
If $sDirFilter Then
If StringRegExp($sFile, $sFilter) Then $sFileList &= $sDelim & $DirPath & $SearchWD & $sFile
Else
$sFileList &= $sDelim & $DirPath & $SearchWD & $sFile
EndIf
EndIf
If Not $Extended Then ContinueLoop
$hWSTMP = FileFindFirstFile($sPath & $SearchWD & $sFile & "\*")
If $hWSTMP = -1 Then ContinueLoop
$hWSearch = $hWSTMP
$SearchWD &= $sFile & "\"
Else
If ($iFlags + @extended = 2) Or StringRegExp($sFile, $sFilter) = 0 Then ContinueLoop
$sFileList &= $sDelim & $DirPath & $sFile
EndIf
WEnd
FileClose($hSearch)
If Not $sFileList Then Return SetError(4, 4, "")
Return StringSplit(StringTrimLeft($sFileList, 1), "|", StringReplace(BitAND($iFlag, 32), "32", 2))
EndFunc ;==>_FileListToArrayEx
Last edited: