aldigobbler commited on
Commit
33671b3
·
verified ·
1 Parent(s): 378852a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +189 -5
app.py CHANGED
@@ -4,8 +4,12 @@ import os
4
  import subprocess
5
  import sys
6
  import shutil
 
 
 
 
 
7
 
8
- # Try to import pyngrok, install if not available
9
  try:
10
  from pyngrok import ngrok, conf
11
  PYNGROK_AVAILABLE = True
@@ -384,6 +388,148 @@ def start_server():
384
  print(f"Failed to start server: {e}")
385
  return False
386
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  def cleanup_ngrok():
388
  """Clean up ngrok tunnels on exit"""
389
  if PYNGROK_AVAILABLE:
@@ -393,7 +539,22 @@ def cleanup_ngrok():
393
  except:
394
  pass
395
 
 
 
 
 
 
 
 
 
 
 
 
396
  if __name__ == "__main__":
 
 
 
 
397
  print("=== Minecraft Server Setup ===")
398
 
399
  try:
@@ -408,17 +569,40 @@ if __name__ == "__main__":
408
  else:
409
  print("\n=== Starting ngrok tunnel ===")
410
  tunnel, tunnel_url = start_ngrok_tunnel()
411
- if not tunnel:
 
 
 
 
 
412
  print("Failed to start ngrok tunnel. Server will start but won't be accessible externally.")
413
 
414
  print("\n=== Starting Minecraft Server ===")
415
- start_server()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
  except KeyboardInterrupt:
418
  print("\n\nShutting down...")
419
- cleanup_ngrok()
420
  sys.exit(0)
421
  except Exception as e:
422
  print(f"Unexpected error: {e}")
423
- cleanup_ngrok()
424
  sys.exit(1)
 
4
  import subprocess
5
  import sys
6
  import shutil
7
+ from mcstatus import JavaServer
8
+ import gradio as gr
9
+ import threading
10
+ import time
11
+ import signal
12
 
 
13
  try:
14
  from pyngrok import ngrok, conf
15
  PYNGROK_AVAILABLE = True
 
388
  print(f"Failed to start server: {e}")
389
  return False
390
 
391
+ def start_server_background():
392
+ """Start the Minecraft server in the background"""
393
+ global server_process
394
+
395
+ if not JAR_PATH.exists():
396
+ print("Server JAR not found. Run setup first.")
397
+ return False
398
+
399
+ # Get Java path
400
+ java_path = check_java()
401
+ if not java_path:
402
+ print("Java not found. Run setup first.")
403
+ return False
404
+
405
+ # Change to the data directory
406
+ original_cwd = os.getcwd()
407
+ os.chdir(DATA_DIR)
408
+
409
+ # Start the server
410
+ cmd = [
411
+ java_path,
412
+ "-Xmx2G", # Max heap size
413
+ "-Xms1G", # Initial heap size
414
+ "-jar", str(JAR_PATH),
415
+ "--nogui"
416
+ ]
417
+
418
+ print(f"Starting Minecraft server in background with command: {' '.join(cmd)}")
419
+ print(f"Working directory: {DATA_DIR}")
420
+
421
+ try:
422
+ server_process = subprocess.Popen(
423
+ cmd,
424
+ stdout=subprocess.PIPE,
425
+ stderr=subprocess.STDOUT,
426
+ universal_newlines=True,
427
+ bufsize=1,
428
+ cwd=DATA_DIR
429
+ )
430
+
431
+ # Start a thread to monitor server output
432
+ def monitor_server():
433
+ for line in server_process.stdout:
434
+ print(f"[SERVER] {line.strip()}")
435
+
436
+ monitor_thread = threading.Thread(target=monitor_server, daemon=True)
437
+ monitor_thread.start()
438
+
439
+ # Wait a bit for server to start
440
+ time.sleep(5)
441
+
442
+ os.chdir(original_cwd)
443
+ print("✓ Minecraft server started in background")
444
+ return True
445
+
446
+ except Exception as e:
447
+ print(f"Failed to start server: {e}")
448
+ os.chdir(original_cwd)
449
+ return False
450
+
451
+ def get_server_status():
452
+ """Get current server status for Gradio interface"""
453
+ global server_ip
454
+
455
+ if not server_ip:
456
+ return "Server IP not available", "N/A", "N/A", "N/A"
457
+
458
+ try:
459
+ server = JavaServer.lookup(server_ip)
460
+ status = server.status()
461
+ latency = server.ping()
462
+
463
+ status_text = f"**Server Status:** {status.players.online} player(s) online, latency: {round(status.latency)} ms"
464
+ version_text = f"**Server Version:** {status.version.name} ({status.version.protocol})"
465
+ description_text = f"**Server Description:** {status.description}"
466
+
467
+ if status.players.sample:
468
+ players_text = f"**Players:** {', '.join(player.name for player in status.players.sample)}"
469
+ else:
470
+ players_text = "**Players:** No players online"
471
+
472
+ return status_text, version_text, description_text, players_text
473
+
474
+ except Exception as e:
475
+ error_msg = f"**Error:** Could not connect to server - {str(e)}"
476
+ return error_msg, "N/A", "N/A", "N/A"
477
+
478
+ def create_gradio_interface():
479
+ """Create and return the Gradio interface"""
480
+ global server_ip
481
+
482
+ with gr.Blocks(title="Minecraft Server Manager") as demo:
483
+ gr.Markdown("# Minecraft Server Status Monitor")
484
+
485
+ if server_ip:
486
+ gr.Markdown(f"**Server IP:** {server_ip}")
487
+ else:
488
+ gr.Markdown("**Server IP:** Not available yet")
489
+
490
+ # Initial status
491
+ try:
492
+ if server_ip:
493
+ initial_status = get_server_status()
494
+ else:
495
+ initial_status = ("Server starting...", "N/A", "N/A", "N/A")
496
+ except:
497
+ initial_status = ("Server not ready", "N/A", "N/A", "N/A")
498
+
499
+ status_markdown = gr.Markdown(initial_status[0])
500
+ version_markdown = gr.Markdown(initial_status[1])
501
+ description_markdown = gr.Markdown(initial_status[2])
502
+ players_markdown = gr.Markdown(initial_status[3])
503
+
504
+ btn = gr.Button("Refresh Status")
505
+ btn.click(
506
+ get_server_status,
507
+ outputs=[status_markdown, version_markdown, description_markdown, players_markdown]
508
+ )
509
+
510
+ # Auto-refresh every 30 seconds
511
+ demo.load(
512
+ get_server_status,
513
+ outputs=[status_markdown, version_markdown, description_markdown, players_markdown],
514
+ every=30
515
+ )
516
+
517
+ return demo
518
+
519
+ def stop_server():
520
+ """Stop the Minecraft server"""
521
+ global server_process
522
+
523
+ if server_process:
524
+ print("Stopping Minecraft server...")
525
+ server_process.terminate()
526
+ try:
527
+ server_process.wait(timeout=10)
528
+ except subprocess.TimeoutExpired:
529
+ server_process.kill()
530
+ server_process = None
531
+ print("✓ Minecraft server stopped")
532
+
533
  def cleanup_ngrok():
