145 lines
4.1 KiB
PowerShell
145 lines
4.1 KiB
PowerShell
# ==========================================
|
||
# 🌐 NET UTILS
|
||
# ==========================================
|
||
|
||
# --- CONFIG ---
|
||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||
|
||
# --- ФУНКЦИИ ---
|
||
|
||
$script:HwidFile = "C:\Tools\sing-box\hwid"
|
||
$script:AppName = "VPN-Proxy-Control by Dokril"
|
||
|
||
function Get-HWID {
|
||
# Генерация или чтение HWID из файла
|
||
if (Test-Path $script:HwidFile) {
|
||
return (Get-Content $script:HwidFile -Raw).Trim()
|
||
}
|
||
|
||
# Генерируем новый HWID
|
||
$hwid = [Guid]::NewGuid().ToString("N").Substring(0, 16)
|
||
|
||
# Сохраняем
|
||
$dir = Split-Path $script:HwidFile -Parent
|
||
if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
||
Set-Content -Path $script:HwidFile -Value $hwid
|
||
|
||
return $hwid
|
||
}
|
||
|
||
function Get-SubscriptionHeaders {
|
||
# Формируем заголовки как в server.py
|
||
$osName = "windows"
|
||
$osVersion = [Environment]::OSVersion.Version.ToString()
|
||
|
||
return @{
|
||
"User-Agent" = "singbox"
|
||
"x-hwid" = (Get-HWID)
|
||
"x-device-os" = $osName
|
||
"x-ver-os" = $osVersion
|
||
"x-device-model" = $script:AppName
|
||
}
|
||
}
|
||
|
||
function Download-File {
|
||
param(
|
||
[string]$Url,
|
||
[string]$Destination,
|
||
[string]$UserAgent = "VPN-Proxy-Installer"
|
||
)
|
||
|
||
try {
|
||
$req = [System.Net.HttpWebRequest]::Create($Url)
|
||
$req.UserAgent = $UserAgent
|
||
$resp = $req.GetResponse()
|
||
|
||
$stream = $resp.GetResponseStream()
|
||
$fs = [System.IO.File]::Create($Destination)
|
||
$msgLen = $resp.ContentLength
|
||
|
||
$buffer = New-Object byte[] 10240
|
||
$count = 0
|
||
$total = 0
|
||
|
||
do {
|
||
$count = $stream.Read($buffer, 0, $buffer.Length)
|
||
$fs.Write($buffer, 0, $count)
|
||
$total += $count
|
||
# Можно добавить прогресс бар, но пока просто качаем
|
||
} while ($count -gt 0)
|
||
|
||
$fs.Close()
|
||
$stream.Close()
|
||
$resp.Close()
|
||
|
||
# Unblock file to prevent "Mark of the Web" issues
|
||
Unblock-File -Path $Destination -ErrorAction SilentlyContinue
|
||
|
||
return $true
|
||
}
|
||
catch {
|
||
Write-Error "Ошибка скачивания: $_"
|
||
return $false
|
||
}
|
||
}
|
||
|
||
|
||
function Get-SubscriptionData {
|
||
param(
|
||
[string]$Url,
|
||
[string]$UserAgent = "singbox",
|
||
$Headers = @{}
|
||
)
|
||
|
||
Write-Info "Загружаю подписку..."
|
||
|
||
$rawContent = $null
|
||
$userInfo = @{}
|
||
|
||
# 1. Получаем ответ
|
||
try {
|
||
$response = Invoke-WebRequest -Uri $Url -Headers $Headers -TimeoutSec 15 -UseBasicParsing
|
||
$rawContent = $response.Content
|
||
|
||
# Парсим subscription-userinfo header
|
||
$userInfoHeader = $response.Headers["subscription-userinfo"]
|
||
if ($userInfoHeader) {
|
||
$parts = $userInfoHeader -split ";"
|
||
foreach ($part in $parts) {
|
||
if ($part -match "(\w+)=(\d+)") {
|
||
$userInfo[$matches[1]] = [int64]$matches[2]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch {
|
||
return @{
|
||
success = $false
|
||
error = "Ошибка загрузки: $($_.Exception.Message)"
|
||
rawContent = $null
|
||
}
|
||
}
|
||
|
||
# 2. Пробуем парсить как JSON
|
||
try {
|
||
$config = $rawContent | ConvertFrom-Json
|
||
return @{
|
||
success = $true
|
||
config = $config
|
||
rawContent = $rawContent
|
||
userInfo = $userInfo
|
||
}
|
||
}
|
||
catch {
|
||
# JSON не распарсился — возвращаем rawContent для дальнейшей обработки
|
||
return @{
|
||
success = $false
|
||
error = "Ответ не в формате JSON (возможно Base64 или список ссылок)"
|
||
rawContent = $rawContent
|
||
userInfo = $userInfo
|
||
}
|
||
}
|
||
}
|
||
|
||
|