KC9UZR

MIT Unifyed Minecraft AI Automatic Self Replication Server

Jun 22nd, 2025
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.62 KB | None | 0 0
  1. import os
  2. import subprocess
  3. import requests
  4. import json
  5. import time
  6. import sys
  7.  
  8. # --- Server Configuration ---
  9. SERVER_DIRECTORY = "minecraft_server"
  10. SERVER_JAR_NAME = "paper.jar"
  11. GEYSER_JAR_NAME = "Geyser-Spigot.jar"
  12. SERVER_MEMORY_MB = 4096
  13. SESSION_NAME = "mc_server"
  14.  
  15. # --- API URLs for Updates ---
  16. PAPER_API_URL = "https://api.papermc.io/v2/projects/paper"
  17. GEYSER_API_URL = "https://ci.geysermc.org/job/Geyser-Spigot/lastSuccessfulBuild/api/json"
  18.  
  19. # --- Color Definitions ---
  20. COLORS = {
  21.     "red": "\033[31m", "green": "\033[32m", "yellow": "\033[33m", "blue": "\033[34m",
  22.     "magenta": "\033[35m", "cyan": "\033[36m", "bright_blue": "\033[94m",
  23.     "bright_green": "\033[92m", "bright_magenta": "\033[95m", "bright_yellow": "\033[93m",
  24.     "end": "\033[0m", "bold": "\033[1m",
  25. }
  26.  
  27. RAINBOW_COLORS = [
  28.     COLORS["red"], COLORS["yellow"], COLORS["green"], COLORS["cyan"], COLORS["blue"], COLORS["magenta"]
  29. ]
  30.  
  31. def rainbow_text(text):
  32.     output = ""
  33.     for i, char in enumerate(text):
  34.         output += RAINBOW_COLORS[i % len(RAINBOW_COLORS)] + char
  35.     output += COLORS["end"]
  36.     print(output)
  37.  
  38. def clear_screen():
  39.     os.system('cls' if os.name == 'nt' else 'clear')
  40.  
  41. def print_header():
  42.     clear_screen()
  43.     rainbow_text("======================================================")
  44.     rainbow_text("==  Unified Minecraft Server Manager (Java+Bedrock) ==")
  45.     rainbow_text("==                 MIT Programming Class            ==")
  46.     rainbow_text("======================================================")
  47.     print("")
  48.  
  49. def download_file(url, filename):
  50.     print(f"{COLORS['yellow']}Downloading {os.path.basename(filename)}...{COLORS['end']}")
  51.     try:
  52.         with requests.get(url, stream=True) as r:
  53.             r.raise_for_status()
  54.             total_size = int(r.headers.get('content-length', 0))
  55.             block_size = 8192
  56.             with open(filename, 'wb') as f:
  57.                 downloaded = 0
  58.                 for chunk in r.iter_content(chunk_size=block_size):
  59.                     f.write(chunk)
  60.                     downloaded += len(chunk)
  61.                     done = int(50 * downloaded / total_size) if total_size > 0 else 0
  62.                     sys.stdout.write(f"\r[{'=' * done}{' ' * (50-done)}] {downloaded / (1024*1024):.2f} MB")
  63.                     sys.stdout.flush()
  64.         print(f"\n{COLORS['green']}Download complete!{COLORS['end']}")
  65.         return True
  66.     except requests.exceptions.RequestException as e:
  67.         print(f"\n{COLORS['red']}Error downloading file: {e}{COLORS['end']}")
  68.         return False
  69.  
  70. def update_server():
  71.     print_header()
  72.     print(f"{COLORS['cyan']}Checking for updates...{COLORS['end']}")
  73.     os.makedirs(SERVER_DIRECTORY, exist_ok=True)
  74.     try:
  75.         print(f"\n{COLORS['bright_blue']}--- Updating Paper Server ---{COLORS['end']}")
  76.         versions_res = requests.get(PAPER_API_URL).json()
  77.         latest_version = versions_res['versions'][-1]
  78.         builds_res = requests.get(f"{PAPER_API_URL}/versions/{latest_version}/builds").json()
  79.         latest_build = builds_res['builds'][-1]
  80.         build_number = latest_build['build']
  81.         jar_name = latest_build['downloads']['application']['name']
  82.         download_url = f"{PAPER_API_URL}/versions/{latest_version}/builds/{build_number}/downloads/{jar_name}"
  83.         download_file(download_url, os.path.join(SERVER_DIRECTORY, SERVER_JAR_NAME))
  84.     except Exception as e:
  85.         print(f"{COLORS['red']}Could not update Paper: {e}{COLORS['end']}")
  86.  
  87.     try:
  88.         print(f"\n{COLORS['bright_green']}--- Updating Geyser Proxy ---{COLORS['end']}")
  89.         geyser_res = requests.get(GEYSER_API_URL).json()
  90.         artifact = geyser_res['artifacts'][0]
  91.         download_url = f"{geyser_res['url']}artifact/{artifact['relativePath']}"
  92.         plugins_dir = os.path.join(SERVER_DIRECTORY, "plugins")
  93.         os.makedirs(plugins_dir, exist_ok=True)
  94.         download_file(download_url, os.path.join(plugins_dir, GEYSER_JAR_NAME))
  95.     except Exception as e:
  96.         print(f"{COLORS['red']}Could not update Geyser: {e}{COLORS['end']}")
  97.     input(f"\n{COLORS['bold']}Updates complete. Press Enter to return...{COLORS['end']}")
  98.  
  99. def initial_setup():
  100.     print_header()
  101.     print(f"{COLORS['yellow']}Performing first-time setup...{COLORS['end']}")
  102.     update_server()
  103.     print(f"\n{COLORS['red']}{COLORS['bold']}You must agree to the Minecraft EULA.{COLORS['end']}")
  104.     try:
  105.         print(f"{COLORS['cyan']}Running server once to generate configuration files...{COLORS['end']}")
  106.         java_command = f"java -Xms1024M -Xmx1024M -jar {SERVER_JAR_NAME} --nogui"
  107.         subprocess.run(java_command, shell=True, cwd=SERVER_DIRECTORY, check=False, timeout=60, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
  108.     except subprocess.TimeoutExpired:
  109.         print("Server generated files and timed out (this is expected for setup).")
  110.     except Exception as e:
  111.         print(f"{COLORS['red']}An error occurred: {e}{COLORS['end']}")
  112.  
  113.     try:
  114.         with open(os.path.join(SERVER_DIRECTORY, "eula.txt"), "w") as f:
  115.             f.write("eula=true\n")
  116.         print(f"{COLORS['green']}EULA accepted. 'eula.txt' created.{COLORS['end']}")
  117.     except Exception as e:
  118.         print(f"{COLORS['red']}Could not write eula.txt: {e}{COLORS['end']}")
  119.     input(f"\n{COLORS['bold']}Initial setup complete. Please use the menu to enable Bedrock support. Press Enter...{COLORS['end']}")
  120.  
  121. def enable_floodgate():
  122.     """Modifies the geyser config to allow bedrock accounts."""
  123.     print_header()
  124.     print(f"{COLORS['bright_yellow']}--- Enabling Bedrock Support (Floodgate) ---{COLORS['end']}")
  125.     geyser_config_path = os.path.join(SERVER_DIRECTORY, "plugins", "Geyser-Spigot", "config.yml")
  126.  
  127.     if not os.path.exists(geyser_config_path):
  128.         print(f"{COLORS['red']}Error: Geyser config not found!{COLORS['end']}")
  129.         print(f"Please run the server at least ONCE to generate the file '{geyser_config_path}'")
  130.         input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  131.         return
  132.  
  133.     try:
  134.         with open(geyser_config_path, 'r') as f:
  135.             lines = f.readlines()
  136.  
  137.         new_lines = []
  138.         changed = False
  139.         for line in lines:
  140.             if line.strip().startswith("auth-type:"):
  141.                 if "floodgate" in line:
  142.                     print(f"{COLORS['green']}Bedrock support is already enabled (auth-type is 'floodgate').{COLORS['end']}")
  143.                     input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  144.                     return
  145.                 new_lines.append(line.replace("online", "floodgate"))
  146.                 changed = True
  147.             else:
  148.                 new_lines.append(line)
  149.  
  150.         if changed:
  151.             with open(geyser_config_path, 'w') as f:
  152.                 f.writelines(new_lines)
  153.             print(f"{COLORS['green']}Successfully updated Geyser 'config.yml' for Bedrock support.{COLORS['end']}")
  154.         else:
  155.             print(f"{COLORS['yellow']}Could not find 'auth-type' setting. It might have already been changed.{COLORS['end']}")
  156.  
  157.     except Exception as e:
  158.         print(f"{COLORS['red']}An error occurred while modifying the config file: {e}{COLORS['end']}")
  159.     input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  160.  
  161. def is_server_running():
  162.     result = subprocess.run(f"screen -ls | grep -q '\\.{SESSION_NAME}\\s'", shell=True)
  163.     return result.returncode == 0
  164.  
  165. def start_server():
  166.     print_header()
  167.     if is_server_running():
  168.         print(f"{COLORS['yellow']}Server is already running!{COLORS['end']}")
  169.         print(f"To connect to its console, type: {COLORS['cyan']}screen -r {SESSION_NAME}{COLORS['end']}")
  170.     else:
  171.         print(f"{COLORS['green']}Starting server...{COLORS['end']}")
  172.         if not os.path.exists(os.path.join(SERVER_DIRECTORY, SERVER_JAR_NAME)):
  173.             print(f"{COLORS['red']}Server JAR not found! Run setup/update first.{COLORS['end']}")
  174.             input(f"\n{COLORS['bold']}Press Enter...{COLORS['end']}")
  175.             return
  176.  
  177.         java_command = f"java -Xms{SERVER_MEMORY_MB}M -Xmx{SERVER_MEMORY_MB}M -jar {SERVER_JAR_NAME} --nogui"
  178.         screen_command = f"screen -dmS {SESSION_NAME} {java_command}"
  179.         subprocess.run(screen_command, shell=True, cwd=SERVER_DIRECTORY)
  180.         print(f"Server starting in screen session '{COLORS['cyan']}{SESSION_NAME}{COLORS['end']}'.")
  181.     input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  182.  
  183. def stop_server():
  184.     print_header()
  185.     if not is_server_running():
  186.         print(f"{COLORS['yellow']}Server is not currently running.{COLORS['end']}")
  187.     else:
  188.         print(f"{COLORS['red']}Stopping server gracefully...{COLORS['end']}")
  189.         subprocess.run(f"screen -S {SESSION_NAME} -X stuff 'stop\n'", shell=True)
  190.     input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  191.  
  192. def open_console():
  193.     if not is_server_running():
  194.         print_header()
  195.         print(f"{COLORS['yellow']}Server is not running.{COLORS['end']}")
  196.         input(f"\n{COLORS['bold']}Press Enter to return...{COLORS['end']}")
  197.     else:
  198.         print(f"{COLORS['green']}Attaching to console... Press {COLORS['bold']}CTRL+A, then D{COLORS['end']}{COLORS['green']} to detach.{COLORS['end']}")
  199.         time.sleep(3)
  200.         os.system(f"screen -r {SESSION_NAME}")
  201.  
  202. def main_menu():
  203.     while True:
  204.         print_header()
  205.         status = f"{COLORS['green']}ONLINE{COLORS['end']}" if is_server_running() else f"{COLORS['red']}OFFLINE{COLORS['end']}"
  206.         print(f"Server Status: {status}\n")
  207.         print(f"{COLORS['bright_yellow']}--- Main Menu ---{COLORS['end']}")
  208.         print(f"1. Start Server")
  209.         print(f"2. Stop Server")
  210.         print(f"3. Open Server Console")
  211.         print(f"\n{COLORS['bright_magenta']}--- Maintenance ---{COLORS['end']}")
  212.         print(f"4. Update Server (Paper & Geyser)")
  213.         print(f"5. Enable Bedrock Support (Floodgate)")
  214.         print(f"6. Perform First-Time Setup")
  215.         print(f"\n{COLORS['red']}7. Exit{COLORS['end']}")
  216.        
  217.         choice = input(f"\n{COLORS['bold']}Enter your choice [1-7]: {COLORS['end']}")
  218.  
  219.         if choice == '1': start_server()
  220.         elif choice == '2': stop_server()
  221.         elif choice == '3': open_console()
  222.         elif choice == '4': update_server()
  223.         elif choice == '5': enable_floodgate()
  224.         elif choice == '6': initial_setup()
  225.         elif choice == '7':
  226.             print(f"\n{COLORS['green']}Goodbye!{COLORS['end']}")
  227.             break
  228.         else:
  229.             print(f"\n{COLORS['red']}Invalid choice.{COLORS['end']}"); time.sleep(1)
  230.  
  231. if __name__ == "__main__":
  232.     if not os.path.isdir(SERVER_DIRECTORY):
  233.         initial_setup()
  234.     main_menu()
Add Comment
Please, Sign In to add comment