@echo off
setlocal enabledelayedexpansion

REM --- BF2142 Player Name Changer ---------------------------------------------
REM Place this file in the Battlefield 2142 install root (next to BF2142.exe).
REM It rewrites every config that stores the player nickname so each LAN
REM machine ends up with a unique name. Touches:
REM
REM   %USERPROFILE%\Documents\Battlefield 2142\Profiles\Global.con
REM   %USERPROFILE%\Documents\Battlefield 2142\Profiles\<ACTIVE>\Profile.con
REM   <Install>\mods\bf2142\Settings\Usersettings.con
REM   <Install>\mods\bf2142\Settings\Profiles\Custom\GeneralOptions.con
REM
REM Every file that changes is backed up to *.bak (first run only).
REM ----------------------------------------------------------------------------

set "ROOT=%~dp0"
set "INSTALL_SETTINGS=%ROOT%mods\bf2142\Settings"
set "DOCS_ROOT=%USERPROFILE%\Documents\Battlefield 2142"
set "DOCS_PROFILES=%DOCS_ROOT%\Profiles"

if not exist "%ROOT%BF2142.exe" (
    echo [!] BF2142.exe not found next to this script.
    echo     Put ChangePlayerName.bat in the same folder as BF2142.exe.
    echo     Current folder: %ROOT%
    pause
    exit /b 1
)

echo.
echo ============================================================
echo   Battlefield 2142 - Player Name Changer
echo ============================================================
echo.
echo Install profiles root : %INSTALL_SETTINGS%
echo Documents profiles    : %DOCS_PROFILES%
echo.

REM ---- Locate active profile ID from Global.con ------------------------------
set "ACTIVE_ID="
if exist "%DOCS_PROFILES%\Global.con" (
    for /f "tokens=2 delims= " %%A in ('findstr /C:"setDefaultUser" "%DOCS_PROFILES%\Global.con"') do (
        set "ACTIVE_ID=%%~A"
    )
)
if defined ACTIVE_ID (
    echo Active profile folder : !ACTIVE_ID!
) else (
    echo Active profile folder : ^(not detected - will update install files only^)
)
echo.

echo Current names on disk:
for %%F in (
    "%DOCS_PROFILES%\Global.con"
    "%INSTALL_SETTINGS%\Usersettings.con"
    "%INSTALL_SETTINGS%\Profiles\Custom\GeneralOptions.con"
) do (
    if exist "%%~F" (
        echo   [%%~nxF]
        findstr /R /C:"setLastOnlineUser" /C:"GSPlayerName" /C:"setPlayerName" "%%~F" 2>nul
    )
)
if defined ACTIVE_ID if exist "%DOCS_PROFILES%\!ACTIVE_ID!\Profile.con" (
    echo   [Profile.con in !ACTIVE_ID!]
    findstr /R /C:"setName " /C:"setEAOnline" "%DOCS_PROFILES%\!ACTIVE_ID!\Profile.con" 2>nul
)
echo.

:ASK
set "NEWNAME="
set /p "NEWNAME=Enter new player name (1-16 chars, no quotes/backslash/%%): "
if "!NEWNAME!"=="" (
    echo     Name cannot be empty.
    goto ASK
)

