Paper Minecraft Server Auto Updater for 1.21.5

CraniX

New member
Apr 25, 2025
1
0
1
Canada
modrinth.com

paper_updater.py​


Code:
import os
import requests
import shutil

# Configuration
paper_version = "1.21.5"
paper_dir = os.path.abspath(".")  # current directory
paper_api = f"https://api.papermc.io/v2/projects/paper/versions/{paper_version}"

def get_latest_build():
    print("[INFO] Fetching latest build info from PaperMC API...")
    response = requests.get(paper_api)
    if response.status_code != 200:
        print("[ERROR] Failed to get version info.")
        return None

    builds = response.json().get("builds", [])
    if not builds:
        print("[ERROR] No builds found.")
        return None

    return max(builds)  # highest build number is the latest

def construct_jar_name(build):
    return f"paper-{paper_version}-{build}.jar"

def download_latest_jar(build):
    jar_name = construct_jar_name(build)
    url = f"{paper_api}/builds/{build}/downloads/{jar_name}"
    print(f"[INFO] Downloading latest Paper jar: {jar_name}")
    response = requests.get(url, stream=True)

    if response.status_code == 200:
        with open(os.path.join(paper_dir, jar_name), 'wb') as f:
            shutil.copyfileobj(response.raw, f)
        print("[INFO] Download complete.")
        return jar_name
    else:
        print("[ERROR] Failed to download the latest jar.")
        return None

def get_existing_jar():
    for filename in os.listdir(paper_dir):
        if filename.startswith("paper-") and filename.endswith(".jar"):
            return filename
    return None

def main():
    print(f"({get_current_time()}) Checking for updates...")
    latest_build = get_latest_build()
    if latest_build is None:
        return

    latest_jar = construct_jar_name(latest_build)
    existing_jar = get_existing_jar()

    if existing_jar == latest_jar:
        print("[INFO] Latest jar is already present. No update needed.")
    else:
        # Remove old jar(s)
        for filename in os.listdir(paper_dir):
            if filename.startswith("paper-") and filename.endswith(".jar"):
                print(f"[INFO] Removing old jar: {filename}")
                os.remove(os.path.join(paper_dir, filename))

        # Download new jar
        downloaded = download_latest_jar(latest_build)
        if not downloaded:
            print("[ERROR] Could not download latest jar.")
            return

    print("[INFO] Update check complete. Control returning to batch file.")

def get_current_time():
    from datetime import datetime
    return datetime.now().strftime("%H:%M:%S.%f")[:-3]

if __name__ == "__main__":
    main()

This downloads the latest Paper version and auto deletes the old one. Below is an example of how I use paper_updater.py with a windows batch file.

Code:
@echo off
setlocal enabledelayedexpansion
title Paper Minecraft Server Updater + Launcher

:: STEP 1: Check for updates
echo (%time%) Checking for updates...
python paper_updater.py

:: STEP 2: Find latest Paper jar
for /f "delims=" %%f in ('dir /b /a:-d /o-d "paper-*.jar"') do (
    set "jarname=%%f"
    goto launch_server
)

echo ERROR: No paper-*.jar file found!
pause
exit /b

:launch_server
:: STEP 3: Run the server in a loop if it crashes
:server_loop
echo (%time%) Starting Minecraft server using !jarname!...
"C:\Program Files\Java\jdk-24\bin\java.exe" -Xms8G -Xmx12G -jar "!jarname!" --nogui

echo (%time%) WARNING: Server stopped or crashed! Restarting in 5 seconds...
timeout /t 5
goto server_loop