2026-02-24 20:56:36 +08:00
|
|
|
|
#
|
|
|
|
|
|
# FunMC 一键部署脚本 (Windows)
|
2026-02-25 20:35:01 +08:00
|
|
|
|
# 用法: irm fc.funmc.cn/install.ps1 | iex
|
2026-02-24 20:56:36 +08:00
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
|
|
|
|
|
|
|
|
# 配置
|
|
|
|
|
|
$FUNMC_VERSION = "0.1.0"
|
|
|
|
|
|
$INSTALL_DIR = "$env:ProgramFiles\FunMC"
|
|
|
|
|
|
$CONFIG_DIR = "$env:ProgramData\FunMC"
|
|
|
|
|
|
$DATA_DIR = "$env:ProgramData\FunMC\data"
|
|
|
|
|
|
$LOG_DIR = "$env:ProgramData\FunMC\logs"
|
|
|
|
|
|
|
|
|
|
|
|
# 颜色输出函数
|
|
|
|
|
|
function Write-ColorOutput($ForegroundColor, $Message) {
|
|
|
|
|
|
$fc = $host.UI.RawUI.ForegroundColor
|
|
|
|
|
|
$host.UI.RawUI.ForegroundColor = $ForegroundColor
|
|
|
|
|
|
Write-Output $Message
|
|
|
|
|
|
$host.UI.RawUI.ForegroundColor = $fc
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function Write-Info($Message) { Write-ColorOutput Cyan "[INFO] $Message" }
|
|
|
|
|
|
function Write-Success($Message) { Write-ColorOutput Green "[✓] $Message" }
|
|
|
|
|
|
function Write-Warning($Message) { Write-ColorOutput Yellow "[!] $Message" }
|
|
|
|
|
|
function Write-Error($Message) { Write-ColorOutput Red "[✗] $Message" }
|
|
|
|
|
|
|
|
|
|
|
|
# 显示标题
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ FunMC 服务端一键部署脚本 v$FUNMC_VERSION ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ 魔幻方开发 ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
|
|
|
|
|
|
# 检查管理员权限
|
|
|
|
|
|
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
|
|
|
|
|
|
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
|
|
|
|
Write-Error "请以管理员身份运行此脚本"
|
|
|
|
|
|
Write-Host "右键点击 PowerShell,选择 '以管理员身份运行'"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 生成随机字符串
|
|
|
|
|
|
function Get-RandomString($Length) {
|
|
|
|
|
|
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
|
|
|
|
-join ((1..$Length) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查并安装 Chocolatey
|
|
|
|
|
|
function Install-Chocolatey {
|
|
|
|
|
|
Write-Info "[1/7] 检查 Chocolatey..."
|
|
|
|
|
|
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
|
|
|
|
|
|
Write-Info "安装 Chocolatey..."
|
|
|
|
|
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
|
|
|
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
|
|
|
|
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
|
|
|
|
|
}
|
|
|
|
|
|
Write-Success "Chocolatey 就绪"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 安装依赖
|
|
|
|
|
|
function Install-Dependencies {
|
|
|
|
|
|
Write-Info "[2/7] 安装系统依赖..."
|
|
|
|
|
|
|
|
|
|
|
|
# 安装 Rust
|
|
|
|
|
|
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) {
|
|
|
|
|
|
Write-Info "安装 Rust..."
|
|
|
|
|
|
choco install rust -y
|
|
|
|
|
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 安装 Node.js
|
|
|
|
|
|
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
|
|
|
|
|
|
Write-Info "安装 Node.js..."
|
|
|
|
|
|
choco install nodejs-lts -y
|
|
|
|
|
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 安装 PostgreSQL
|
|
|
|
|
|
if (-not (Get-Command psql -ErrorAction SilentlyContinue)) {
|
|
|
|
|
|
Write-Info "安装 PostgreSQL..."
|
|
|
|
|
|
choco install postgresql -y
|
|
|
|
|
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 安装 Git
|
|
|
|
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
|
|
|
|
Write-Info "安装 Git..."
|
|
|
|
|
|
choco install git -y
|
|
|
|
|
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "系统依赖安装完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 配置数据库
|
|
|
|
|
|
function Setup-Database {
|
|
|
|
|
|
Write-Info "[3/7] 配置数据库..."
|
|
|
|
|
|
|
|
|
|
|
|
$global:DB_PASSWORD = Get-RandomString 24
|
|
|
|
|
|
|
|
|
|
|
|
# 启动 PostgreSQL 服务
|
|
|
|
|
|
Start-Service postgresql* -ErrorAction SilentlyContinue
|
|
|
|
|
|
|
|
|
|
|
|
# 创建数据库和用户
|
|
|
|
|
|
$pgCommands = @"
|
|
|
|
|
|
CREATE USER funmc WITH PASSWORD '$DB_PASSWORD';
|
|
|
|
|
|
CREATE DATABASE funmc OWNER funmc;
|
|
|
|
|
|
GRANT ALL PRIVILEGES ON DATABASE funmc TO funmc;
|
|
|
|
|
|
"@
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
$pgCommands | psql -U postgres 2>$null
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
Write-Warning "数据库可能已存在,继续..."
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "数据库配置完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 创建目录
|
|
|
|
|
|
function Create-Directories {
|
|
|
|
|
|
Write-Info "[4/7] 创建目录结构..."
|
|
|
|
|
|
|
|
|
|
|
|
@($INSTALL_DIR, $CONFIG_DIR, $DATA_DIR, $LOG_DIR) | ForEach-Object {
|
|
|
|
|
|
if (-not (Test-Path $_)) {
|
|
|
|
|
|
New-Item -ItemType Directory -Path $_ -Force | Out-Null
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "目录创建完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 下载并编译
|
|
|
|
|
|
function Build-FunMC {
|
|
|
|
|
|
Write-Info "[5/7] 编译 FunMC..."
|
|
|
|
|
|
|
|
|
|
|
|
$srcDir = "$INSTALL_DIR\src"
|
|
|
|
|
|
|
|
|
|
|
|
if (Test-Path $srcDir) {
|
|
|
|
|
|
Set-Location $srcDir
|
|
|
|
|
|
git pull
|
|
|
|
|
|
} else {
|
2026-02-25 20:35:01 +08:00
|
|
|
|
git clone https://gt.funmc.cn/xiaobai/FunConnect.git $srcDir
|
2026-02-24 20:56:36 +08:00
|
|
|
|
Set-Location $srcDir
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 编译服务端
|
|
|
|
|
|
cargo build --release -p funmc-server -p funmc-relay-server
|
|
|
|
|
|
|
|
|
|
|
|
# 复制二进制文件
|
|
|
|
|
|
Copy-Item "target\release\funmc-server.exe" $INSTALL_DIR -Force
|
|
|
|
|
|
Copy-Item "target\release\funmc-relay-server.exe" $INSTALL_DIR -Force
|
|
|
|
|
|
|
|
|
|
|
|
# 编译管理面板
|
|
|
|
|
|
Set-Location "$srcDir\admin-panel"
|
|
|
|
|
|
npm install
|
|
|
|
|
|
npm run build
|
|
|
|
|
|
Copy-Item "dist" "$INSTALL_DIR\admin-panel" -Recurse -Force
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "FunMC 编译完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 配置服务
|
|
|
|
|
|
function Configure-Services {
|
|
|
|
|
|
Write-Info "[6/7] 配置服务..."
|
|
|
|
|
|
|
|
|
|
|
|
$JWT_SECRET = Get-RandomString 48
|
|
|
|
|
|
$ADMIN_PASSWORD = Get-RandomString 12
|
|
|
|
|
|
|
|
|
|
|
|
# 获取服务器 IP
|
|
|
|
|
|
$SERVER_IP = (Invoke-WebRequest -Uri "https://ifconfig.me" -UseBasicParsing -TimeoutSec 5).Content.Trim()
|
|
|
|
|
|
if (-not $SERVER_IP) {
|
|
|
|
|
|
$SERVER_IP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notmatch "Loopback" } | Select-Object -First 1).IPAddress
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 创建配置文件
|
|
|
|
|
|
$serverConfig = @"
|
|
|
|
|
|
# FunMC 服务端配置
|
|
|
|
|
|
DATABASE_URL=postgres://funmc:$($global:DB_PASSWORD)@localhost/funmc
|
|
|
|
|
|
JWT_SECRET=$JWT_SECRET
|
|
|
|
|
|
BIND_ADDR=0.0.0.0:3000
|
|
|
|
|
|
QUIC_PORT=3001
|
|
|
|
|
|
RUST_LOG=info
|
|
|
|
|
|
|
|
|
|
|
|
# 服务器信息
|
|
|
|
|
|
SERVER_NAME=FunMC Server
|
|
|
|
|
|
SERVER_IP=$SERVER_IP
|
|
|
|
|
|
SERVER_DOMAIN=
|
|
|
|
|
|
|
|
|
|
|
|
# 管理面板
|
|
|
|
|
|
ADMIN_ENABLED=true
|
|
|
|
|
|
ADMIN_USERNAME=admin
|
|
|
|
|
|
ADMIN_PASSWORD=$ADMIN_PASSWORD
|
|
|
|
|
|
|
|
|
|
|
|
# 客户端下载
|
|
|
|
|
|
CLIENT_DOWNLOAD_ENABLED=true
|
|
|
|
|
|
CLIENT_VERSION=$FUNMC_VERSION
|
|
|
|
|
|
"@
|
|
|
|
|
|
|
|
|
|
|
|
$serverConfig | Out-File "$CONFIG_DIR\server.env" -Encoding UTF8
|
|
|
|
|
|
|
|
|
|
|
|
$relayConfig = @"
|
|
|
|
|
|
RELAY_PORT=7900
|
|
|
|
|
|
JWT_SECRET=$JWT_SECRET
|
|
|
|
|
|
RUST_LOG=info
|
|
|
|
|
|
"@
|
|
|
|
|
|
|
|
|
|
|
|
$relayConfig | Out-File "$CONFIG_DIR\relay.env" -Encoding UTF8
|
|
|
|
|
|
|
|
|
|
|
|
# 注册 Windows 服务
|
|
|
|
|
|
$nssm = "$env:ChocolateyInstall\bin\nssm.exe"
|
|
|
|
|
|
if (-not (Test-Path $nssm)) {
|
|
|
|
|
|
choco install nssm -y
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# FunMC Server 服务
|
|
|
|
|
|
& $nssm install FunMC-Server "$INSTALL_DIR\funmc-server.exe"
|
|
|
|
|
|
& $nssm set FunMC-Server AppDirectory $INSTALL_DIR
|
|
|
|
|
|
& $nssm set FunMC-Server AppEnvironmentExtra "$(Get-Content "$CONFIG_DIR\server.env" -Raw)"
|
|
|
|
|
|
& $nssm set FunMC-Server AppStdout "$LOG_DIR\server.log"
|
|
|
|
|
|
& $nssm set FunMC-Server AppStderr "$LOG_DIR\server-error.log"
|
|
|
|
|
|
|
|
|
|
|
|
# FunMC Relay 服务
|
|
|
|
|
|
& $nssm install FunMC-Relay "$INSTALL_DIR\funmc-relay-server.exe"
|
|
|
|
|
|
& $nssm set FunMC-Relay AppDirectory $INSTALL_DIR
|
|
|
|
|
|
& $nssm set FunMC-Relay AppEnvironmentExtra "$(Get-Content "$CONFIG_DIR\relay.env" -Raw)"
|
|
|
|
|
|
& $nssm set FunMC-Relay AppStdout "$LOG_DIR\relay.log"
|
|
|
|
|
|
& $nssm set FunMC-Relay AppStderr "$LOG_DIR\relay-error.log"
|
|
|
|
|
|
|
|
|
|
|
|
# 运行数据库迁移
|
|
|
|
|
|
Set-Location "$INSTALL_DIR\src\server"
|
|
|
|
|
|
$env:DATABASE_URL = "postgres://funmc:$($global:DB_PASSWORD)@localhost/funmc"
|
|
|
|
|
|
cargo sqlx migrate run
|
|
|
|
|
|
|
|
|
|
|
|
# 启动服务
|
|
|
|
|
|
Start-Service FunMC-Server
|
|
|
|
|
|
Start-Service FunMC-Relay
|
|
|
|
|
|
|
|
|
|
|
|
# 保存凭据
|
|
|
|
|
|
$credentials = @"
|
|
|
|
|
|
======================================
|
|
|
|
|
|
FunMC 服务端安装信息
|
|
|
|
|
|
======================================
|
|
|
|
|
|
|
|
|
|
|
|
服务器 IP: $SERVER_IP
|
|
|
|
|
|
API 地址: http://${SERVER_IP}:3000
|
|
|
|
|
|
管理面板: http://${SERVER_IP}:3000/admin
|
|
|
|
|
|
|
|
|
|
|
|
管理员账号: admin
|
|
|
|
|
|
管理员密码: $ADMIN_PASSWORD
|
|
|
|
|
|
|
|
|
|
|
|
数据库密码: $($global:DB_PASSWORD)
|
|
|
|
|
|
JWT 密钥: $JWT_SECRET
|
|
|
|
|
|
|
|
|
|
|
|
======================================
|
|
|
|
|
|
请妥善保管此文件!
|
|
|
|
|
|
======================================
|
|
|
|
|
|
"@
|
|
|
|
|
|
|
|
|
|
|
|
$credentials | Out-File "$CONFIG_DIR\credentials.txt" -Encoding UTF8
|
|
|
|
|
|
|
|
|
|
|
|
$global:SERVER_IP = $SERVER_IP
|
|
|
|
|
|
$global:ADMIN_PASSWORD = $ADMIN_PASSWORD
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "服务配置完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 配置防火墙
|
|
|
|
|
|
function Configure-Firewall {
|
|
|
|
|
|
Write-Info "[7/7] 配置防火墙..."
|
|
|
|
|
|
|
|
|
|
|
|
# 添加防火墙规则
|
|
|
|
|
|
New-NetFirewallRule -DisplayName "FunMC API" -Direction Inbound -Protocol TCP -LocalPort 3000 -Action Allow -ErrorAction SilentlyContinue
|
|
|
|
|
|
New-NetFirewallRule -DisplayName "FunMC QUIC" -Direction Inbound -Protocol UDP -LocalPort 3001 -Action Allow -ErrorAction SilentlyContinue
|
|
|
|
|
|
New-NetFirewallRule -DisplayName "FunMC Relay" -Direction Inbound -Protocol UDP -LocalPort 7900-7901 -Action Allow -ErrorAction SilentlyContinue
|
|
|
|
|
|
|
|
|
|
|
|
Write-Success "防火墙配置完成"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 显示完成信息
|
|
|
|
|
|
function Show-Completion {
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "║ FunMC 安装完成! ║" -ForegroundColor Green
|
|
|
|
|
|
Write-Host "║ ║" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "服务器信息:" -ForegroundColor Green
|
|
|
|
|
|
Write-Host " API 地址: http://$($global:SERVER_IP):3000"
|
|
|
|
|
|
Write-Host " 管理面板: http://$($global:SERVER_IP):3000/admin"
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "管理员登录:" -ForegroundColor Green
|
|
|
|
|
|
Write-Host " 用户名: admin"
|
|
|
|
|
|
Write-Host " 密码: $($global:ADMIN_PASSWORD)"
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "客户端下载:" -ForegroundColor Green
|
|
|
|
|
|
Write-Host " http://$($global:SERVER_IP):3000/download"
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "重要文件:" -ForegroundColor Yellow
|
|
|
|
|
|
Write-Host " 配置文件: $CONFIG_DIR\server.env"
|
|
|
|
|
|
Write-Host " 凭据信息: $CONFIG_DIR\credentials.txt"
|
|
|
|
|
|
Write-Host " 日志文件: $LOG_DIR\"
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "服务管理命令:" -ForegroundColor Cyan
|
|
|
|
|
|
Write-Host " 查看状态: Get-Service FunMC*"
|
|
|
|
|
|
Write-Host " 重启服务: Restart-Service FunMC-Server"
|
|
|
|
|
|
Write-Host " 查看日志: Get-Content $LOG_DIR\server.log -Tail 50"
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "魔幻方开发 - 让 Minecraft 联机变得简单" -ForegroundColor Green
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 主流程
|
|
|
|
|
|
try {
|
|
|
|
|
|
Install-Chocolatey
|
|
|
|
|
|
Install-Dependencies
|
|
|
|
|
|
Setup-Database
|
|
|
|
|
|
Create-Directories
|
|
|
|
|
|
Build-FunMC
|
|
|
|
|
|
Configure-Services
|
|
|
|
|
|
Configure-Firewall
|
|
|
|
|
|
Show-Completion
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
Write-Error "安装过程中出错: $_"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
}
|