REM Reject quotes, backslashes, percent.
echo(!NEWNAME!| findstr /R "[\"\\%%]" >nul && (
    echo     Forbidden character in name.
    goto ASK
)

REM Length check (<=16).
set "LEN=0"
set "TMP=!NEWNAME!"
:LENLOOP
if defined TMP (
    set "TMP=!TMP:~1!"
    set /a LEN+=1
    goto LENLOOP
)
if !LEN! GTR 16 (
    echo     Name is !LEN! chars; max is 16.
    goto ASK
)

echo.
echo Applying name: !NEWNAME!
echo.

REM Pass values through env vars so PowerShell doesn't see any quoting issues.
set "BF2142_NEWNAME=!NEWNAME!"
set "BF2142_INSTALL_SETTINGS=%INSTALL_SETTINGS%"
set "BF2142_DOCS_PROFILES=%DOCS_PROFILES%"
set "BF2142_ACTIVE_ID=!ACTIVE_ID!"

REM --- Write the worker PowerShell script to a temp file ----------------------
REM (Doing it this way avoids cmd's caret/quote escaping hell that would hit us
REM  if we tried to inline the PS on the command line.)
set "PSFILE=%TEMP%\BF2142_ChangePlayerName_%RANDOM%.ps1"

> "%PSFILE%" echo $name    = $env:BF2142_NEWNAME
>>"%PSFILE%" echo $install = $env:BF2142_INSTALL_SETTINGS
>>"%PSFILE%" echo $docs    = $env:BF2142_DOCS_PROFILES
>>"%PSFILE%" echo $active  = $env:BF2142_ACTIVE_ID
>>"%PSFILE%" echo.
>>"%PSFILE%" echo function Patch($path, $rules) {
>>"%PSFILE%" echo   if (-not (Test-Path -LiteralPath $path)) { Write-Host "  skip  : $path"; return }
>>"%PSFILE%" echo   $bak = "$path.bak"
>>"%PSFILE%" echo   if (-not (Test-Path -LiteralPath $bak)) { Copy-Item -LiteralPath $path -Destination $bak -Force }
>>"%PSFILE%" echo   $text = Get-Content -LiteralPath $path -Raw
>>"%PSFILE%" echo   $orig = $text
>>"%PSFILE%" echo   foreach ($r in $rules) { $text = [regex]::Replace($text, $r.Pattern, $r.Replacement) }
>>"%PSFILE%" echo   if ($text -ne $orig) {
>>"%PSFILE%" echo     Set-Content -LiteralPath $path -Value $text -NoNewline -Encoding ASCII
>>"%PSFILE%" echo     Write-Host "  wrote : $path"
>>"%PSFILE%" echo   } else {
>>"%PSFILE%" echo     Write-Host "  noop  : $path"
>>"%PSFILE%" echo   }
>>"%PSFILE%" echo }
>>"%PSFILE%" echo.
>>"%PSFILE%" echo $docRules = @(
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(setLastOnlineUser\s+)"[^"]*"'; Replacement=('${1}"' + $name + '"')}
>>"%PSFILE%" echo )
>>"%PSFILE%" echo $profRules = @(
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(LocalProfile\.setName\s+)"[^"]*"';                  Replacement=('${1}"' + $name + '"')},
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(LocalProfile\.setEAOnlineMasterAccount\s+)"[^"]*"'; Replacement=('${1}"' + $name + '"')},
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(LocalProfile\.setEAOnlineSubAccount\s+)"[^"]*"';    Replacement=('${1}"' + $name + '"')}
>>"%PSFILE%" echo )
>>"%PSFILE%" echo $installRules = @(
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(GSPlayerName\s+)"[^"]*"';         Replacement=('${1}"' + $name + '"')},
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(game\.setPlayerName\s+)"[^"]*"'; Replacement=('${1}"' + $name + '"')},
>>"%PSFILE%" echo   [pscustomobject]@{Pattern='(?m)^PlayerName=.*$';               Replacement=('PlayerName=' + $name)}
>>"%PSFILE%" echo )
>>"%PSFILE%" echo.
>>"%PSFILE%" echo Patch (Join-Path $docs 'Global.con') $docRules
>>"%PSFILE%" echo if ($active) {
>>"%PSFILE%" echo   Patch (Join-Path $docs (Join-Path $active 'Profile.con')) $profRules
>>"%PSFILE%" echo } else {
>>"%PSFILE%" echo   Write-Host '  skip  : ^<active^>/Profile.con (no active profile id)'
>>"%PSFILE%" echo }
>>"%PSFILE%" echo Patch (Join-Path $install 'Usersettings.con') $installRules
>>"%PSFILE%" echo Patch (Join-Path $install 'Profiles\Custom\GeneralOptions.con') $installRules

powershell -NoProfile -ExecutionPolicy Bypass -File "%PSFILE%"
set "PSRC=%ERRORLEVEL%"

del /q "%PSFILE%" >nul 2>&1
set "BF2142_NEWNAME="
set "BF2142_INSTALL_SETTINGS="
set "BF2142_DOCS_PROFILES="
set "BF2142_ACTIVE_ID="

if not "%PSRC%"=="0" (
    echo.
    echo [!] PowerShell returned exit code %PSRC%. Originals are in *.bak next to each file.
    pause
    exit /b %PSRC%
)

echo.
echo Done. Launch BF2142 and confirm the new name shows in-game and in the LAN browser.
echo If something looks wrong, restore the *.bak files next to each affected .con.
echo.
pause
endlocal
