Server Manager (.ps1)
Gera um script PowerShell pra rodar seu servidor DayZ com watchdog (reinicia sozinho se cair), restart programado, log com horário e BEC, o que o start.bat faz mal. Roda 100% no navegador.
Pra rodar um .ps1: clique direito → Executar com PowerShell, ou no PowerShell powershell -ExecutionPolicy Bypass -File .\Start-DayZServer.ps1. Salve na pasta do servidor.
Start-DayZServer.ps1
# Tecplay, Server Manager DayZ (PowerShell). Gerado em tecplay.inf.br/ferramentas
# Rode: clique direito > Executar com PowerShell (ou powershell -ExecutionPolicy Bypass -File este.ps1)
# ===== Configuracao (edite aqui) =====
$ServerName = 'Meu Servidor DayZ'
$ServerLocation = 'C:\DayZServer'
$Exe = 'DayZServer_x64.exe'
$Config = 'serverDZ.cfg'
$Port = 2302
$Profiles = 'profiles'
$CpuCount = 4
$Mods = ''
$ServerMods = ''
$IgnoreMods = ''
$Mission = ''
$BePath = ''
$LimitFPS = 0
$RestartHours = 4
$GraceSeconds = 10
$LogFile = Join-Path $ServerLocation 'server-manager.log'
# Log com horario
function Write-Log([string]$Message) {
$line = "[{0}] {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message
Write-Host $line
Add-Content -Path $LogFile -Value $line
}
# ===== Mods server-side conhecidos (token normalizado: minusculo, sem @ e sem simbolo) =====
$ServerSideKnown = @('2464526692', 'gamelabs', '2276010135', 'dayzeditorloader', 'editorloader', '2482312670', 'spawnerbubaku')
$CfTokens = @('cf', '1559212036', 'communityframework', 'communityframeworkcf')
function Get-ModToken([string]$Name) {
$t = $Name -replace '^@+', ''
return ($t.ToLower() -replace '[^a-z0-9]', '')
}
# ===== Modo Facil: le as pastas @Mod e separa cliente x server-side =====
function Resolve-Mods {
$dirs = @(Get-ChildItem -LiteralPath $ServerLocation -Directory -Filter '@*' -ErrorAction SilentlyContinue | Sort-Object Name)
$cli = @(); $srv = @()
foreach ($d in $dirs) {
if ($ServerSideKnown -contains (Get-ModToken $d.Name)) { $srv += $d.Name } else { $cli += $d.Name }
}
# @CF (e dependencias base) carregam PRIMEIRO.
$cf = @($cli | Where-Object { $CfTokens -contains (Get-ModToken $_) })
$rest = @($cli | Where-Object { $CfTokens -notcontains (Get-ModToken $_) })
$script:Mods = ((@($cf) + @($rest)) -join ';')
$script:ServerMods = ($srv -join ';')
if ($script:Mods) { Write-Log ("Mods de cliente: " + $script:Mods) } else { Write-Log 'Nenhuma pasta @Mod encontrada - subindo VANILLA.' }
if ($script:ServerMods) { Write-Log ("Mods server-side: " + $script:ServerMods) }
}
# ===== Copia toda .bikey de dentro dos @mod pra keys\ (recursivo: pega keys, Keys, Key, key) =====
function Copy-ModKeys {
$dest = Join-Path $ServerLocation 'keys'
if (-not (Test-Path -LiteralPath $dest)) { New-Item -ItemType Directory -Path $dest | Out-Null }
$n = 0
foreach ($d in @(Get-ChildItem -LiteralPath $ServerLocation -Directory -Filter '@*' -ErrorAction SilentlyContinue)) {
# -Recurse pega keys\ Keys\ Key\ key\ e qualquer subpasta.
foreach ($k in @(Get-ChildItem -LiteralPath $d.FullName -Filter '*.bikey' -Recurse -File -ErrorAction SilentlyContinue)) {
Copy-Item -LiteralPath $k.FullName -Destination $dest -Force -ErrorAction SilentlyContinue
$n++
}
}
Write-Log ("Chaves .bikey copiadas para keys\: " + $n)
}
# ===== Monta os argumentos (refeito a cada ciclo, o Modo Facil pode mudar a lista) =====
function Get-ServerArgs {
$a = @()
$a += "-config=$Config"
$a += "-port=$Port"
$a += "-profiles=$Profiles"
$a += "-cpuCount=$CpuCount"
# Aspas em volta do PARAMETRO INTEIRO. Aspas so no valor fazem o
# engine engolir a aspa como parte do nome do mod, e ele NAO carrega.
if ($Mods) { $a += "`"-mod=$Mods`"" }
if ($ServerMods) { $a += "`"-serverMod=$ServerMods`"" }
if ($IgnoreMods) { $a += "`"-ignoreMod=$IgnoreMods`"" }
if ($Mission) { $a += "`"-mission=$Mission`"" }
if ($BePath) { $a += "`"-BEpath=$BePath`"" }
if ($LimitFPS -gt 0) { $a += "-limitFPS=$LimitFPS" }
$a += '-dologs'
$a += '-adminlog'
$a += '-netlog'
$a += '-freezecheck'
return $a
}
$script:BecProc = $null
function Start-DayZ {
Resolve-Mods
Copy-ModKeys
$argLine = (Get-ServerArgs) -join ' '
Write-Log "Subindo o servidor: $ServerName"
$p = Start-Process -FilePath (Join-Path $ServerLocation $Exe) -WorkingDirectory $ServerLocation -ArgumentList $argLine -PassThru
return $p
}
# ===== Parada: SEMPRE por PID. Matar por NOME derruba os outros servidores da mesma maquina. =====
function Stop-Proc($Proc) {
if (-not $Proc) { return }
try { if ($Proc.HasExited) { return } } catch { return }
try { $Proc.CloseMainWindow() | Out-Null } catch { }
for ($i = 0; $i -lt 10; $i++) {
Start-Sleep -Milliseconds 500
try { if ($Proc.HasExited) { return } } catch { return }
}
Stop-Process -Id $Proc.Id -Force -ErrorAction SilentlyContinue
}
function Stop-All($Proc) {
Stop-Proc $Proc
}
# ===== Pergunta [R]einiciar / [S]air, com timeout =====
function Read-RestartChoice([int]$TimeoutSeconds) {
Write-Host ''
Write-Host ' [R] reiniciar agora [S] sair' -ForegroundColor Yellow
Write-Host (' Sem resposta, reinicia sozinho em' + " " + $TimeoutSeconds + "s...")
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ((Get-Date) -lt $deadline) {
# KeyAvailable so existe no console (nao no ISE). Se nao houver,
# o timeout resolve e o servidor sobe de novo sozinho.
try {
if ($Host.UI.RawUI.KeyAvailable) {
$k = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
$ch = ([string]$k.Character).ToUpper()
if ($ch -eq 'R') { return 'restart' }
if ($ch -eq 'S') { return 'exit' }
}
} catch { break }
Start-Sleep -Milliseconds 200
}
return 'restart'
}
# ===== Loop principal =====
while ($true) {
$proc = Start-DayZ
$startedAt = Get-Date
$scheduledStop = $false
while (-not $proc.HasExited) {
Start-Sleep -Seconds 15
if (((Get-Date) - $startedAt).TotalHours -ge $RestartHours) {
$scheduledStop = $true
Write-Log ('Restart programado' + " ($RestartHours h)")
break
}
}
if (-not $scheduledStop) { Write-Log 'Servidor caiu - reiniciando (watchdog)' }
Stop-All $proc
if ((Read-RestartChoice $GraceSeconds) -eq 'exit') {
Write-Log 'Encerrado pelo operador (S).'
break
}
}
Achou útil? Encontrou bug?
Manda feedback que a Tecplay lê tudo e prioriza melhorias.
Feito pela Tecplay