534
  """Clean up ngrok tunnels on exit"""
535
  if PYNGROK_AVAILABLE:
 
539
  except:
540
  pass
541
 
542
+ def cleanup_all():
543
+ """Clean up all resources"""
544
+ stop_server()
545
+ cleanup_ngrok()
546
+
547
+ def signal_handler(signum, frame):
548
+ """Handle shutdown signals"""
549
+ print("\nReceived shutdown signal. Cleaning up...")
550
+ cleanup_all()
551
+ sys.exit(0)
552
+
553
  if __name__ == "__main__":
554
+ # Register signal handlers
555
+ signal.signal(signal.SIGINT, signal_handler)
556
+ signal.signal(signal.SIGTERM, signal_handler)
557
+
558
  print("=== Minecraft Server Setup ===")
559
 
560
  try:
 
569
  else:
570
  print("\n=== Starting ngrok tunnel ===")
571
  tunnel, tunnel_url = start_ngrok_tunnel()
572
+ if tunnel:
573
+ ngrok_tunnel = tunnel
574
+ # Extract IP from tunnel URL (format: tcp://x.tcp.ngrok.io:port)
575
+ server_ip = tunnel_url.replace('tcp://', '')
576
+ print(f"Server will be accessible at: {server_ip}")
577
+ else:
578
  print("Failed to start ngrok tunnel. Server will start but won't be accessible externally.")
579
 
580
  print("\n=== Starting Minecraft Server ===")
581
+ if not start_server_background():
582
+ print("Failed to start server.")
583
+ cleanup_all()
584
+ sys.exit(1)
585
+
586
+ # Wait a bit for server to fully start
587
+ print("Waiting for server to start...")
588
+ time.sleep(10)
589
+
590
+ print("\n=== Starting Gradio Interface ===")
591
+ demo = create_gradio_interface()
592
+
593
+ # Launch Gradio interface
594
+ demo.launch(
595
+ server_name="0.0.0.0",
596
+ server_port=7860,
597
+ share=False,
598
+ show_error=True
599
+ )
600
 
601
  except KeyboardInterrupt:
602
  print("\n\nShutting down...")
603
+ cleanup_all()
604
  sys.exit(0)
605
  except Exception as e:
606
  print(f"Unexpected error: {e}")
607
+ cleanup_all()
608
  sys.exit(1)