smodusermc commited on
Commit
96f2a19
Β·
verified Β·
1 Parent(s): 6b9b587

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -100
app.py CHANGED
@@ -9,7 +9,6 @@ import time
9
  from datetime import datetime
10
  from functools import wraps
11
  from pathlib import Path
12
- import requests
13
  import subprocess
14
 
15
  from flask import Flask, render_template, request, jsonify, redirect, url_for, session, send_file, Response
@@ -58,106 +57,105 @@ def login_required(f):
58
  return f(*args, **kwargs)
59
  return decorated_function
60
 
61
- def start_playit_agent():
 
 
 
 
62
  """
63
- Starts the PlayIt.gg agent and polls its local API to find
64
- the public tunnel address.
65
  """
66
- if not os.environ.get('PLAYIT_SECRET_KEY'):
67
- print("=" * 50)
68
- print("⚠️ PLAYIT_SECRET_KEY NOT FOUND ⚠️")
69
- print("PlayIt.gg tunnel will NOT start.")
70
- print("Please set the PLAYIT_SECRET_KEY environment variable.")
71
- print("=" * 50)
72
- server_manager.log("PLAYIT_SECRET_KEY missing. PlayIt.gg agent not started.", "error")
73
- return
74
 
75
- print("=" * 50)
76
- print("πŸš€ STARTING PLAYIT.GG AGENT (Polling for Address) πŸš€")
77
- print("=" * 50)
 
 
 
 
 
78
 
79
- # 1. Launch the agent in the background
 
 
 
 
 
 
 
 
80
  try:
81
- # Use subprocess.Popen to start the agent (we don't need to capture output anymore)
82
  subprocess.Popen(
83
  ['playit', 'run', '--api-address', '127.0.0.1:9000'],
84
- # Note: We added --api-address to ensure the API port is explicit
85
- stdout=subprocess.DEVNULL, # Send output to nowhere
86
- stderr=subprocess.DEVNULL # Send errors to nowhere
87
  )
88
- server_manager.log("PlayIt.gg agent launched. Starting polling thread...", "info")
89
- except Exception as e:
90
- server_manager.log(f"Error launching PlayIt.gg agent: {e}", "error")
91
- return
92
-
93
- # 2. Poll the local API until the tunnel address is found
94
- API_URL = "http://127.0.0.1:9000/api/v1/status"
95
- MAX_ATTEMPTS = 60 # Poll for up to 60 seconds (1 minute)
96
-
97
- for attempt in range(MAX_ATTEMPTS):
98
- time.sleep(1) # Wait 1 second between attempts
99
 
100
- try:
101
- response = requests.get(API_URL, timeout=5)
102
- data = response.json()
103
-
104
- # The structure of the status API is a list of tunnels
105
- for tunnel in data.get('tunnels', []):
106
- # Look for a tunnel that targets the Minecraft port (25565)
107
- if tunnel.get('target_ip') == '127.0.0.1' and tunnel.get('target_port') == config.SERVER_PORT:
108
- # Get the first available public address from the tunnel info
109
- public_address_info = tunnel.get('available_addresses', [None])[0]
110
-
111
- if public_address_info:
112
- # Format is {host}.playit.gg:port
113
- public_address = f"{public_address_info['host']}:{public_address_info['port']}"
114
-
115
- print("=" * 50)
116
- print(f"πŸŽ‰ PLAYIT.GG TUNNEL ESTABLISHED! πŸŽ‰")
117
- print(f"MINECRAFT ADDRESS: **{public_address}**")
118
- print("=" * 50)
119
-
120
- server_manager.log(f"PlayIt.gg Tunnel Ready: {public_address}", "success")
121
- socketio.emit('server_connect_info', {'address': public_address, 'type': 'playit'})
122
- return # Success! Exit the polling loop
123
-
124
- # If tunnels were found but the correct one wasn't ready yet, continue polling
125
- if data.get('tunnels'):
126
- server_manager.log(f"Attempt {attempt+1}/{MAX_ATTEMPTS}: PlayIt agent running, tunnel not yet ready...", "info")
127
- else:
128
- server_manager.log(f"Attempt {attempt+1}/{MAX_ATTEMPTS}: Waiting for PlayIt API...", "info")
129
-
130
- except requests.exceptions.ConnectionError:
131
- # PlayIt agent hasn't started its API yet
132
- server_manager.log(f"Attempt {attempt+1}/{MAX_ATTEMPTS}: PlayIt agent API not yet available...", "info")
133
- except Exception as e:
134
- server_manager.log(f"Error reading PlayIt API: {e}", "error")
135
-
136
- # If the loop finishes without finding the address
137
- server_manager.log("PlayIt.gg tunnel address not found after 60 seconds.", "error")
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- # --- Tunneling/Connection Display Setup (Updated for PlayIt.gg) ---
141
- def start_tunneling():
142
- # This function is now mainly for initial display and is called after the
143
- # PlayIt agent is started in its own thread.
144
  connect_address = f"{config.SPACE_URL}:{config.SERVER_PORT}"
