• Hi Guest! To get rid of ads on the page, please consider donating through user upgrades or other methods.

Other [Autoit] Find BnS path (source code)

Fukki

Cricket
Member
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:

Endless

Founder
Staff member
Administrator
If you get the registry path/values for other regions, hit me up or feel free to update your post ;)
 

Fukki

Cricket
Member
i have test many times and pc (win7, win10)
it's work with MuiCache scan for other region like TH and VN

3469
 
Last edited:

cupid

Forgiving
Staff member
Moderator
Member
Yikes ... That's some hacky hacked hack . . . But works!

Also, you can check if the system is 32 or 64bits and add the wow6432 bit (example):

Code:
Local $wow32 = ''

If @OSArch == 'X64' Or @OSArch == 'IA64' Then $wow32 = 'Wow6432Node\'

;BaseDir support only NA/EU TW JP KR region
If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & 'NCWest\BnS\', 'BaseDir')
If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & 'NCTaiwan\TWBNS22\', 'BaseDir')
If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & 'PlayNC\BNS_JPN\', 'BaseDir')
If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & 'plaync\BNS_KOR\', 'BaseDir')
If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & 'plaync\BNS_KOR_TEST\', 'BaseDir')

This should work.
 

cupid

Forgiving
Staff member
Moderator
Member
You're welcome.

If you want, you can try something like this as well:

Code:
Local $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\'

For $key In $keys
    If $bnsPath == '' Then $bnsPath = RegRead('HKLM\SOFTWARE\' & $wow32 & $key & '\', 'BaseDir')
Next

I think you can just do For $key In ['NCWest\BnS', 'NCTaiwan\TWBNS22', 'PlayNC\BNS_JPN', 'plaync\BNS_KOR', 'plaync\BNS_KOR_TEST'] but I'm not sure.

Just remember that this is from my knowledge of Visual Basic 6/.net/VBscript, and from reading the documentation, so, it may not work.
 
Top Bottom