Scope B (Windows agent): - probe.go split into shared core + probe_linux.go (verbatim Linux sampler, build-tagged) + probe_windows.go (Win32 sampler: GetSystemTimes CPU diff, GlobalMemoryStatusEx, fixed-drive df totals, GetIfTable2 counted set, MachineGuid boot identity, registry facts; load and TCP/UDP counts stay zero - x/sys v0.47.0 exports no wrapper) - update intents are acknowledged and skipped on Windows (the release assets are Linux binaries; Windows nodes update via install-agent.ps1) - cmd/xui-agent-windows: SCM service host (svc.Run + mgr install/ uninstall/start/stop) mirroring main.go's agent lifecycle wiring - install-agent.ps1: downloads the exe, writes probeOnly agent.json, registers and starts the service, rerun-safe Scope C (version display): - config.GetAgentDisplayVersion (and the master getter) compose from the bare number so a V-form injection no longer doubles the letter (AV2.1.0 -> A2.1.0) - node list view repairs stored AV-prefixed reports at assembly so deployed agents read uniformly without an update Scope D (production fix): - share-link reality sni: when the inbound has a sing-box fragment, sni is the fragment's tls.server_name - the only name the sing-box REALITY server serves. The previous rule picked a uniformly random serverNames entry per generation, which xray tolerated but sing-box refuses as an invalid connection. sid keeps its random pick: the converter carries the whole shortIds list into the fragment, so every listed sid is served.
103 lines
3.9 KiB
PowerShell
103 lines
3.9 KiB
PowerShell
#Requires -RunAsAdministrator
|
|
<#
|
|
.SYNOPSIS
|
|
Installs the 3x-ui probe-only agent on Windows (64-bit).
|
|
|
|
.DESCRIPTION
|
|
Downloads x-ui-agent-windows-amd64.exe into C:\x-ui, writes
|
|
agent.json with "probeOnly": true (Windows nodes run no proxy
|
|
core: facts, metrics and latency probes only), registers the
|
|
x-ui-agent Windows service (auto-start) and starts it.
|
|
|
|
Re-running is safe: an existing service is stopped and removed
|
|
first, and any of -Master/-Token/-Name left empty is inherited
|
|
from the agent.json already on disk.
|
|
|
|
.EXAMPLE
|
|
.\install-agent.ps1 -Master "https://panel.example.com/rogue" -Token "<agent token>" -Name "win-node-1"
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$Master,
|
|
[string]$Token,
|
|
[string]$Name,
|
|
[string]$InstallDir = "C:\x-ui",
|
|
[string]$AgentUrl = $env:XUI_URL
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Release download base, same shape as install-agent.sh's
|
|
# RELEASE_BASE (the version segment is bumped by the release flow).
|
|
$ReleaseBase = "https://git.881218.xyz/rogue/3x-ui-agent/releases/download/V2.0.3"
|
|
if (-not $AgentUrl) {
|
|
$AgentUrl = "$ReleaseBase/x-ui-agent-windows-amd64.exe"
|
|
}
|
|
|
|
$ServiceName = "x-ui-agent"
|
|
$ExeName = "x-ui-agent-windows-amd64.exe"
|
|
$ExePath = Join-Path $InstallDir $ExeName
|
|
$ConfigPath = Join-Path $InstallDir "agent.json"
|
|
|
|
# Inherit missing parameters from an existing agent.json (reruns).
|
|
if (Test-Path $ConfigPath) {
|
|
$existing = Get-Content $ConfigPath -Raw | ConvertFrom-Json
|
|
if (-not $Master) { $Master = $existing.master_url }
|
|
if (-not $Token) { $Token = $existing.token }
|
|
if (-not $Name) { $Name = $existing.node_name }
|
|
}
|
|
if (-not $Master) { throw "missing -Master (and no existing agent.json to inherit from)" }
|
|
if (-not $Token) { throw "missing -Token (and no existing agent.json to inherit from)" }
|
|
if (-not $Name) { throw "missing -Name (and no existing agent.json to inherit from)" }
|
|
|
|
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
|
|
|
# Stop and remove any previous install so the exe file is not locked
|
|
# by a running service when it is replaced below. Prefer the old
|
|
# binary's own subcommands; fall back to sc.exe when it is gone.
|
|
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
|
if ($svc) {
|
|
if (Test-Path $ExePath) {
|
|
& $ExePath stop | Out-Null
|
|
& $ExePath uninstall | Out-Null
|
|
}
|
|
else {
|
|
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
|
|
& sc.exe delete $ServiceName | Out-Null
|
|
}
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
|
|
# Download the agent binary (via a temp file, then swap into place).
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
$tmpExe = "$ExePath.new"
|
|
Write-Host "Downloading $AgentUrl"
|
|
Invoke-WebRequest -Uri $AgentUrl -OutFile $tmpExe -UseBasicParsing
|
|
if (-not (Test-Path $tmpExe) -or (Get-Item $tmpExe).Length -eq 0) {
|
|
throw "agent download produced an empty file: $AgentUrl"
|
|
}
|
|
Move-Item -Force $tmpExe $ExePath
|
|
|
|
# Write agent.json. Windows agents are probe-only: probeOnly is
|
|
# always set (the design contract, not an option).
|
|
$config = [ordered]@{
|
|
master_url = $Master
|
|
token = $Token
|
|
node_name = $Name
|
|
probeOnly = $true
|
|
}
|
|
$json = $config | ConvertTo-Json
|
|
# Go's encoding/json rejects a UTF-8 BOM, which Set-Content -Encoding
|
|
# UTF8 would add on Windows PowerShell 5.1: write BOM-less UTF-8.
|
|
[System.IO.File]::WriteAllText($ConfigPath, $json, (New-Object System.Text.UTF8Encoding($false)))
|
|
Write-Host "Wrote $ConfigPath (probeOnly)"
|
|
|
|
# Register and start the service.
|
|
& $ExePath install -config $ConfigPath
|
|
if ($LASTEXITCODE -ne 0) { throw "service install failed (exit $LASTEXITCODE)" }
|
|
& $ExePath start
|
|
if ($LASTEXITCODE -ne 0) { throw "service start failed (exit $LASTEXITCODE)" }
|
|
|
|
Write-Host "3x-ui agent installed and running as service '$ServiceName'."
|
|
Write-Host "Update later by re-running this script; the master's one-click agent update is intentionally not consumed on Windows."
|