145
 
146
- # We can't know the PlayIt.gg tunnel address immediately, as it's generated
147
- # asynchronously by the agent. We instruct the user to check the logs.
148
  print("=" * 50)
149
  print("🌐 MINECRAFT CONNECTION INFO 🌐")
150
  print(f"Web Panel Address: {connect_address}")
151
  print("------------------------------------------")
152
- print("MC Tunnel: **CHECK THE CONTAINER LOGS**")
153
- print("The PlayIt.gg agent will print the public address once connected.")
 
 
 
 
 
 
 
 
 
 
 
154
  print("------------------------------------------")
155
  print("=" * 50)
156
 
157
- server_manager.log(f"Web Panel Address: {connect_address}", "info")
158
- server_manager.log("PlayIt.gg agent started. Check logs for the public tunnel address.", "info")
159
- # Emit a placeholder address for the UI until the user finds the real one in logs
160
- socketio.emit('server_connect_info', {'address': 'Check logs for PlayIt.gg address', 'type': 'playit'})
 
161
 
162
 
163
  # --- Automated Save/Cleanup Thread ---
@@ -196,31 +194,31 @@ def logout():
196
  @login_required
197
  def index():
198
  return render_template('index.html',
199
- status=server_manager.get_status(),
200
- mods_count=len(mod_manager.get_installed_mods()))
201
 
202
  @app.route('/console')
203
  @login_required
204
  def console():
205
  return render_template('console.html',
206
- history=server_manager.get_console_history(200))
207
 
208
  @app.route('/players')
209
  @login_required
210
  def players():
211
  return render_template('players.html',
212
- online=server_manager.players_online,
213
- all_players=player_tracker.get_all_players(),
214
- whitelist=player_tracker.get_whitelist(),
215
- ops=player_tracker.get_ops(),
216
- banned=player_tracker.get_banned())
217
 
218
  @app.route('/mods')
219
  @login_required
220
  def mods():
221
  return render_template('mods.html',
222
- mods=mod_manager.get_installed_mods(),
223
- total_size=mod_manager.get_total_size())
224
 
225
  @app.route('/files')
226
  @app.route('/files/<path:filepath>')
@@ -228,22 +226,22 @@ def mods():
228
  def files(filepath=''):
229
  dir_content = file_manager.list_directory(filepath)
230
  return render_template('files.html',
231
- content=dir_content,
232
- current_path=filepath)
233
 
234
  @app.route('/import')
235
  @login_required
236
  def import_page():
237
  return render_template('import.html',
238
- backups=file_manager.list_backups())
239
 
240
  @app.route('/settings')
241
  @login_required
242
  def settings():
243
  props = file_manager.get_server_properties()
244
  return render_template('settings.html',
245
- properties=props,
246
- pinger_status=health_pinger.get_status())
247
 
