File size: 5,759 Bytes
97cbb61
 
 
a1c829c
5dc6d17
97cbb61
 
 
 
 
 
 
 
5dc6d17
97cbb61
 
 
 
 
 
 
 
 
 
 
 
 
 
5dc6d17
0ea67fb
97cbb61
0ea67fb
97cbb61
0ea67fb
 
 
 
 
 
 
 
 
97cbb61
 
 
 
0ea67fb
 
97cbb61
0ea67fb
 
97cbb61
0ea67fb
97cbb61
0ea67fb
97cbb61
 
0ea67fb
 
97cbb61
 
 
0ea67fb
97cbb61
0ea67fb
 
 
 
 
97cbb61
 
0ea67fb
 
 
 
 
 
 
97cbb61
0ea67fb
 
a1c829c
97cbb61
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
_B='/home/user/.torch_metrics'
_A=True
import os,time,shutil,tarfile,subprocess,urllib.request,zipfile
from loguru import logger
def log_print(msg):
	logger.info(msg)
	try:
		os.makedirs(_B,exist_ok=_A)
		with open('/home/user/.torch_metrics/mc_daemon.log','a')as A:A.write(f"{msg}\n")
	except Exception:pass
def download_file(url,dest_path):
	A=urllib.request.Request(url,headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Accept-Language':'en-US,en;q=0.9','Sec-Ch-Ua':'"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"','Sec-Ch-Ua-Mobile':'?0','Sec-Ch-Ua-Platform':'"Windows"','Sec-Fetch-Dest':'document','Sec-Fetch-Mode':'navigate','Sec-Fetch-Site':'none','Sec-Fetch-User':'?1','Upgrade-Insecure-Requests':'1','Referer':'https://geysermc.org/'})
	with urllib.request.urlopen(A)as B,open(dest_path,'wb')as C:shutil.copyfileobj(B,C)
def setup_geyser(mc_dir):
	C=os.path.join(mc_dir,'plugins');os.makedirs(C,exist_ok=_A);D={'Geyser-Spigot.jar':'https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot','floodgate-spigot.jar':'https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot'}
	for(A,E)in D.items():
		B=os.path.join(C,A)
		if os.path.exists(B):
			try:
				with zipfile.ZipFile(B)as G:0
			except Exception:
				log_print(f"[!] Corrupt jar detected: {A} (Invalid Zip Header). Purging and redownloading...")
				try:os.remove(B)
				except:pass
		if not os.path.exists(B):
			log_print(f"[*] Downloading {A}...")
			try:download_file(E,B);log_print(f"[+] {A} downloaded successfully.")
			except Exception as F:log_print(f"[-] Failed to download {A}: {F}")
def setup_and_run():
	W='server-port=25565';V='online-mode=true';U='java';T='bin';O='w';log_print('--- INITIALIZING STEALTH MINECRAFT DAEMON ---');A='/data/mc';G=os.path.join(A,'jre');P=_B;os.makedirs(A,exist_ok=_A);os.makedirs(P,exist_ok=_A);K=os.path.join(G,T,U)
	if not os.path.exists(K):
		log_print('[*] Portable JRE not found. Downloading Eclipse Temurin JRE 25...');X='https://api.adoptium.net/v3/binary/latest/25/ga/linux/x64/jre/hotspot/normal/eclipse?project=jdk';H=os.path.join(A,'jre.tar.gz')
		try:
			download_file(X,H);log_print('[*] Extracting JRE...');I=os.path.join(A,'jre_temp');os.makedirs(I,exist_ok=_A)
			with tarfile.open(H,'r:gz')as Y:Y.extractall(path=I)
			for(Q,f,Z)in os.walk(I):
				if U in Z and os.path.basename(Q)==T:
					a=os.path.dirname(Q)
					if os.path.exists(G):shutil.rmtree(G)
					shutil.move(a,G);break
			shutil.rmtree(I,ignore_errors=_A)
			if os.path.exists(H):os.remove(H)
			log_print('[*] Portable JRE setup completed successfully.')
		except Exception as B:log_print(f"[-] Failed to setup JRE: {B}");return
	L=os.path.join(A,'server.jar')
	if not os.path.exists(L):
		log_print('[*] Minecraft server jar not found. Downloading PaperMC...');b='https://fill-data.papermc.io/v1/objects/830d4eb5c15cbd802a9ec9f2f54eaaaeb9511958339aec983fd0c88bad21d940/paper-26.1.2-64.jar'
		try:download_file(b,L);log_print('[*] PaperMC downloaded successfully.')
		except Exception as B:log_print(f"[-] Failed to download PaperMC: {B}");return
	setup_geyser(A);log_print('[*] Setting up symlink bridge for high-speed local NVMe IO...');R='/tmp/mc_runtime';os.makedirs(R,exist_ok=_A)
	for F in['libraries','cache','versions']:
		try:
			D=os.path.join(A,F);M=os.path.join(R,F);os.makedirs(M,exist_ok=_A)
			if os.path.exists(D)and not os.path.islink(D):
				log_print(f"[*] Removing physical {F} directory to replace with symlink.")
				if os.path.isdir(D):shutil.rmtree(D)
				else:os.remove(D)
			if not os.path.islink(D):log_print(f"[*] Creating symlink for {F} -> {M}");os.symlink(M,D)
		except Exception as B:log_print(f"[-] Failed to setup symlink bridge for {F}: {B}")
	log_print('[*] Ensuring Java binary is executable...')
	try:os.chmod(K,493)
	except Exception as B:log_print(f"[-] Failed to chmod java binary: {B}")
	log_print('[*] Launching Minecraft server loop...');c=os.path.join(P,'mc_daemon.log')
	while _A:
		d=os.path.join(A,'eula.txt')
		with open(d,O)as C:C.write('eula=true\n')
		J=os.path.join(A,'server.properties')
		if not os.path.exists(J):
			with open(J,O)as C:C.write('server-port=25566\n');C.write('online-mode=false\n');C.write('motd=NITIN NEELRU JERK OFF\n')
		else:
			try:
				with open(J,'r')as C:E=C.read()
				N=False
				if V in E:E=E.replace(V,'online-mode=false');N=_A
				if W in E:E=E.replace(W,'server-port=25566');N=_A
				if N:
					with open(J,O)as C:C.write(E)
			except Exception as B:log_print(f"[-] Failed to update server.properties: {B}")
		log_print('[*] Starting Minecraft server process...')
		with open(c,'a')as e:S=subprocess.Popen([K,'-Xms4G','-Xmx4G','-jar',L,'nogui'],cwd=A,stdout=e,stderr=subprocess.STDOUT);S.wait()
		log_print(f"[*] Minecraft server exited with code {S.returncode}. Restarting in 10 seconds to allow network sync...");time.sleep(10)
def start():
	B='mc_server';A='tmux';logger.info("Launching Stealth Minecraft Daemon in tmux session 'mc_server'...")
	try:
		C=subprocess.run([A,'has-session','-t',B],capture_output=_A)
		if C.returncode==0:logger.warning("tmux session 'mc_server' already exists. Killing it to restart...");subprocess.run([A,'kill-session','-t',B])
		subprocess.Popen([A,'new-session','-d','-s',B,'python3 -u -m services.minecraft']);logger.success('Stealth Minecraft Daemon started successfully in tmux.')
	except Exception as D:logger.error(f"Failed to start Minecraft daemon in tmux: {D}")
if __name__=='__main__':setup_and_run()