XignCode Bypasser installer for Blade & Soul

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












As the title says, this batch script installs the XignCode Bypasser.



Xigncode is a software bundled with games to analise running programs and prevent cheating. (Sometimes, it prevents the game to load at all on the newest Windows releases.)



For this, a bypasser was created that disables this check, allowing players to run the game (if they couldn't), mod the game (One Click Tool, for example) and (if you want) cheat.



Copying the files manually is a boring task that can lead to mistakes (copying from the wrong location, deleting the Bypasser by mistake, ....).



For that, I've made the following batch script that does all the copying and extraction:



@echo off

REM set the title - https://stackoverflow.com/a/39329524
title XignCode Bypasser installer
color 07

REM config
setlocal EnableDelayedExpansion
set CALLPATH=%~dp0
set FILESPATH=!CALLPATH!
set WIN_BITS=64
set REGKEY="HKEY_LOCAL_MACHINESOFTWAREWow6432NodeNCWestBnS"

REM needs administrator rights - https://stackoverflow.com/a/21295806
REM we run fsutil to check the error code. 0 = admin
fsutil dirty query %SystemDrive% >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
call :kill 1 "You need to execute as administrator"
)

REM detect the bitness and fixes values - https://superuser.com/a/268384
echo %PROCESSOR_ARCHITECTURE% | find /i "x86" >nul
IF %ERRORLEVEL% EQU 0 (
set WIN_BITS=32
set REGKEY="HKEY_LOCAL_MACHINESOFTWARENCWestBnS"
)

REM checks if the game is running - https://stackoverflow.com/a/1329790
tasklist /FI "WINDOWTITLE eq Blade & Soul" 2>nul | find /I /N "Client.exe" >nul
IF %ERRORLEVEL% EQU 0 (
call :kill 1 "Close the game before installing the Xigncode Bypasser"
)

set WIDTH=80
for /f "tokens=1*" %%a in ('mode con') do (
IF "%%a" EQU "Columns:" (
set "WIDTH=%%b"
)
)

REM this key is required - https://stackoverflow.com/a/445323
REM we check if it exists before trying to run the code
REG QUERY !REGKEY! >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
REM call :kill 1 "Registry key !REGKEY! not found"
call :colorecho "Registry key !REGKEY! not found" red black
call :pause "Press any key to select the game installation directory"
call :getfolder "Select game installation folder"

IF [!getfolder!] EQU (
call :kill 1 "Folder selection canceled"
)
set "AppPath=!getfolder!"
) ELSE (
REM fetches the data in the registry
for /f "tokens=2*" %%a in ('REG QUERY !REGKEY! /v BaseDir') do set "AppPath=%%~b"

IF NOT EXIST "!AppPath!*" (
call :colorecho "!AppPath! does not exist or is empty" red black
call :pause "Press any key to select the game installation directory"
call :getfolder "Select game installation folder"

IF [!getfolder!] EQU (
call :kill 1 "Folder selection canceled"
)
set "AppPath=!getfolder!"
)
)

:startpatch
REM ready to replace everything

cls
call :colorecho "This will install the XignCode Bypasser" black gray
call :line
echo Game installation: !AppPath!
echo Files in: !FILESPATH!
echo Detected !WIN_BITS! bit Windows installation
call :line

:choice
echo What to do next?
choice /c:qigeb /n /m "[Q]uit | [I]nstall | [G]ame folder | [B]ypasser folder | [E]xtract ZIP"

IF ERRORLEVEL 5 (
REM [B]ypasser folder

call :getfolder "Select XignCode Bypasser folder"

IF [!getfolder!] EQU (
call :colorecho "Folder selection canceled" darkyellow black
goto choice
) ELSE (
IF NOT EXIST "!getfolder!*" (
call :colorecho "Folder is empty" red black
goto choice
) ELSE (
set "FILESPATH=!getfolder!"
goto startpatch
)
)

) ELSE (
IF ERRORLEVEL 4 (
REM [E]xtract ZIP
call :zipfile "!CALLPATH!"
IF ERRORLEVEL 255 (
call :colorecho "No suitable extraction program found" darkred black
goto choice
)
IF ERRORLEVEL 2 (
goto choice
)
IF ERRORLEVEL 1 (
call :colorecho "File selection canceled" darkyellow black
goto choice
)
IF ERRORLEVEL 0 (
set FILESPATH=!zipfile!
goto startpatch
)
) ELSE (
IF ERRORLEVEL 3 (
REM [G]ame folder
call :getfolder "Select game installation folder"

IF [!getfolder!] EQU (
call :colorecho "Folder selection canceled" darkyellow black
goto choice
) ELSE (
IF NOT EXIST "!getfolder!*" (
call :colorecho "Folder is empty" red black
goto choice
) ELSE (
set "AppPath=!getfolder!"
goto startpatch
)
)
) ELSE (
IF ERRORLEVEL 2 (
REM [I]nstall
call :line

REM call the patching function
for %%b in (32,64) do (
IF %%b LEQ !WIN_BITS! (
call :patch %%b
IF ERRORLEVEL 1 (
call :colorecho "Installation for %%b bits was skipped" darkyellow black
)
)
)

call :line
call :colorecho "The XignCode Bypasser was successfully installed!" darkgreen black
) ELSE (
REM [Q]uit
call :line
call :colorecho "You decided to quit the installer" darkyellow black
)
)
)
)

call :kill 0 "More in http://bnsbuddy.com/ and https://www.reddit.com/r/BladeAndSoulMods/"

REM =====================
REM FUNCTION DECLARATION!
REM =====================

:line
REM draws a line width the width of the console
call :repeat _ !WIDTH!
echo %repeat%
goto :eof

:repeat
REM https://rosettacode.org/wiki/Repeat_a_string#Batch_File
REM repeats a char n times
REM %1 = char, %2 = times
REM exit: 1 = times missing
setlocal EnableDelayedExpansion

IF [%2] EQU (
REM closest thing to a return
REM explained below
endlocal & set "repeat="
exit /b 1
)
set char=%1
for /l %%i in (1,1,%2) do set res=!res!%char%

REM since %res% is expanded on compilation time
REM it will have the correct value before endlocal
REM has any effect, working as a "return"
endlocal & set "repeat=%res%"
goto :eof


:getfolder
REM fetches a folder path
REM %1 = title
setlocal EnableDelayedExpansion

set txt='Please choose a folder.'
IF NOT [%1] EQU (
set txt=%1
set txt=!txt:"=!
)

REM executes the folder dialog - https://stackoverflow.com/a/15885133
set "cmd="(new-object -COM 'Shell.Application').BrowseForFolder(0,'%txt%',0,0).self.path""
for /f "usebackq delims=" %%I in (`powershell -NoProfile -Noninteractive -NoLogo %cmd%`) do set "folder=%%I"

endlocal & set "getfolder=%folder%"
goto :eof

:colorecho
REM prints a message with specific colors
REM %1 = message, %2 = text color, %3 = background color, %4 = extra arguments (like -NoNewline)
REM https://www.petri.com/change-powershell-console-font-and-background-colors
setlocal EnableDelayedExpansion

powershell -NoProfile -Noninteractive -NoLogo Write-Host %1 -ForegroundColor %2 -BackgroundColor %3 %4