248
  # --- API Routes ---
249
 
@@ -524,12 +522,9 @@ def main():
524
  print(f"MC Server: Port {config.SERVER_PORT}")
525
  print("=" * 50)
526
 
527
- # NEW: Start the PlayIt.gg agent
528
  threading.Thread(target=start_playit_agent, daemon=True).start()
529
 
530
- # 1. Start the Tunneling/Connection Display
531
- threading.Thread(target=start_tunneling, daemon=True).start()
532
-
533
  # 2. Start the Auto-Save and Cleanup Thread
534
  threading.Thread(target=start_auto_save_cleanup_thread, daemon=True).start()
535
 
 
9
  from datetime import datetime
10
  from functools import wraps
11
  from pathlib import Path
 
12
  import subprocess
13
 
14
  from flask import Flask, render_template, request, jsonify, redirect, url_for, session, send_file, Response
 
57
  return f(*args, **kwargs)
58
  return decorated_function
59
 
60
+ # ====================================================================
61
+ # === START PLAYIT.GG AGENT FUNCTIONS (CLAIM/SECRET KEY LOGIC) ===
62
+ # ====================================================================
63
+
64
+ def run_playit_claim_mode():
65
  """
66
+ Executes 'playit claim' to generate a claim code, required when the key is missing.
 
67
  """
68
+ try:
69
+ # Run 'playit claim' synchronously to get the output
70
+ result = subprocess.run(
71
+ ['playit', 'claim'],
72
+ capture_output=True,
73
+ text=True,
74
+ timeout=10
75
+ )
76
 
77
+ if result.returncode == 0:
78
+ # The claim code is usually the last word printed by the command
79
+ claim_code = result.stdout.strip().split()[-1]
80
+ # Call the display function with the claim code
81
+ start_tunneling(claim_code=claim_code)
82
+ else:
83
+ server_manager.log(f"PlayIt claim failed: {result.stderr.strip()}", "error")
84
+ start_tunneling(error_message="PlayIt 'claim' failed.")
85
 
86
+ except Exception as e:
87
+ server_manager.log(f"Error during PlayIt claim: {e}", "error")
88
+ start_tunneling(error_message="PlayIt claim encountered an error.")
89
+
90
+
91
+ def run_playit_secret_mode():
92
+ """
93
+ Launches the 'playit run' agent in the background when the SECRET_KEY is present.
94
+ """
95
  try:
96
+ # Launch the agent in the background
97
  subprocess.Popen(
98
  ['playit', 'run', '--api-address', '127.0.0.1:9000'],
99
+ stdout=subprocess.DEVNULL, # Keep console clean
100
+ stderr=subprocess.DEVNULL
 
101
  )
102
+ server_manager.log("PlayIt.gg agent launched with SECRET KEY. The public address should appear in the main logs shortly.", "info")
103
+ # Display the connection info immediately
104
+ start_tunneling(secret_mode=True)
 
 
 
 
 
 
 
 
105
 
106
+ except Exception as e:
107
+ server_manager.log(f"Error launching PlayIt.gg agent with key: {e}", "error")
108
+ start_tunneling(error_message="PlayIt 'run' failed with Secret Key. Check logs.")
109
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
+ def start_playit_agent():
112
+ """
113
+ Determines which PlayIt.gg mode to run based on the environment variable.
114
+ """
115
+ if os.environ.get('PLAYIT_SECRET_KEY'):
116
+ print("=" * 50)
117
+ print("πŸš€ STARTING PLAYIT.GG AGENT (Secret Key Mode) πŸš€")
118
+ print("=" * 50)
119
+ run_playit_secret_mode()
120
+ else:
121
+ print("=" * 50)
122
+ print("πŸ”‘ STARTING PLAYIT.GG AGENT (Claim Code Mode) πŸ”‘")
123
+ print("Action Required: Go to playit.gg/claim and enter the code below.")
124
+ print("=" * 50)
125
+ run_playit_claim_mode()
126
+
127
 
