Skip to content

Instantly share code, notes, and snippets.

@stillie
Created August 21, 2025 08:42
Show Gist options
  • Save stillie/203391958aab7c7ac477596d45f47ecb to your computer and use it in GitHub Desktop.
Save stillie/203391958aab7c7ac477596d45f47ecb to your computer and use it in GitHub Desktop.
MC Discord crash recovery script
@echo off
setlocal enabledelayedexpansion
:: Configuration
set MAX_CRASHES=3
set CRASH_COUNT=0
set SERVER_BAT=run.bat
set WEBHOOK_URL={DISCORD_WEBHOOK_URL}
:: Get current directory for local file path
set CURRENT_DIR=%cd%
:: Check if run.bat exists
if not exist "%SERVER_BAT%" (
echo ERROR: %SERVER_BAT% not found in current directory!
echo Please make sure this script is in the same folder as your run.bat file.
pause
exit /b 1
)
echo Minecraft Server Auto-Restart Monitor
echo ====================================
echo Max crashes before giving up: %MAX_CRASHES%
echo Server batch file: %SERVER_BAT%
echo Discord webhook configured
echo.
:start_server
set /a CRASH_COUNT+=1
echo [%date% %time%] Starting server (Attempt %CRASH_COUNT%/%MAX_CRASHES%)
:: Send Discord notification for server start attempt
if %CRASH_COUNT% gtr 1 (
call :send_discord_message "πŸ”„ **Server Restart Attempt**" "Attempting to restart Minecraft server (Attempt %CRASH_COUNT%/%MAX_CRASHES%)\n\nπŸ“ Server location: `%CURRENT_DIR%`" "16776960"
)
:: Record start time for uptime tracking
for /f "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /a "start_seconds=((%%a*60)+%%b)*60+%%c"
)
:: Start the server and wait for it to finish
call "%SERVER_BAT%" nogui
:: Calculate uptime to help determine if this was a manual stop
for /f "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /a "end_seconds=((%%a*60)+%%b)*60+%%c"
)
set /a "uptime_seconds=end_seconds-start_seconds"
if %uptime_seconds% lss 0 set /a "uptime_seconds+=86400"
:: Check the exit code and uptime to determine shutdown type
if %errorlevel% equ 0 (
echo [%date% %time%] Server shut down normally (uptime: %uptime_seconds% seconds). Exiting monitor.
if %uptime_seconds% gtr 30 (
call :send_discord_message "βœ… **Server Shutdown**" "Minecraft server shut down normally after running for %uptime_seconds% seconds.\nAuto-restart monitor stopping.\n\nπŸ“ Server location: `%CURRENT_DIR%`" "65280"
) else (
call :send_discord_message "⚠️ **Quick Server Exit**" "Server exited quickly (%uptime_seconds% seconds) with code 0.\nThis might indicate a startup issue.\nAuto-restart monitor stopping.\n\nπŸ“ Server location: `%CURRENT_DIR%`" "16776960"
)
goto end
) else (
echo [%date% %time%] Server crashed with exit code %errorlevel%
:: Send crash notification
call :send_discord_message "πŸ’₯ **Server Crashed**" "Minecraft server crashed with exit code %errorlevel%\nCrash #%CRASH_COUNT% of %MAX_CRASHES%\n\nπŸ“ Server location: `%CURRENT_DIR%`" "16711680"
:: Check if we've reached the maximum number of crashes
if %CRASH_COUNT% geq %MAX_CRASHES% (
echo [%date% %time%] Maximum crash limit reached (%MAX_CRASHES%). Giving up.
echo Server will not be restarted automatically.
call :send_discord_message "🚨 **Max Crashes Reached**" "Server has crashed %MAX_CRASHES% times. Auto-restart disabled.\nManual intervention required.\n\nπŸ“ Server location: `%CURRENT_DIR%`" "8388608"
goto end
) else (
set /a REMAINING=!MAX_CRASHES! - !CRASH_COUNT!
echo [%date% %time%] Restarting server... (!REMAINING! attempts remaining)
echo Waiting 10 seconds before restart...
timeout /t 10 /nobreak >nul
goto start_server
)
)
:end
echo.
echo Auto-restart monitor has stopped.
pause
exit /b 0
:: Function to send Discord webhook message
:send_discord_message
set "title=%~1"
set "description=%~2"
set "color=%~3"
:: Create temporary JSON file
set "temp_json=%temp%\discord_webhook.json"
:: Write JSON payload to temp file
(
echo {
echo "embeds": [
echo {
echo "title": %title%,
echo "description": %description%,
echo "color": %color%,
echo "timestamp": "%date%T%time%",
echo "footer": {
echo "text": "Minecraft Server Monitor"
echo }
echo }
echo ]
echo }
) > "%temp_json%"
:: Send webhook using curl (if available) or PowerShell as fallback
curl --version >nul 2>&1
if %errorlevel% equ 0 (
curl -H "Content-Type: application/json" -d @"%temp_json%" "%WEBHOOK_URL%" >nul 2>&1
) else (
:: Fallback to PowerShell
powershell -Command "try { Invoke-RestMethod -Uri '%WEBHOOK_URL%' -Method Post -ContentType 'application/json' -Body (Get-Content '%temp_json%' -Raw) } catch { Write-Host 'Failed to send Discord notification' }"
)
:: Clean up temp file
del "%temp_json%" >nul 2>&1
goto :eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment