This repository has been archived on 2026-10-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
rsx-modloader/scripts/install.ps1
T
SashegDev b8e5df778e Модлоадер RustexRemake: агент, патч лаунчера, установщик и сборка
Моды грузятся через -javaagent, game.jar не патчится, переживают ре-обфускацию.

Что внутри:
- агент rsx-bridge.jar: профиль сборки игры, патчи A2/A6, загрузка модов
  через родной загрузчик игры (ilxq -> special.Main)
- патч лаунчера: окно выбора «С модами / Ванилла» по кнопке «Играть»
  и защита от автоапдейта лаунчера
- install/uninstall: всё ставится в %LOCALAPPDATA%\rsx-mod, пути не хардкодятся
- build: три готовых артефакта в dist, нужен только JDK
- testserver: локальный сервер, принимает любой ник и токен

Проверено на живом клиенте: мод грузится и выполняется в игровом потоке,
в логе видно игрока и мир.
2026-10-17 00:32:10 +03:00

188 lines
7.5 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Installs the modloader: copies the runtime files, patches the launcher and
# wires the agent into the launcher config.
#
# install.cmd normal install
# install.cmd --uninstall put everything back
# install.cmd --home <path> install the runtime somewhere else
# install.cmd --game <path> point at a specific game installation
$ErrorActionPreference = 'Stop'
$Repo = Split-Path -Parent $PSScriptRoot
if (-not $Repo) { $Repo = $PSCommandPath | Split-Path -Parent | Split-Path -Parent }
$LauncherHome = Join-Path $env:APPDATA 'kjstudio\launcher'
$Config = Join-Path $LauncherHome 'launcher_config.properties'
$AppJar = Join-Path $LauncherHome 'app.jar'
$Marker = Join-Path $LauncherHome '.rsx-patched'
$Dist = Join-Path $Repo 'dist'
$ModHome = Join-Path $env:LOCALAPPDATA 'rsx-mod'
$GamePath = $null
$Uninstall = $false
for ($i = 0; $i -lt $args.Count; $i++) {
switch ($args[$i]) {
'--uninstall' { $Uninstall = $true }
'--home' { $ModHome = $args[++$i] }
'--game' { $GamePath = $args[++$i] }
default { }
}
}
function Say($text, $color) {
if ($color) { Write-Host " $text" -ForegroundColor $color } else { Write-Host " $text" }
}
function Die($text) { Say $text Red; exit 1 }
# --------------------------------------------------------------- launcher must be closed
function Get-LauncherRunning {
Get-Process -ErrorAction SilentlyContinue | Where-Object {
$_.MainWindowTitle -like '*Koptojop*' -or
($_.Path -and $_.Path -like "$LauncherHome*")
}
}
$running = Get-LauncherRunning
if ($running) {
Die 'Лаунчер запущен - закрой его (крестик) и запусти установщик снова.'
}
# --------------------------------------------------------------- java and patcher
$FindPatcher = Join-Path $Dist 'rsx-launcher-patch.jar'
function Find-Java {
$candidates = @(
(Join-Path $LauncherHome 'runtime\java\bin\java.exe')
)
foreach ($c in $candidates) {
if (Test-Path $c) { return $c }
}
$cmd = Get-Command java -ErrorAction SilentlyContinue
if ($cmd) { return $cmd.Source }
return $null
}
# --------------------------------------------------------------- read the config safely
# Handing the config to java.util.Properties is the only safe way to read it: it
# is a properties file, where a backslash escapes the next character.
function Read-GamePath($java, $path, $patcher) {
if (-not (Test-Path $path)) { return $null }
$prev = $ErrorActionPreference
$ErrorActionPreference = 'Continue'
$raw = & $java -jar $patcher getprop $path gamePath1 2>$null
$ErrorActionPreference = $prev
if ($raw) {
$value = ($raw | Select-Object -First 1) -replace '^\s+', ''
if ($value) { return $value }
}
return $null
}
if (-not (Test-Path $Config)) {
Die "Не найден конфиг лаунчера: $Config"
}
$game = Read-GamePath (Find-Java) $Config $FindPatcher
if ($GamePath) { $game = $GamePath }
# --------------------------------------------------------------- uninstall
if ($Uninstall) {
Say 'Удаляю модлоадер...'
$backup = "$AppJar.orig"
if (Test-Path $backup) {
Copy-Item $backup $AppJar -Force
Say 'app.jar восстановлен из резервной копии'
} else {
Say 'резервной копии нет, лаунчер не трогаю'
}
$ErrorActionPreference = 'Continue'
& $java -jar $FindPatcher setenv $Config '' 2>&1 |
ForEach-Object { Say $_ }
$ErrorActionPreference = 'Stop'
Say 'env убран из конфига лаунчера'
Remove-Item $Marker -Force -ErrorAction SilentlyContinue
Say 'маркер удалён'
Say 'Готово. Лаунчер снова запускается как обычно.' Green
exit 0
}
# --------------------------------------------------------------- checks
if (-not (Test-Path $Dist)) { Die "Нет каталога dist: $Dist (собери через build.cmd)" }
foreach ($f in 'rsx-bridge.jar', 'rsx-launcher-patch.jar', 'rsx-api.jar') {
if (-not (Test-Path (Join-Path $Dist $f))) { Die "Нет dist\$f - запусти build.cmd" }
}
$java = Find-Java
if (-not $java) { Die 'Не найден java (нужен лаунчерный runtime или java в PATH)' }
# a clean base to patch: re-patching an already patched jar is a no-op
if (Test-Path "$AppJar.orig") {
Copy-Item "$AppJar.orig" $AppJar -Force
Say 'восстановлен оригинальный app.jar перед патчем'
}
Say "Лаунчер: $LauncherHome"
Say "Игра: $(if ($game) { $game } else { 'не указан в gamePath1' })"
Say "Модлоадер: $ModHome"
Say ''
# --------------------------------------------------------------- copy the runtime
New-Item -ItemType Directory -Force -Path (Join-Path $ModHome 'bridge\profiles') | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $ModHome 'mods') | Out-Null
Copy-Item (Join-Path $Dist 'rsx-bridge.jar') (Join-Path $ModHome 'bridge') -Force
Say 'скопирован rsx-bridge.jar'
$existingProfile = Join-Path $ModHome 'bridge\profiles\latest.rsxp'
$oldProfile = 'G:\rsx-mod\bridge\profiles\latest.rsxp'
if (-not (Test-Path $existingProfile) -and (Test-Path $oldProfile)) {
Copy-Item $oldProfile (Split-Path $existingProfile) -Force
Say 'перенесён профиль сборки игры (latest.rsxp)'
} elseif (Test-Path $existingProfile) {
Say 'профиль уже на месте, оставляю как есть'
} else {
Say 'профиля нет - запусти prepare-build.cmd после первой установки', Yellow
}
# --------------------------------------------------------------- patch the launcher
Say ''
Say 'Патчу лаунчер...'
$patcher = Join-Path $Dist 'rsx-launcher-patch.jar'
$meta = "wa`nALLATORIxDEMO"
# native stderr must not be treated as a PowerShell error here
$prev = $ErrorActionPreference
$ErrorActionPreference = 'Continue'
$out = & $java -jar $patcher patch $AppJar $ModHome $meta 2>&1
$code = $LASTEXITCODE
$ErrorActionPreference = $prev
$out | ForEach-Object { Say $_ }
if ($code -ne 0) {
Die "Патч не удался (код $code). Если лаунчер запущен с правами администратора - закрой его и повтори."
}
Set-Content -LiteralPath $Marker -Value 'patched app.jar: rsx modloader' -Encoding ASCII
Say 'маркер .rsx-patched создан'
# --------------------------------------------------------------- wire the agent
$agentArg = "-javaagent:`"$ModHome\bridge\rsx-bridge.jar`""
$ErrorActionPreference = 'Continue'
$out = & $java -jar $patcher setenv $Config $agentArg 2>&1
$code = $LASTEXITCODE
$ErrorActionPreference = $prev
$out | ForEach-Object { Say $_ }
if ($code -ne 0) {
Die "Не удалось записать env в конфиг лаунчера (код $code)"
}
Say ''
Say 'Проверяю, что путь читается как надо...'
$ErrorActionPreference = 'Continue'
$check = & $java -jar $patcher showenv $Config 2>&1
$ErrorActionPreference = $prev
$check | ForEach-Object { Say $_ }
Say ''
Say 'Готово.' Green
Say ''
Say 'Дальше:'
Say ' 1. запускай лаунчер через start-launcher.cmd, а не ярлыком -'
Say ' updater.exe перекачает app.jar и сотрёт патч'
Say ' 2. жми «Играть» - появится выбор «С модами / Ванилла»'
Say " 3. моды клади в $ModHome\mods"