goto :eof


:pause
REM handles the pausing
REM %1 = message
setlocal EnableDelayedExpansion

set a=%1
echo !a:"=!

pause >nul

goto :eof

:kill
REM creates the exit messages
REM %1 = exit code, %2 = message
setlocal EnableDelayedExpansion

IF NOT [%2] EQU (
IF %1 EQU 0 (
set a=%2
echo !a:"=!
) ELSE (
call :colorecho %2 red black
)
)

call :pause "Press any key to exit."
exit %1

goto :eof

:patch
REM function to handle the patching
REM %1 = bitness
REM exit: 1 = skipped
setlocal EnableDelayedExpansion

set bits=%1
set folder=!FILESPATH!!bits!
set dll=bsengine_Shipping
set target=!AppPath!bin

IF NOT !bits! EQU 32 (
REM 64bit paths need treatment -.-
set dll=!dll!!bits!
set target=!target!!bits!
)

REM make sure the folder with the contents exist
IF NOT EXIST "!folder!*" (
call :kill 1 "Folder !bits! does not exist or is empty"
)

REM it exists, confirm the remaining
IF NOT EXIST "!folder!XignCode*" (
call :kill 1 "Folder !bits!XignCode does not exist or is empty"
)
IF NOT EXIST "!folder!!dll!.dll" (
call :kill 1 "File !bits!!dll!.dll does not exist"
)

echo Folder !bits! found, preparing to copy files ...

REM verifying if the bypasser was already installed may save work
REM step 1 - verify if the dll exists
IF EXIST "!target!XignCode!dll!.dll" (
REM step 2 - compare if they are the same. if they are ...
fc /b "!folder!!dll!.dll" "!target!XignCode!dll!.dll" >nul
IF %ERRORLEVEL% EQU 0 (
REM step 3 - check if the x3.xem file is the same (original one is different)
fc /b "!folder!XignCodex3.xem" "!target!XignCodex3.xem" >nul
IF %ERRORLEVEL% EQU 0 (
REM step 4 - faily certain it's already installed, ask user input
call :colorecho "The bypasser was already installed for !bits! bits." darkyellow black
choice /c:yn /n /m "Install anyway? [Y] Yes | [N] No"
IF ERRORLEVEL 2 (
exit /b 1
)
)
)
)

REM hacky way to echo without a new line
echo | set /P ="Copying files "
call :colorecho . darkgreen black -NoNewline

REM begin copying the directory
xcopy "!folder!XignCode" "!target!XignCode" /i /s /q /y >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
call :colorecho . darkred black
call :kill 1 "Error (%ERRORLEVEL%) while copying the folder !bits!XignCode"
)

call :colorecho . darkgreen black -NoNewline

REM copy the dll file
copy "!folder!!dll!.dll" "!target!XignCode!dll!.dll" /b /y >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
call :colorecho . darkred black
call :kill 1 "Error (%ERRORLEVEL%) while copying the file !bits!!dll!.dll"
)

call :colorecho . darkgreen black

goto :eof

:zipfile
REM opens a file dialog that allows to choose the zip file
REM also "returns" the path where the folder is when done
REM %1 = optional target for extraction
REM exit: 0 = extracted, 1 = skipped, 2 = failed
setlocal EnableDelayedExpansion

REM https://stackoverflow.com/a/50115044
REM fix for dialog not showing: https://stackoverflow.com/q/216710
set cmd=powershell -NoProfile -Noninteractive -NoLogo -command "&[System.Reflection.Assembly]::LoadWithPartialName('System.windows.forms')"

for /f "delims=" %%i in ('!cmd!') do (
set filedrive=%%~di
set filepath=%%~pi
set filename=%%~ni
set fileext=%%~xi
)

IF "!filedrive!!filepath!!filename!!fileext!" EQU "" (
endlocal & exit /b 1
)

set "folder=!filedrive!!filepath!"
set "file=!filename!!fileext!"

set target=%~dp1
IF "!target!" EQU "" (
SET target=%TEMP%
)

set code=255

REM UNTESTED!!! CAN'T TEST THIS!
REM https://stackoverflow.com/q/1825585
set psv=powershell -NoProfile -Noninteractive -NoLogo -command "$psversiontable.PSVersion.Major"
for /f "tokens=1" %%i in ('!psv!') do (
IF %%i GEQ 5 (
echo Using Powershell version %%i to extact
REM https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6
powershell -NoProfile -Noninteractive -NoLogo Expand-Archive "!folder!!file!" "!target!!filename!" >nul
IF NOT %ERRORLEVEL% EQU 0 (
call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
set code=2
) ELSE (
endlocal & set "zipfile=%target%%filename%"
exit /b 0
)
)
)

REM https://stackoverflow.com/q/14122732
IF EXIST "%ProgramFiles%7-Zip7z.exe" (
echo Using 7-Zip to extact
"%ProgramFiles%7-Zip7z.exe" x "!folder!!file!" -bd -y -o"!target!!filename!" >nul
IF NOT %ERRORLEVEL% EQU 0 (
call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
set code=2
) ELSE (
endlocal & set "zipfile=%target%%filename%"
exit /b 0
)
)

REM https://stackoverflow.com/a/19337595
IF EXIST "%ProgramFiles%WinRARwinrar.exe" (
echo Using WinRAR to extact
"%ProgramFiles%WinRARwinrar.exe" x -ibck "!folder!!file!" *.* "!target!!filename!" >nul
IF NOT %ERRORLEVEL% EQU 0 (
call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
set code=2
) ELSE (
endlocal & set "zipfile=%target%%filename%"
exit /b 0
)
)

exit /b !code!


This script has many functionalities:



  • Automatically fetches the game installation path from the registry

  • Automatically detects the Windows "bitness" (to decide if it patches the 64-bit folder or not)

  • Allows to change the game installation path for the running script

  • Extracts the files and automatically assumes the path where they were extracted to

  • Verifies if it was already installed, allowing to skip or install anyway

Knowing it is a rather large script, I've tried to split it into multiple functions, to make it easier to understand, read and maintain in the future.



You can see the complete instruction list on https://github.com/ismael-miguel/xcb-installer



As far as I know and tested, this is working as it should. All it's functionalities function as intended and there seem to be no obvious errors.



Regarding readability, error handling and readability, is there anything else I can improve?




Disclaimer:



Seeing that this action of bypassing XignCode may be against the Terms and Conditions of the game, I've asked about it on Are we allowed to post questions that allow you to do something that may be against the Terms and Conditions of another software? (to which 13 upvoted the only answer, 1 downvoted).



This script does not allow you to get the files in any way, shape or form: it only does all the extracting and copying. If you want the files, you have to get them by yourself. I do not want to make it any easier to get the needed files.



Batch is a language I'm not familiar with, requiring me to learn a lot from all the websites and links available in comments.