128
+ def start_tunneling(claim_code=None, secret_mode=False, error_message=None):
129
+ """
130
+ Displays the connection information based on the current PlayIt mode.
131
+ """
132
  connect_address = f"{config.SPACE_URL}:{config.SERVER_PORT}"
133
 
 
 
134
  print("=" * 50)
135
  print("🌐 MINECRAFT CONNECTION INFO 🌐")
136
  print(f"Web Panel Address: {connect_address}")
137
  print("------------------------------------------")
138
+
139
+ if error_message:
140
+ print(f"MC Tunnel: **ERROR: {error_message}**")
141
+ socketio.emit('server_connect_info', {'address': error_message, 'type': 'error'})
142
+ elif claim_code:
143
+ print(f"MC Tunnel: CLAIM CODE")
144
+ print(f"Claim Code: **{claim_code}** (Use at playit.gg/claim)")
145
+ socketio.emit('server_connect_info', {'address': f'CLAIM: {claim_code}', 'type': 'claim'})
146
+ elif secret_mode:
147
+ print("MC Tunnel: **CHECK THE CONTAINER LOGS**")
148
+ print("The PlayIt.gg agent is running and will print the public address once connected.")
149
+ socketio.emit('server_connect_info', {'address': 'Agent Running (Check Logs)', 'type': 'playit'})
150
+
151
  print("------------------------------------------")
152
  print("=" * 50)
153
 
154
+ server_manager.log(f"Connect Address: {connect_address}", "info")
155
+
156
+ # ====================================================================
157
+ # === END PLAYIT.GG AGENT FUNCTIONS ===
158
+ # ====================================================================
159
 
160
 
161
  # --- Automated Save/Cleanup Thread ---
 
194
  @login_required
195
  def index():
196
  return render_template('index.html',
197
+ status=server_manager.get_status(),
198
+ mods_count=len(mod_manager.get_installed_mods()))
199
 
200
  @app.route('/console')
201
  @login_required
202
  def console():
203
  return render_template('console.html',
204
+ history=server_manager.get_console_history(200))
205
 
206
  @app.route('/players')
207
  @login_required
208
  def players():
209
  return render_template('players.html',
210
+ online=server_manager.players_online,
211
+ all_players=player_tracker.get_all_players(),
212
+ whitelist=player_tracker.get_whitelist(),
213
+ ops=player_tracker.get_ops(),
214
+ banned=player_tracker.get_banned())
215
 
216
  @app.route('/mods')
217
  @login_required
218
  def mods():
219
  return render_template('mods.html',
220
+ mods=mod_manager.get_installed_mods(),
221
+ total_size=mod_manager.get_total_size())
222
 
223
  @app.route('/files')
224
  @app.route('/files/<path:filepath>')
 
226
  def files(filepath=''):
227
  dir_content = file_manager.list_directory(filepath)
228
  return render_template('files.html',
229
+ content=dir_content,
230
+ current_path=filepath)
231
 
232
  @app.route('/import')
233
  @login_required
234
  def import_page():
235
  return render_template('import.html',
236
+ backups=file_manager.list_backups())
237
 
238
  @app.route('/settings')
239
  @login_required
240
  def settings():
241
  props = file_manager.get_server_properties()
242
  return render_template('settings.html',
243
+ properties=props,
244
+ pinger_status=health_pinger.get_status())
245
 
246
  # --- API Routes ---
247
 
 
522
  print(f"MC Server: Port {config.SERVER_PORT}")
523
  print("=" * 50)
524
 
525
+ # 1. Start the PlayIt.gg agent (handles Claim Code or Secret Key run)
526
  threading.Thread(target=start_playit_agent, daemon=True).start()
527
 
 
 
 
528
  # 2. Start the Auto-Save and Cleanup Thread
529
  threading.Thread(target=start_auto_save_cleanup_thread, daemon=True).start()
530