share|improve this question



























    up vote
    1
    down vote

    favorite












    As the title says, this batch script installs the XignCode Bypasser.



    Xigncode is a software bundled with games to analise running programs and prevent cheating. (Sometimes, it prevents the game to load at all on the newest Windows releases.)



    For this, a bypasser was created that disables this check, allowing players to run the game (if they couldn't), mod the game (One Click Tool, for example) and (if you want) cheat.



    Copying the files manually is a boring task that can lead to mistakes (copying from the wrong location, deleting the Bypasser by mistake, ....).



    For that, I've made the following batch script that does all the copying and extraction:



    @echo off

    REM set the title - https://stackoverflow.com/a/39329524
    title XignCode Bypasser installer
    color 07

    REM config
    setlocal EnableDelayedExpansion
    set CALLPATH=%~dp0
    set FILESPATH=!CALLPATH!
    set WIN_BITS=64
    set REGKEY="HKEY_LOCAL_MACHINESOFTWAREWow6432NodeNCWestBnS"

    REM needs administrator rights - https://stackoverflow.com/a/21295806
    REM we run fsutil to check the error code. 0 = admin
    fsutil dirty query %SystemDrive% >nul 2>&1
    IF NOT %ERRORLEVEL% EQU 0 (
    call :kill 1 "You need to execute as administrator"
    )

    REM detect the bitness and fixes values - https://superuser.com/a/268384
    echo %PROCESSOR_ARCHITECTURE% | find /i "x86" >nul
    IF %ERRORLEVEL% EQU 0 (
    set WIN_BITS=32
    set REGKEY="HKEY_LOCAL_MACHINESOFTWARENCWestBnS"
    )

    REM checks if the game is running - https://stackoverflow.com/a/1329790
    tasklist /FI "WINDOWTITLE eq Blade & Soul" 2>nul | find /I /N "Client.exe" >nul
    IF %ERRORLEVEL% EQU 0 (
    call :kill 1 "Close the game before installing the Xigncode Bypasser"
    )

    set WIDTH=80
    for /f "tokens=1*" %%a in ('mode con') do (
    IF "%%a" EQU "Columns:" (
    set "WIDTH=%%b"
    )
    )

    REM this key is required - https://stackoverflow.com/a/445323
    REM we check if it exists before trying to run the code
    REG QUERY !REGKEY! >nul 2>&1
    IF NOT %ERRORLEVEL% EQU 0 (
    REM call :kill 1 "Registry key !REGKEY! not found"
    call :colorecho "Registry key !REGKEY! not found" red black
    call :pause "Press any key to select the game installation directory"
    call :getfolder "Select game installation folder"

    IF [!getfolder!] EQU (
    call :kill 1 "Folder selection canceled"
    )
    set "AppPath=!getfolder!"
    ) ELSE (
    REM fetches the data in the registry
    for /f "tokens=2*" %%a in ('REG QUERY !REGKEY! /v BaseDir') do set "AppPath=%%~b"

    IF NOT EXIST "!AppPath!*" (
    call :colorecho "!AppPath! does not exist or is empty" red black
    call :pause "Press any key to select the game installation directory"
    call :getfolder "Select game installation folder"

    IF [!getfolder!] EQU (
    call :kill 1 "Folder selection canceled"
    )
    set "AppPath=!getfolder!"
    )
    )

    :startpatch
    REM ready to replace everything

    cls
    call :colorecho "This will install the XignCode Bypasser" black gray
    call :line
    echo Game installation: !AppPath!
    echo Files in: !FILESPATH!
    echo Detected !WIN_BITS! bit Windows installation
    call :line

    :choice
    echo What to do next?
    choice /c:qigeb /n /m "[Q]uit | [I]nstall | [G]ame folder | [B]ypasser folder | [E]xtract ZIP"

    IF ERRORLEVEL 5 (
    REM [B]ypasser folder

    call :getfolder "Select XignCode Bypasser folder"

    IF [!getfolder!] EQU (
    call :colorecho "Folder selection canceled" darkyellow black
    goto choice
    ) ELSE (
    IF NOT EXIST "!getfolder!*" (
    call :colorecho "Folder is empty" red black
    goto choice
    ) ELSE (
    set "FILESPATH=!getfolder!"
    goto startpatch
    )
    )

    ) ELSE (
    IF ERRORLEVEL 4 (
    REM [E]xtract ZIP
    call :zipfile "!CALLPATH!"
    IF ERRORLEVEL 255 (
    call :colorecho "No suitable extraction program found" darkred black
    goto choice
    )
    IF ERRORLEVEL 2 (
    goto choice
    )
    IF ERRORLEVEL 1 (
    call :colorecho "File selection canceled" darkyellow black
    goto choice
    )
    IF ERRORLEVEL 0 (
    set FILESPATH=!zipfile!
    goto startpatch
    )
    ) ELSE (
    IF ERRORLEVEL 3 (
    REM [G]ame folder
    call :getfolder "Select game installation folder"

    IF [!getfolder!] EQU (
    call :colorecho "Folder selection canceled" darkyellow black
    goto choice
    ) ELSE (
    IF NOT EXIST "!getfolder!*" (
    call :colorecho "Folder is empty" red black
    goto choice
    ) ELSE (
    set "AppPath=!getfolder!"
    goto startpatch
    )
    )
    ) ELSE (
    IF ERRORLEVEL 2 (
    REM [I]nstall
    call :line

    REM call the patching function
    for %%b in (32,64) do (
    IF %%b LEQ !WIN_BITS! (
    call :patch %%b
    IF ERRORLEVEL 1 (
    call :colorecho "Installation for %%b bits was skipped" darkyellow black
    )
    )
    )

    call :line
    call :colorecho "The XignCode Bypasser was successfully installed!" darkgreen black
    ) ELSE (
    REM [Q]uit
    call :line
    call :colorecho "You decided to quit the installer" darkyellow black
    )
    )
    )
    )

    call :kill 0 "More in http://bnsbuddy.com/ and https://www.reddit.com/r/BladeAndSoulMods/"

    REM =====================
    REM FUNCTION DECLARATION!
    REM =====================

    :line
    REM draws a line width the width of the console
    call :repeat _ !WIDTH!
    echo %repeat%
    goto :eof

    :repeat
    REM https://rosettacode.org/wiki/Repeat_a_string#Batch_File
    REM repeats a char n times
    REM %1 = char, %2 = times
    REM exit: 1 = times missing
    setlocal EnableDelayedExpansion

    IF [%2] EQU (
    REM closest thing to a return
    REM explained below
    endlocal & set "repeat="
    exit /b 1
    )
    set char=%1
    for /l %%i in (1,1,%2) do set res=!res!%char%

    REM since %res% is expanded on compilation time
    REM it will have the correct value before endlocal
    REM has any effect, working as a "return"
    endlocal & set "repeat=%res%"
    goto :eof


    :getfolder
    REM fetches a folder path
    REM %1 = title
    setlocal EnableDelayedExpansion

    set txt='Please choose a folder.'
    IF NOT [%1] EQU (
    set txt=%1
    set txt=!txt:"=!
    )

    REM executes the folder dialog - https://stackoverflow.com/a/15885133
    set "cmd="(new-object -COM 'Shell.Application').BrowseForFolder(0,'%txt%',0,0).self.path""
    for /f "usebackq delims=" %%I in (`powershell -NoProfile -Noninteractive -NoLogo %cmd%`) do set "folder=%%I"

    endlocal & set "getfolder=%folder%"
    goto :eof

    :colorecho
    REM prints a message with specific colors
    REM %1 = message, %2 = text color, %3 = background color, %4 = extra arguments (like -NoNewline)
    REM https://www.petri.com/change-powershell-console-font-and-background-colors
    setlocal EnableDelayedExpansion

    powershell -NoProfile -Noninteractive -NoLogo Write-Host %1 -ForegroundColor %2 -BackgroundColor %3 %4

    goto :eof


    :pause
    REM handles the pausing
    REM %1 = message
    setlocal EnableDelayedExpansion

    set a=%1
    echo !a:"=!

    pause >nul

    goto :eof

    :kill
    REM creates the exit messages
    REM %1 = exit code, %2 = message
    setlocal EnableDelayedExpansion

    IF NOT [%2] EQU (
    IF %1 EQU 0 (
    set a=%2
    echo !a:"=!
    ) ELSE (
    call :colorecho %2 red black
    )
    )

    call :pause "Press any key to exit."
    exit %1

    goto :eof

    :patch
    REM function to handle the patching
    REM %1 = bitness
    REM exit: 1 = skipped
    setlocal EnableDelayedExpansion

    set bits=%1
    set folder=!FILESPATH!!bits!
    set dll=bsengine_Shipping
    set target=!AppPath!bin

    IF NOT !bits! EQU 32 (
    REM 64bit paths need treatment -.-
    set dll=!dll!!bits!
    set target=!target!!bits!
    )

    REM make sure the folder with the contents exist
    IF NOT EXIST "!folder!*" (
    call :kill 1 "Folder !bits! does not exist or is empty"
    )

    REM it exists, confirm the remaining
    IF NOT EXIST "!folder!XignCode*" (
    call :kill 1 "Folder !bits!XignCode does not exist or is empty"
    )
    IF NOT EXIST "!folder!!dll!.dll" (
    call :kill 1 "File !bits!!dll!.dll does not exist"
    )

    echo Folder !bits! found, preparing to copy files ...

    REM verifying if the bypasser was already installed may save work
    REM step 1 - verify if the dll exists
    IF EXIST "!target!XignCode!dll!.dll" (
    REM step 2 - compare if they are the same. if they are ...
    fc /b "!folder!!dll!.dll" "!target!XignCode!dll!.dll" >nul
    IF %ERRORLEVEL% EQU 0 (
    REM step 3 - check if the x3.xem file is the same (original one is different)
    fc /b "!folder!XignCodex3.xem" "!target!XignCodex3.xem" >nul
    IF %ERRORLEVEL% EQU 0 (
    REM step 4 - faily certain it's already installed, ask user input
    call :colorecho "The bypasser was already installed for !bits! bits." darkyellow black
    choice /c:yn /n /m "Install anyway? [Y] Yes | [N] No"
    IF ERRORLEVEL 2 (
    exit /b 1
    )
    )
    )
    )

    REM hacky way to echo without a new line
    echo | set /P ="Copying files "
    call :colorecho . darkgreen black -NoNewline

    REM begin copying the directory
    xcopy "!folder!XignCode" "!target!XignCode" /i /s /q /y >nul 2>&1
    IF NOT %ERRORLEVEL% EQU 0 (
    call :colorecho . darkred black
    call :kill 1 "Error (%ERRORLEVEL%) while copying the folder !bits!XignCode"
    )

    call :colorecho . darkgreen black -NoNewline

    REM copy the dll file
    copy "!folder!!dll!.dll" "!target!XignCode!dll!.dll" /b /y >nul 2>&1
    IF NOT %ERRORLEVEL% EQU 0 (
    call :colorecho . darkred black
    call :kill 1 "Error (%ERRORLEVEL%) while copying the file !bits!!dll!.dll"
    )

    call :colorecho . darkgreen black

    goto :eof

    :zipfile
    REM opens a file dialog that allows to choose the zip file
    REM also "returns" the path where the folder is when done
    REM %1 = optional target for extraction
    REM exit: 0 = extracted, 1 = skipped, 2 = failed
    setlocal EnableDelayedExpansion

    REM https://stackoverflow.com/a/50115044
    REM fix for dialog not showing: https://stackoverflow.com/q/216710
    set cmd=powershell -NoProfile -Noninteractive -NoLogo -command "&[System.Reflection.Assembly]::LoadWithPartialName('System.windows.forms')"

    for /f "delims=" %%i in ('!cmd!') do (
    set filedrive=%%~di
    set filepath=%%~pi
    set filename=%%~ni
    set fileext=%%~xi
    )

    IF "!filedrive!!filepath!!filename!!fileext!" EQU "" (
    endlocal & exit /b 1
    )

    set "folder=!filedrive!!filepath!"
    set "file=!filename!!fileext!"

    set target=%~dp1
    IF "!target!" EQU "" (
    SET target=%TEMP%
    )

    set code=255

    REM UNTESTED!!! CAN'T TEST THIS!
    REM https://stackoverflow.com/q/1825585
    set psv=powershell -NoProfile -Noninteractive -NoLogo -command "$psversiontable.PSVersion.Major"
    for /f "tokens=1" %%i in ('!psv!') do (
    IF %%i GEQ 5 (
    echo Using Powershell version %%i to extact
    REM https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6
    powershell -NoProfile -Noninteractive -NoLogo Expand-Archive "!folder!!file!" "!target!!filename!" >nul
    IF NOT %ERRORLEVEL% EQU 0 (
    call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
    set code=2
    ) ELSE (
    endlocal & set "zipfile=%target%%filename%"
    exit /b 0
    )
    )
    )

    REM https://stackoverflow.com/q/14122732
    IF EXIST "%ProgramFiles%7-Zip7z.exe" (
    echo Using 7-Zip to extact
    "%ProgramFiles%7-Zip7z.exe" x "!folder!!file!" -bd -y -o"!target!!filename!" >nul
    IF NOT %ERRORLEVEL% EQU 0 (
    call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
    set code=2
    ) ELSE (
    endlocal & set "zipfile=%target%%filename%"
    exit /b 0
    )
    )

    REM https://stackoverflow.com/a/19337595
    IF EXIST "%ProgramFiles%WinRARwinrar.exe" (
    echo Using WinRAR to extact
    "%ProgramFiles%WinRARwinrar.exe" x -ibck "!folder!!file!" *.* "!target!!filename!" >nul
    IF NOT %ERRORLEVEL% EQU 0 (
    call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
    set code=2
    ) ELSE (
    endlocal & set "zipfile=%target%%filename%"
    exit /b 0
    )
    )

    exit /b !code!


    This script has many functionalities:



    • Automatically fetches the game installation path from the registry

    • Automatically detects the Windows "bitness" (to decide if it patches the 64-bit folder or not)

    • Allows to change the game installation path for the running script

    • Extracts the files and automatically assumes the path where they were extracted to

    • Verifies if it was already installed, allowing to skip or install anyway

    Knowing it is a rather large script, I've tried to split it into multiple functions, to make it easier to understand, read and maintain in the future.



    You can see the complete instruction list on https://github.com/ismael-miguel/xcb-installer



    As far as I know and tested, this is working as it should. All it's functionalities function as intended and there seem to be no obvious errors.



    Regarding readability, error handling and readability, is there anything else I can improve?




    Disclaimer:



    Seeing that this action of bypassing XignCode may be against the Terms and Conditions of the game, I've asked about it on Are we allowed to post questions that allow you to do something that may be against the Terms and Conditions of another software? (to which 13 upvoted the only answer, 1 downvoted).



    This script does not allow you to get the files in any way, shape or form: it only does all the extracting and copying. If you want the files, you have to get them by yourself. I do not want to make it any easier to get the needed files.



    Batch is a language I'm not familiar with, requiring me to learn a lot from all the websites and links available in comments.







    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      As the title says, this batch script installs the XignCode Bypasser.



      Xigncode is a software bundled with games to analise running programs and prevent cheating. (Sometimes, it prevents the game to load at all on the newest Windows releases.)



      For this, a bypasser was created that disables this check, allowing players to run the game (if they couldn't), mod the game (One Click Tool, for example) and (if you want) cheat.



      Copying the files manually is a boring task that can lead to mistakes (copying from the wrong location, deleting the Bypasser by mistake, ....).



      For that, I've made the following batch script that does all the copying and extraction:



      @echo off

      REM set the title - https://stackoverflow.com/a/39329524
      title XignCode Bypasser installer
      color 07

      REM config
      setlocal EnableDelayedExpansion
      set CALLPATH=%~dp0
      set FILESPATH=!CALLPATH!
      set WIN_BITS=64
      set REGKEY="HKEY_LOCAL_MACHINESOFTWAREWow6432NodeNCWestBnS"

      REM needs administrator rights - https://stackoverflow.com/a/21295806
      REM we run fsutil to check the error code. 0 = admin
      fsutil dirty query %SystemDrive% >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :kill 1 "You need to execute as administrator"
      )

      REM detect the bitness and fixes values - https://superuser.com/a/268384
      echo %PROCESSOR_ARCHITECTURE% | find /i "x86" >nul
      IF %ERRORLEVEL% EQU 0 (
      set WIN_BITS=32
      set REGKEY="HKEY_LOCAL_MACHINESOFTWARENCWestBnS"
      )

      REM checks if the game is running - https://stackoverflow.com/a/1329790
      tasklist /FI "WINDOWTITLE eq Blade & Soul" 2>nul | find /I /N "Client.exe" >nul
      IF %ERRORLEVEL% EQU 0 (
      call :kill 1 "Close the game before installing the Xigncode Bypasser"
      )

      set WIDTH=80
      for /f "tokens=1*" %%a in ('mode con') do (
      IF "%%a" EQU "Columns:" (
      set "WIDTH=%%b"
      )
      )

      REM this key is required - https://stackoverflow.com/a/445323
      REM we check if it exists before trying to run the code
      REG QUERY !REGKEY! >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      REM call :kill 1 "Registry key !REGKEY! not found"
      call :colorecho "Registry key !REGKEY! not found" red black
      call :pause "Press any key to select the game installation directory"
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :kill 1 "Folder selection canceled"
      )
      set "AppPath=!getfolder!"
      ) ELSE (
      REM fetches the data in the registry
      for /f "tokens=2*" %%a in ('REG QUERY !REGKEY! /v BaseDir') do set "AppPath=%%~b"

      IF NOT EXIST "!AppPath!*" (
      call :colorecho "!AppPath! does not exist or is empty" red black
      call :pause "Press any key to select the game installation directory"
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :kill 1 "Folder selection canceled"
      )
      set "AppPath=!getfolder!"
      )
      )

      :startpatch
      REM ready to replace everything

      cls
      call :colorecho "This will install the XignCode Bypasser" black gray
      call :line
      echo Game installation: !AppPath!
      echo Files in: !FILESPATH!
      echo Detected !WIN_BITS! bit Windows installation
      call :line

      :choice
      echo What to do next?
      choice /c:qigeb /n /m "[Q]uit | [I]nstall | [G]ame folder | [B]ypasser folder | [E]xtract ZIP"

      IF ERRORLEVEL 5 (
      REM [B]ypasser folder

      call :getfolder "Select XignCode Bypasser folder"

      IF [!getfolder!] EQU (
      call :colorecho "Folder selection canceled" darkyellow black
      goto choice
      ) ELSE (
      IF NOT EXIST "!getfolder!*" (
      call :colorecho "Folder is empty" red black
      goto choice
      ) ELSE (
      set "FILESPATH=!getfolder!"
      goto startpatch
      )
      )

      ) ELSE (
      IF ERRORLEVEL 4 (
      REM [E]xtract ZIP
      call :zipfile "!CALLPATH!"
      IF ERRORLEVEL 255 (
      call :colorecho "No suitable extraction program found" darkred black
      goto choice
      )
      IF ERRORLEVEL 2 (
      goto choice
      )
      IF ERRORLEVEL 1 (
      call :colorecho "File selection canceled" darkyellow black
      goto choice
      )
      IF ERRORLEVEL 0 (
      set FILESPATH=!zipfile!
      goto startpatch
      )
      ) ELSE (
      IF ERRORLEVEL 3 (
      REM [G]ame folder
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :colorecho "Folder selection canceled" darkyellow black
      goto choice
      ) ELSE (
      IF NOT EXIST "!getfolder!*" (
      call :colorecho "Folder is empty" red black
      goto choice
      ) ELSE (
      set "AppPath=!getfolder!"
      goto startpatch
      )
      )
      ) ELSE (
      IF ERRORLEVEL 2 (
      REM [I]nstall
      call :line

      REM call the patching function
      for %%b in (32,64) do (
      IF %%b LEQ !WIN_BITS! (
      call :patch %%b
      IF ERRORLEVEL 1 (
      call :colorecho "Installation for %%b bits was skipped" darkyellow black
      )
      )
      )

      call :line
      call :colorecho "The XignCode Bypasser was successfully installed!" darkgreen black
      ) ELSE (
      REM [Q]uit
      call :line
      call :colorecho "You decided to quit the installer" darkyellow black
      )
      )
      )
      )

      call :kill 0 "More in http://bnsbuddy.com/ and https://www.reddit.com/r/BladeAndSoulMods/"

      REM =====================
      REM FUNCTION DECLARATION!
      REM =====================

      :line
      REM draws a line width the width of the console
      call :repeat _ !WIDTH!
      echo %repeat%
      goto :eof

      :repeat
      REM https://rosettacode.org/wiki/Repeat_a_string#Batch_File
      REM repeats a char n times
      REM %1 = char, %2 = times
      REM exit: 1 = times missing
      setlocal EnableDelayedExpansion

      IF [%2] EQU (
      REM closest thing to a return
      REM explained below
      endlocal & set "repeat="
      exit /b 1
      )
      set char=%1
      for /l %%i in (1,1,%2) do set res=!res!%char%

      REM since %res% is expanded on compilation time
      REM it will have the correct value before endlocal
      REM has any effect, working as a "return"
      endlocal & set "repeat=%res%"
      goto :eof


      :getfolder
      REM fetches a folder path
      REM %1 = title
      setlocal EnableDelayedExpansion

      set txt='Please choose a folder.'
      IF NOT [%1] EQU (
      set txt=%1
      set txt=!txt:"=!
      )

      REM executes the folder dialog - https://stackoverflow.com/a/15885133
      set "cmd="(new-object -COM 'Shell.Application').BrowseForFolder(0,'%txt%',0,0).self.path""
      for /f "usebackq delims=" %%I in (`powershell -NoProfile -Noninteractive -NoLogo %cmd%`) do set "folder=%%I"

      endlocal & set "getfolder=%folder%"
      goto :eof

      :colorecho
      REM prints a message with specific colors
      REM %1 = message, %2 = text color, %3 = background color, %4 = extra arguments (like -NoNewline)
      REM https://www.petri.com/change-powershell-console-font-and-background-colors
      setlocal EnableDelayedExpansion

      powershell -NoProfile -Noninteractive -NoLogo Write-Host %1 -ForegroundColor %2 -BackgroundColor %3 %4

      goto :eof


      :pause
      REM handles the pausing
      REM %1 = message
      setlocal EnableDelayedExpansion

      set a=%1
      echo !a:"=!

      pause >nul

      goto :eof

      :kill
      REM creates the exit messages
      REM %1 = exit code, %2 = message
      setlocal EnableDelayedExpansion

      IF NOT [%2] EQU (
      IF %1 EQU 0 (
      set a=%2
      echo !a:"=!
      ) ELSE (
      call :colorecho %2 red black
      )
      )

      call :pause "Press any key to exit."
      exit %1

      goto :eof

      :patch
      REM function to handle the patching
      REM %1 = bitness
      REM exit: 1 = skipped
      setlocal EnableDelayedExpansion

      set bits=%1
      set folder=!FILESPATH!!bits!
      set dll=bsengine_Shipping
      set target=!AppPath!bin

      IF NOT !bits! EQU 32 (
      REM 64bit paths need treatment -.-
      set dll=!dll!!bits!
      set target=!target!!bits!
      )

      REM make sure the folder with the contents exist
      IF NOT EXIST "!folder!*" (
      call :kill 1 "Folder !bits! does not exist or is empty"
      )

      REM it exists, confirm the remaining
      IF NOT EXIST "!folder!XignCode*" (
      call :kill 1 "Folder !bits!XignCode does not exist or is empty"
      )
      IF NOT EXIST "!folder!!dll!.dll" (
      call :kill 1 "File !bits!!dll!.dll does not exist"
      )

      echo Folder !bits! found, preparing to copy files ...

      REM verifying if the bypasser was already installed may save work
      REM step 1 - verify if the dll exists
      IF EXIST "!target!XignCode!dll!.dll" (
      REM step 2 - compare if they are the same. if they are ...
      fc /b "!folder!!dll!.dll" "!target!XignCode!dll!.dll" >nul
      IF %ERRORLEVEL% EQU 0 (
      REM step 3 - check if the x3.xem file is the same (original one is different)
      fc /b "!folder!XignCodex3.xem" "!target!XignCodex3.xem" >nul
      IF %ERRORLEVEL% EQU 0 (
      REM step 4 - faily certain it's already installed, ask user input
      call :colorecho "The bypasser was already installed for !bits! bits." darkyellow black
      choice /c:yn /n /m "Install anyway? [Y] Yes | [N] No"
      IF ERRORLEVEL 2 (
      exit /b 1
      )
      )
      )
      )

      REM hacky way to echo without a new line
      echo | set /P ="Copying files "
      call :colorecho . darkgreen black -NoNewline

      REM begin copying the directory
      xcopy "!folder!XignCode" "!target!XignCode" /i /s /q /y >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho . darkred black
      call :kill 1 "Error (%ERRORLEVEL%) while copying the folder !bits!XignCode"
      )

      call :colorecho . darkgreen black -NoNewline

      REM copy the dll file
      copy "!folder!!dll!.dll" "!target!XignCode!dll!.dll" /b /y >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho . darkred black
      call :kill 1 "Error (%ERRORLEVEL%) while copying the file !bits!!dll!.dll"
      )

      call :colorecho . darkgreen black

      goto :eof

      :zipfile
      REM opens a file dialog that allows to choose the zip file
      REM also "returns" the path where the folder is when done
      REM %1 = optional target for extraction
      REM exit: 0 = extracted, 1 = skipped, 2 = failed
      setlocal EnableDelayedExpansion

      REM https://stackoverflow.com/a/50115044
      REM fix for dialog not showing: https://stackoverflow.com/q/216710
      set cmd=powershell -NoProfile -Noninteractive -NoLogo -command "&[System.Reflection.Assembly]::LoadWithPartialName('System.windows.forms')"

      for /f "delims=" %%i in ('!cmd!') do (
      set filedrive=%%~di
      set filepath=%%~pi
      set filename=%%~ni
      set fileext=%%~xi
      )

      IF "!filedrive!!filepath!!filename!!fileext!" EQU "" (
      endlocal & exit /b 1
      )

      set "folder=!filedrive!!filepath!"
      set "file=!filename!!fileext!"

      set target=%~dp1
      IF "!target!" EQU "" (
      SET target=%TEMP%
      )

      set code=255

      REM UNTESTED!!! CAN'T TEST THIS!
      REM https://stackoverflow.com/q/1825585
      set psv=powershell -NoProfile -Noninteractive -NoLogo -command "$psversiontable.PSVersion.Major"
      for /f "tokens=1" %%i in ('!psv!') do (
      IF %%i GEQ 5 (
      echo Using Powershell version %%i to extact
      REM https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6
      powershell -NoProfile -Noninteractive -NoLogo Expand-Archive "!folder!!file!" "!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )
      )

      REM https://stackoverflow.com/q/14122732
      IF EXIST "%ProgramFiles%7-Zip7z.exe" (
      echo Using 7-Zip to extact
      "%ProgramFiles%7-Zip7z.exe" x "!folder!!file!" -bd -y -o"!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )

      REM https://stackoverflow.com/a/19337595
      IF EXIST "%ProgramFiles%WinRARwinrar.exe" (
      echo Using WinRAR to extact
      "%ProgramFiles%WinRARwinrar.exe" x -ibck "!folder!!file!" *.* "!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )

      exit /b !code!


      This script has many functionalities:



      • Automatically fetches the game installation path from the registry

      • Automatically detects the Windows "bitness" (to decide if it patches the 64-bit folder or not)

      • Allows to change the game installation path for the running script

      • Extracts the files and automatically assumes the path where they were extracted to

      • Verifies if it was already installed, allowing to skip or install anyway

      Knowing it is a rather large script, I've tried to split it into multiple functions, to make it easier to understand, read and maintain in the future.



      You can see the complete instruction list on https://github.com/ismael-miguel/xcb-installer



      As far as I know and tested, this is working as it should. All it's functionalities function as intended and there seem to be no obvious errors.



      Regarding readability, error handling and readability, is there anything else I can improve?




      Disclaimer:



      Seeing that this action of bypassing XignCode may be against the Terms and Conditions of the game, I've asked about it on Are we allowed to post questions that allow you to do something that may be against the Terms and Conditions of another software? (to which 13 upvoted the only answer, 1 downvoted).



      This script does not allow you to get the files in any way, shape or form: it only does all the extracting and copying. If you want the files, you have to get them by yourself. I do not want to make it any easier to get the needed files.



      Batch is a language I'm not familiar with, requiring me to learn a lot from all the websites and links available in comments.







      share|improve this question













      As the title says, this batch script installs the XignCode Bypasser.



      Xigncode is a software bundled with games to analise running programs and prevent cheating. (Sometimes, it prevents the game to load at all on the newest Windows releases.)



      For this, a bypasser was created that disables this check, allowing players to run the game (if they couldn't), mod the game (One Click Tool, for example) and (if you want) cheat.



      Copying the files manually is a boring task that can lead to mistakes (copying from the wrong location, deleting the Bypasser by mistake, ....).



      For that, I've made the following batch script that does all the copying and extraction:



      @echo off

      REM set the title - https://stackoverflow.com/a/39329524
      title XignCode Bypasser installer
      color 07

      REM config
      setlocal EnableDelayedExpansion
      set CALLPATH=%~dp0
      set FILESPATH=!CALLPATH!
      set WIN_BITS=64
      set REGKEY="HKEY_LOCAL_MACHINESOFTWAREWow6432NodeNCWestBnS"

      REM needs administrator rights - https://stackoverflow.com/a/21295806
      REM we run fsutil to check the error code. 0 = admin
      fsutil dirty query %SystemDrive% >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :kill 1 "You need to execute as administrator"
      )

      REM detect the bitness and fixes values - https://superuser.com/a/268384
      echo %PROCESSOR_ARCHITECTURE% | find /i "x86" >nul
      IF %ERRORLEVEL% EQU 0 (
      set WIN_BITS=32
      set REGKEY="HKEY_LOCAL_MACHINESOFTWARENCWestBnS"
      )

      REM checks if the game is running - https://stackoverflow.com/a/1329790
      tasklist /FI "WINDOWTITLE eq Blade & Soul" 2>nul | find /I /N "Client.exe" >nul
      IF %ERRORLEVEL% EQU 0 (
      call :kill 1 "Close the game before installing the Xigncode Bypasser"
      )

      set WIDTH=80
      for /f "tokens=1*" %%a in ('mode con') do (
      IF "%%a" EQU "Columns:" (
      set "WIDTH=%%b"
      )
      )

      REM this key is required - https://stackoverflow.com/a/445323
      REM we check if it exists before trying to run the code
      REG QUERY !REGKEY! >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      REM call :kill 1 "Registry key !REGKEY! not found"
      call :colorecho "Registry key !REGKEY! not found" red black
      call :pause "Press any key to select the game installation directory"
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :kill 1 "Folder selection canceled"
      )
      set "AppPath=!getfolder!"
      ) ELSE (
      REM fetches the data in the registry
      for /f "tokens=2*" %%a in ('REG QUERY !REGKEY! /v BaseDir') do set "AppPath=%%~b"

      IF NOT EXIST "!AppPath!*" (
      call :colorecho "!AppPath! does not exist or is empty" red black
      call :pause "Press any key to select the game installation directory"
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :kill 1 "Folder selection canceled"
      )
      set "AppPath=!getfolder!"
      )
      )

      :startpatch
      REM ready to replace everything

      cls
      call :colorecho "This will install the XignCode Bypasser" black gray
      call :line
      echo Game installation: !AppPath!
      echo Files in: !FILESPATH!
      echo Detected !WIN_BITS! bit Windows installation
      call :line

      :choice
      echo What to do next?
      choice /c:qigeb /n /m "[Q]uit | [I]nstall | [G]ame folder | [B]ypasser folder | [E]xtract ZIP"

      IF ERRORLEVEL 5 (
      REM [B]ypasser folder

      call :getfolder "Select XignCode Bypasser folder"

      IF [!getfolder!] EQU (
      call :colorecho "Folder selection canceled" darkyellow black
      goto choice
      ) ELSE (
      IF NOT EXIST "!getfolder!*" (
      call :colorecho "Folder is empty" red black
      goto choice
      ) ELSE (
      set "FILESPATH=!getfolder!"
      goto startpatch
      )
      )

      ) ELSE (
      IF ERRORLEVEL 4 (
      REM [E]xtract ZIP
      call :zipfile "!CALLPATH!"
      IF ERRORLEVEL 255 (
      call :colorecho "No suitable extraction program found" darkred black
      goto choice
      )
      IF ERRORLEVEL 2 (
      goto choice
      )
      IF ERRORLEVEL 1 (
      call :colorecho "File selection canceled" darkyellow black
      goto choice
      )
      IF ERRORLEVEL 0 (
      set FILESPATH=!zipfile!
      goto startpatch
      )
      ) ELSE (
      IF ERRORLEVEL 3 (
      REM [G]ame folder
      call :getfolder "Select game installation folder"

      IF [!getfolder!] EQU (
      call :colorecho "Folder selection canceled" darkyellow black
      goto choice
      ) ELSE (
      IF NOT EXIST "!getfolder!*" (
      call :colorecho "Folder is empty" red black
      goto choice
      ) ELSE (
      set "AppPath=!getfolder!"
      goto startpatch
      )
      )
      ) ELSE (
      IF ERRORLEVEL 2 (
      REM [I]nstall
      call :line

      REM call the patching function
      for %%b in (32,64) do (
      IF %%b LEQ !WIN_BITS! (
      call :patch %%b
      IF ERRORLEVEL 1 (
      call :colorecho "Installation for %%b bits was skipped" darkyellow black
      )
      )
      )

      call :line
      call :colorecho "The XignCode Bypasser was successfully installed!" darkgreen black
      ) ELSE (
      REM [Q]uit
      call :line
      call :colorecho "You decided to quit the installer" darkyellow black
      )
      )
      )
      )

      call :kill 0 "More in http://bnsbuddy.com/ and https://www.reddit.com/r/BladeAndSoulMods/"

      REM =====================
      REM FUNCTION DECLARATION!
      REM =====================

      :line
      REM draws a line width the width of the console
      call :repeat _ !WIDTH!
      echo %repeat%
      goto :eof

      :repeat
      REM https://rosettacode.org/wiki/Repeat_a_string#Batch_File
      REM repeats a char n times
      REM %1 = char, %2 = times
      REM exit: 1 = times missing
      setlocal EnableDelayedExpansion

      IF [%2] EQU (
      REM closest thing to a return
      REM explained below
      endlocal & set "repeat="
      exit /b 1
      )
      set char=%1
      for /l %%i in (1,1,%2) do set res=!res!%char%

      REM since %res% is expanded on compilation time
      REM it will have the correct value before endlocal
      REM has any effect, working as a "return"
      endlocal & set "repeat=%res%"
      goto :eof


      :getfolder
      REM fetches a folder path
      REM %1 = title
      setlocal EnableDelayedExpansion

      set txt='Please choose a folder.'
      IF NOT [%1] EQU (
      set txt=%1
      set txt=!txt:"=!
      )

      REM executes the folder dialog - https://stackoverflow.com/a/15885133
      set "cmd="(new-object -COM 'Shell.Application').BrowseForFolder(0,'%txt%',0,0).self.path""
      for /f "usebackq delims=" %%I in (`powershell -NoProfile -Noninteractive -NoLogo %cmd%`) do set "folder=%%I"

      endlocal & set "getfolder=%folder%"
      goto :eof

      :colorecho
      REM prints a message with specific colors
      REM %1 = message, %2 = text color, %3 = background color, %4 = extra arguments (like -NoNewline)
      REM https://www.petri.com/change-powershell-console-font-and-background-colors
      setlocal EnableDelayedExpansion

      powershell -NoProfile -Noninteractive -NoLogo Write-Host %1 -ForegroundColor %2 -BackgroundColor %3 %4

      goto :eof


      :pause
      REM handles the pausing
      REM %1 = message
      setlocal EnableDelayedExpansion

      set a=%1
      echo !a:"=!

      pause >nul

      goto :eof

      :kill
      REM creates the exit messages
      REM %1 = exit code, %2 = message
      setlocal EnableDelayedExpansion

      IF NOT [%2] EQU (
      IF %1 EQU 0 (
      set a=%2
      echo !a:"=!
      ) ELSE (
      call :colorecho %2 red black
      )
      )

      call :pause "Press any key to exit."
      exit %1

      goto :eof

      :patch
      REM function to handle the patching
      REM %1 = bitness
      REM exit: 1 = skipped
      setlocal EnableDelayedExpansion

      set bits=%1
      set folder=!FILESPATH!!bits!
      set dll=bsengine_Shipping
      set target=!AppPath!bin

      IF NOT !bits! EQU 32 (
      REM 64bit paths need treatment -.-
      set dll=!dll!!bits!
      set target=!target!!bits!
      )

      REM make sure the folder with the contents exist
      IF NOT EXIST "!folder!*" (
      call :kill 1 "Folder !bits! does not exist or is empty"
      )

      REM it exists, confirm the remaining
      IF NOT EXIST "!folder!XignCode*" (
      call :kill 1 "Folder !bits!XignCode does not exist or is empty"
      )
      IF NOT EXIST "!folder!!dll!.dll" (
      call :kill 1 "File !bits!!dll!.dll does not exist"
      )

      echo Folder !bits! found, preparing to copy files ...

      REM verifying if the bypasser was already installed may save work
      REM step 1 - verify if the dll exists
      IF EXIST "!target!XignCode!dll!.dll" (
      REM step 2 - compare if they are the same. if they are ...
      fc /b "!folder!!dll!.dll" "!target!XignCode!dll!.dll" >nul
      IF %ERRORLEVEL% EQU 0 (
      REM step 3 - check if the x3.xem file is the same (original one is different)
      fc /b "!folder!XignCodex3.xem" "!target!XignCodex3.xem" >nul
      IF %ERRORLEVEL% EQU 0 (
      REM step 4 - faily certain it's already installed, ask user input
      call :colorecho "The bypasser was already installed for !bits! bits." darkyellow black
      choice /c:yn /n /m "Install anyway? [Y] Yes | [N] No"
      IF ERRORLEVEL 2 (
      exit /b 1
      )
      )
      )
      )

      REM hacky way to echo without a new line
      echo | set /P ="Copying files "
      call :colorecho . darkgreen black -NoNewline

      REM begin copying the directory
      xcopy "!folder!XignCode" "!target!XignCode" /i /s /q /y >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho . darkred black
      call :kill 1 "Error (%ERRORLEVEL%) while copying the folder !bits!XignCode"
      )

      call :colorecho . darkgreen black -NoNewline

      REM copy the dll file
      copy "!folder!!dll!.dll" "!target!XignCode!dll!.dll" /b /y >nul 2>&1
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho . darkred black
      call :kill 1 "Error (%ERRORLEVEL%) while copying the file !bits!!dll!.dll"
      )

      call :colorecho . darkgreen black

      goto :eof

      :zipfile
      REM opens a file dialog that allows to choose the zip file
      REM also "returns" the path where the folder is when done
      REM %1 = optional target for extraction
      REM exit: 0 = extracted, 1 = skipped, 2 = failed
      setlocal EnableDelayedExpansion

      REM https://stackoverflow.com/a/50115044
      REM fix for dialog not showing: https://stackoverflow.com/q/216710
      set cmd=powershell -NoProfile -Noninteractive -NoLogo -command "&[System.Reflection.Assembly]::LoadWithPartialName('System.windows.forms')"

      for /f "delims=" %%i in ('!cmd!') do (
      set filedrive=%%~di
      set filepath=%%~pi
      set filename=%%~ni
      set fileext=%%~xi
      )

      IF "!filedrive!!filepath!!filename!!fileext!" EQU "" (
      endlocal & exit /b 1
      )

      set "folder=!filedrive!!filepath!"
      set "file=!filename!!fileext!"

      set target=%~dp1
      IF "!target!" EQU "" (
      SET target=%TEMP%
      )

      set code=255

      REM UNTESTED!!! CAN'T TEST THIS!
      REM https://stackoverflow.com/q/1825585
      set psv=powershell -NoProfile -Noninteractive -NoLogo -command "$psversiontable.PSVersion.Major"
      for /f "tokens=1" %%i in ('!psv!') do (
      IF %%i GEQ 5 (
      echo Using Powershell version %%i to extact
      REM https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6
      powershell -NoProfile -Noninteractive -NoLogo Expand-Archive "!folder!!file!" "!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )
      )

      REM https://stackoverflow.com/q/14122732
      IF EXIST "%ProgramFiles%7-Zip7z.exe" (
      echo Using 7-Zip to extact
      "%ProgramFiles%7-Zip7z.exe" x "!folder!!file!" -bd -y -o"!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )

      REM https://stackoverflow.com/a/19337595
      IF EXIST "%ProgramFiles%WinRARwinrar.exe" (
      echo Using WinRAR to extact
      "%ProgramFiles%WinRARwinrar.exe" x -ibck "!folder!!file!" *.* "!target!!filename!" >nul
      IF NOT %ERRORLEVEL% EQU 0 (
      call :colorecho "Failed to extract: error %ERRORLEVEL%" red black
      set code=2
      ) ELSE (
      endlocal & set "zipfile=%target%%filename%"
      exit /b 0
      )
      )

      exit /b !code!


      This script has many functionalities:



      • Automatically fetches the game installation path from the registry

      • Automatically detects the Windows "bitness" (to decide if it patches the 64-bit folder or not)

      • Allows to change the game installation path for the running script

      • Extracts the files and automatically assumes the path where they were extracted to

      • Verifies if it was already installed, allowing to skip or install anyway

      Knowing it is a rather large script, I've tried to split it into multiple functions, to make it easier to understand, read and maintain in the future.



      You can see the complete instruction list on https://github.com/ismael-miguel/xcb-installer



      As far as I know and tested, this is working as it should. All it's functionalities function as intended and there seem to be no obvious errors.



      Regarding readability, error handling and readability, is there anything else I can improve?




      Disclaimer:



      Seeing that this action of bypassing XignCode may be against the Terms and Conditions of the game, I've asked about it on Are we allowed to post questions that allow you to do something that may be against the Terms and Conditions of another software? (to which 13 upvoted the only answer, 1 downvoted).



      This script does not allow you to get the files in any way, shape or form: it only does all the extracting and copying. If you want the files, you have to get them by yourself. I do not want to make it any easier to get the needed files.



      Batch is a language I'm not familiar with, requiring me to learn a lot from all the websites and links available in comments.









      share|improve this question












      share|improve this question




      share|improve this question








      edited May 14 at 19:53
























      asked May 8 at 21:27









      Ismael Miguel

      4,21111050




      4,21111050

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193958%2fxigncode-bypasser-installer-for-blade-soul%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193958%2fxigncode-bypasser-installer-for-blade-soul%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?