Skip to content

Commit b6ac96a

Browse files
committed
1.52
1 parent dfd01e0 commit b6ac96a

File tree

1 file changed

+199
-143
lines changed

1 file changed

+199
-143
lines changed

src/craftserversetup.py

Lines changed: 199 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
VERSION_MANIFEST = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"
66
BUNGEECORD_DOWNLOAD_URL = "https://ci.md-5.net/job/BungeeCord/lastStableBuild/artifact/bootstrap/target/BungeeCord.jar"
77
APP_VERSION = 1#The API Version.
8-
APP_UF_VERSION = "1.51.1"
8+
APP_UF_VERSION = "1.52"
99
#The semver version
1010
UPDATEINSTALLED = False
1111
DOCFILE = "https://github.com/Enderbyte-Programs/CraftServerSetup/raw/main/doc/craftserversetup.epdoc"
@@ -43,6 +43,7 @@
4343
import shlex #Data parsing
4444
import re #Pattern matching
4545
import typing #HArd types
46+
import argparse #Arguments system
4647

4748
WINDOWS = platform.system() == "Windows"
4849

@@ -408,10 +409,35 @@ def assemble_package_file_path(serverdir:str):
408409
PORTABLE = True
409410
if "developer" in sfd:
410411
DEVELOPER = True
412+
"""
411413
if "-p" in sys.argv or "--portable" in sys.argv:
412414
PORTABLE = True
413415
if "-d" in sys.argv or "--developer" in sys.argv:
414416
DEVELOPER = True
417+
"""
418+
419+
argparser = argparse.ArgumentParser("CraftServerSetup",description="A TUI Minecraft Server maker and manager. Run without arguments for a standard interactive experience.",epilog="(c) 2023-2025 Enderbyte programs, some rights reserved. For support, please email [email protected]")
420+
argparser.add_argument('-p','--portable',action="store_true",required=False,help="Run CraftServerSetup self-contained",dest="p",default=False)
421+
argparser.add_argument('-d','--developer',action="store_true",required=False,help="Enable debug features",dest="d",default=False)
422+
argparser.add_argument('-m','--manage',help="Open management UI directly to the server id. Must not be used in conjunction with --start",required=False,default=0,dest="manage_id")#Manage a certain server
423+
argparser.add_argument("-s",'--start',help="Start the server id provided. Must not be used in conjunction with --manage",required=False,default=0,dest="start_id")#start a certain server
424+
out = argparser.parse_args()
425+
PORTABLE = out.p
426+
DEVELOPER = out.d
427+
428+
try:
429+
int(out.manage_id)
430+
int(out.start_id)
431+
except:
432+
print("ARGUMENT ERROR - Please specify the server id to manage or start.")
433+
sys.exit(4)
434+
435+
manageid = int(out.manage_id)
436+
startid = int(out.start_id)
437+
if manageid != 0 and startid != 0:
438+
print("ARGUMENT ERROR - You may not command a manage and a start at the same time.")
439+
sys.exit(4)
440+
415441
if not WINDOWS:
416442
APPDATADIR = os.path.expanduser("~/.local/share/mcserver")
417443
if PORTABLE:
@@ -3513,6 +3539,150 @@ def resource_warning(stdscr) -> bool:
35133539
else:
35143540
return False
35153541

3542+
def start_server(stdscr,_sname,chosenserver,SERVER_DIR):
3543+
if sys.version_info[1] < 11:
3544+
cursesplus.messagebox.showerror(stdscr,["Unfortunately, the new startups can only be used with Python 3.11 or newer.",f"You are running {sys.version}.","Your server will be started in legacy mode (pre 1.43)"])
3545+
APPDATA["servers"][chosenserver-1]["settings"]["legacy"] = True
3546+
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["launchcommands"]))
3547+
if APPDATA["servers"][chosenserver-1]["settings"]["legacy"]:
3548+
os.chdir(APPDATA["servers"][chosenserver-1]["dir"])
3549+
stdscr.clear()
3550+
stdscr.addstr(0,0,f"STARTING {str(datetime.datetime.now())[0:-5]}\n\r")
3551+
stdscr.refresh()
3552+
if not WINDOWS:
3553+
curses.curs_set(1)
3554+
curses.reset_shell_mode()
3555+
lretr = os.system(APPDATA["servers"][chosenserver-1]["script"])
3556+
#child = pexpect.spawn(APPDATA["servers"][chosenserver-1]["script"])
3557+
#child.expect("Finished")
3558+
curses.reset_prog_mode()
3559+
curses.curs_set(0)
3560+
else:
3561+
curses.curs_set(1)
3562+
curses.reset_shell_mode()
3563+
#COLOURS_ACTIVE = False
3564+
lretr = os.system("cmd /c ("+APPDATA["servers"][chosenserver-1]["script"]+")")
3565+
curses.reset_prog_mode()
3566+
curses.curs_set(0)
3567+
#restart_colour()
3568+
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["exitcommands"]))
3569+
if lretr != 0 and lretr != 127 and lretr != 128 and lretr != 130:
3570+
displog = cursesplus.messagebox.askyesno(stdscr,["Oh No! Your server crashed","Would you like to view the logs?"])
3571+
if displog:
3572+
view_server_logs(stdscr,SERVER_DIR)
3573+
stdscr.clear()
3574+
stdscr.refresh()
3575+
else:
3576+
if not _sname in SERVER_INITS:
3577+
truecommand = APPDATA["servers"][chosenserver-1]["script"]
3578+
if WINDOWS:
3579+
truecommand = "cmd /c ("+APPDATA["servers"][chosenserver-1]["script"]+")"
3580+
SERVER_INITS[_sname] = ServerRunWrapper(truecommand)
3581+
SERVER_INITS[_sname].launch()
3582+
cursesplus.messagebox.showinfo(stdscr,["The server has been started.","It will be ready for use in a few minutes"])
3583+
latestlogfile = SERVER_DIR+"/logs/latest.log"
3584+
#pos = 0
3585+
obuffer = ["Getting logs. Please wait...","The log may take some time to appear.","Don't worry, your server is still running."]
3586+
ooffset = 0
3587+
oxoffset = 0
3588+
tick = 0
3589+
#lfsize = os.path.getsize(latestlogfile)
3590+
stdscr.nodelay(1)
3591+
3592+
redraw = True
3593+
while True:
3594+
3595+
tick += 1
3596+
if tick % 30 == 0:
3597+
tick = 0
3598+
#SERVER_INITS[_sname].datastream.seek(0,0)
3599+
#obuffer = SERVER_INITS[_sname].datastream.readlines()
3600+
if os.path.isfile(latestlogfile):
3601+
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(latestlogfile))
3602+
if mtime < SERVER_INITS[_sname].runtime:
3603+
pass
3604+
else:
3605+
3606+
with open(latestlogfile) as f:
3607+
obc = f.readlines()
3608+
if obc != obuffer:
3609+
obuffer = obc
3610+
ooffset = len(obuffer)-my+headeroverhead
3611+
if ooffset < 0:
3612+
ooffset = 0
3613+
redraw = True
3614+
3615+
#Visual part
3616+
mx,my = os.get_terminal_size()
3617+
mx -= 1
3618+
my -= 1
3619+
headeroverhead = 5
3620+
if redraw:
3621+
stdscr.clear()
3622+
cursesplus.utils.fill_line(stdscr,0,cursesplus.set_colour(cursesplus.BLUE,cursesplus.WHITE))
3623+
stdscr.addstr(0,0,f"Live options for {_sname}",cursesplus.set_colour(cursesplus.BLUE,cursesplus.WHITE))
3624+
stdscr.addstr(1,0,"Press B to go back to the options")
3625+
stdscr.addstr(2,0,"Press C to run a command | Press K to kill the server")
3626+
stdscr.addstr(3,0,"Press S to stop the server")
3627+
stdscr.addstr(4,0,cursesplus.constants.THIN_HORIZ_LINE*mx)
3628+
oi = 5
3629+
for line in obuffer[ooffset:]:
3630+
try:
3631+
stdscr.addstr(oi,0,line[oxoffset:oxoffset+mx-1])
3632+
except:
3633+
break
3634+
oi += 1
3635+
3636+
svrstat = SERVER_INITS[_sname]
3637+
if not svrstat.isprocessrunning():
3638+
3639+
stdscr.nodelay(0)
3640+
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["exitcommands"]))
3641+
if svrstat.hascrashed():
3642+
displog = cursesplus.messagebox.askyesno(stdscr,["Oh No! Your server crashed","Would you like to view the logs?"])
3643+
if displog:
3644+
view_server_logs(stdscr,SERVER_DIR)
3645+
else:
3646+
cursesplus.messagebox.showinfo(stdscr,["The server has been stopped safely."])
3647+
del SERVER_INITS[_sname]
3648+
break
3649+
#stdscr.addstr(0,0,f"Y: {ooffset} X: {oxoffset}")
3650+
if redraw:
3651+
stdscr.refresh()
3652+
redraw = False
3653+
ch = stdscr.getch()
3654+
if ch == curses.KEY_UP and ooffset > 0:
3655+
ooffset -= 1
3656+
redraw = True
3657+
elif ch == curses.KEY_DOWN:
3658+
ooffset += 1
3659+
redraw = True
3660+
elif ch == curses.KEY_LEFT and oxoffset > 0:
3661+
oxoffset -= 1
3662+
redraw = True
3663+
elif ch == curses.KEY_RIGHT:
3664+
oxoffset += 1
3665+
redraw = True
3666+
3667+
elif ch == 98:
3668+
break
3669+
elif ch == 99:
3670+
stdscr.nodelay(0)
3671+
svrstat.send(crssinput(stdscr,"Enter a command to run"))
3672+
stdscr.nodelay(1)
3673+
elif ch == 115:
3674+
svrstat.send("stop")
3675+
pass
3676+
elif ch == 107:
3677+
stdscr.nodelay(0)
3678+
if cursesplus.messagebox.askyesno(stdscr,["Are you sure you want to kill the server?","This can corrupt data.","Only do this if you believe the server to be frozen"]):
3679+
svrstat.fullhalt()
3680+
stdscr.nodelay(1)
3681+
3682+
sleep(1/30)
3683+
3684+
stdscr.nodelay(0)
3685+
35163686
def manage_server(stdscr,_sname: str,chosenserver: int):
35173687
global APPDATA
35183688
global COLOURS_ACTIVE
@@ -3543,148 +3713,7 @@ def manage_server(stdscr,_sname: str,chosenserver: int):
35433713
break
35443714

35453715
elif w == 1:
3546-
if sys.version_info[1] < 11:
3547-
cursesplus.messagebox.showerror(stdscr,["Unfortunately, the new startups can only be used with Python 3.11 or newer.",f"You are running {sys.version}.","Your server will be started in legacy mode (pre 1.43)"])
3548-
APPDATA["servers"][chosenserver-1]["settings"]["legacy"] = True
3549-
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["launchcommands"]))
3550-
if APPDATA["servers"][chosenserver-1]["settings"]["legacy"]:
3551-
os.chdir(APPDATA["servers"][chosenserver-1]["dir"])
3552-
stdscr.clear()
3553-
stdscr.addstr(0,0,f"STARTING {str(datetime.datetime.now())[0:-5]}\n\r")
3554-
stdscr.refresh()
3555-
if not WINDOWS:
3556-
curses.curs_set(1)
3557-
curses.reset_shell_mode()
3558-
lretr = os.system(APPDATA["servers"][chosenserver-1]["script"])
3559-
#child = pexpect.spawn(APPDATA["servers"][chosenserver-1]["script"])
3560-
#child.expect("Finished")
3561-
curses.reset_prog_mode()
3562-
curses.curs_set(0)
3563-
else:
3564-
curses.curs_set(1)
3565-
curses.reset_shell_mode()
3566-
#COLOURS_ACTIVE = False
3567-
lretr = os.system("cmd /c ("+APPDATA["servers"][chosenserver-1]["script"]+")")
3568-
curses.reset_prog_mode()
3569-
curses.curs_set(0)
3570-
#restart_colour()
3571-
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["exitcommands"]))
3572-
if lretr != 0 and lretr != 127 and lretr != 128 and lretr != 130:
3573-
displog = cursesplus.messagebox.askyesno(stdscr,["Oh No! Your server crashed","Would you like to view the logs?"])
3574-
if displog:
3575-
view_server_logs(stdscr,SERVER_DIR)
3576-
stdscr.clear()
3577-
stdscr.refresh()
3578-
else:
3579-
if not _sname in SERVER_INITS:
3580-
truecommand = APPDATA["servers"][chosenserver-1]["script"]
3581-
if WINDOWS:
3582-
truecommand = "cmd /c ("+APPDATA["servers"][chosenserver-1]["script"]+")"
3583-
SERVER_INITS[_sname] = ServerRunWrapper(truecommand)
3584-
SERVER_INITS[_sname].launch()
3585-
cursesplus.messagebox.showinfo(stdscr,["The server has been started.","It will be ready for use in a few minutes"])
3586-
latestlogfile = SERVER_DIR+"/logs/latest.log"
3587-
#pos = 0
3588-
obuffer = ["Getting logs. Please wait...","The log may take some time to appear.","Don't worry, your server is still running."]
3589-
ooffset = 0
3590-
oxoffset = 0
3591-
tick = 0
3592-
#lfsize = os.path.getsize(latestlogfile)
3593-
stdscr.nodelay(1)
3594-
3595-
redraw = True
3596-
while True:
3597-
3598-
tick += 1
3599-
if tick % 30 == 0:
3600-
tick = 0
3601-
#SERVER_INITS[_sname].datastream.seek(0,0)
3602-
#obuffer = SERVER_INITS[_sname].datastream.readlines()
3603-
if os.path.isfile(latestlogfile):
3604-
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(latestlogfile))
3605-
if mtime < SERVER_INITS[_sname].runtime:
3606-
pass
3607-
else:
3608-
3609-
with open(latestlogfile) as f:
3610-
obc = f.readlines()
3611-
if obc != obuffer:
3612-
obuffer = obc
3613-
ooffset = len(obuffer)-my+headeroverhead
3614-
if ooffset < 0:
3615-
ooffset = 0
3616-
redraw = True
3617-
3618-
#Visual part
3619-
mx,my = os.get_terminal_size()
3620-
mx -= 1
3621-
my -= 1
3622-
headeroverhead = 5
3623-
if redraw:
3624-
stdscr.clear()
3625-
cursesplus.utils.fill_line(stdscr,0,cursesplus.set_colour(cursesplus.BLUE,cursesplus.WHITE))
3626-
stdscr.addstr(0,0,f"Live options for {_sname}",cursesplus.set_colour(cursesplus.BLUE,cursesplus.WHITE))
3627-
stdscr.addstr(1,0,"Press B to go back to the options")
3628-
stdscr.addstr(2,0,"Press C to run a command | Press K to kill the server")
3629-
stdscr.addstr(3,0,"Press S to stop the server")
3630-
stdscr.addstr(4,0,cursesplus.constants.THIN_HORIZ_LINE*mx)
3631-
oi = 5
3632-
for line in obuffer[ooffset:]:
3633-
try:
3634-
stdscr.addstr(oi,0,line[oxoffset:oxoffset+mx-1])
3635-
except:
3636-
break
3637-
oi += 1
3638-
3639-
svrstat = SERVER_INITS[_sname]
3640-
if not svrstat.isprocessrunning():
3641-
3642-
stdscr.nodelay(0)
3643-
os.system(";".join(APPDATA["servers"][chosenserver-1]["settings"]["exitcommands"]))
3644-
if svrstat.hascrashed():
3645-
displog = cursesplus.messagebox.askyesno(stdscr,["Oh No! Your server crashed","Would you like to view the logs?"])
3646-
if displog:
3647-
view_server_logs(stdscr,SERVER_DIR)
3648-
else:
3649-
cursesplus.messagebox.showinfo(stdscr,["The server has been stopped safely."])
3650-
del SERVER_INITS[_sname]
3651-
break
3652-
#stdscr.addstr(0,0,f"Y: {ooffset} X: {oxoffset}")
3653-
if redraw:
3654-
stdscr.refresh()
3655-
redraw = False
3656-
ch = stdscr.getch()
3657-
if ch == curses.KEY_UP and ooffset > 0:
3658-
ooffset -= 1
3659-
redraw = True
3660-
elif ch == curses.KEY_DOWN:
3661-
ooffset += 1
3662-
redraw = True
3663-
elif ch == curses.KEY_LEFT and oxoffset > 0:
3664-
oxoffset -= 1
3665-
redraw = True
3666-
elif ch == curses.KEY_RIGHT:
3667-
oxoffset += 1
3668-
redraw = True
3669-
3670-
elif ch == 98:
3671-
break
3672-
elif ch == 99:
3673-
stdscr.nodelay(0)
3674-
svrstat.send(crssinput(stdscr,"Enter a command to run"))
3675-
stdscr.nodelay(1)
3676-
elif ch == 115:
3677-
svrstat.send("stop")
3678-
pass
3679-
elif ch == 107:
3680-
stdscr.nodelay(0)
3681-
if cursesplus.messagebox.askyesno(stdscr,["Are you sure you want to kill the server?","This can corrupt data.","Only do this if you believe the server to be frozen"]):
3682-
svrstat.fullhalt()
3683-
stdscr.nodelay(1)
3684-
3685-
sleep(1/30)
3686-
3687-
stdscr.nodelay(0)
3716+
start_server(stdscr)
36883717
elif w == 2:
36893718
if not os.path.isfile("server.properties"):
36903719
cursesplus.displaymsg(stdscr,["ERROR","server.properties could not be found","Try starting your sever to generate one"])
@@ -5362,6 +5391,33 @@ def main(stdscr):
53625391
except:
53635392
with open(UUIDFILE,"wb+") as f:
53645393
f.write(gzip.compress(json.dumps({}).encode()))
5394+
5395+
#Breakaway point for -m and -s tasks
5396+
_scc = False
5397+
if manageid != 0:
5398+
inc = 0
5399+
for server in APPDATA["servers"]:
5400+
if server["id"] == manageid:
5401+
manage_server(stdscr,server["name"],inc)
5402+
_scc = True
5403+
break
5404+
5405+
inc += 1
5406+
if not _scc:
5407+
cursesplus.messagebox.showerror(stdscr,["Unable to find requested","direct manage ID."])
5408+
5409+
if startid != 0:
5410+
inc = 0
5411+
for server in APPDATA["servers"]:
5412+
if server["id"] == startid:
5413+
os.chdir(server["dir"])
5414+
start_server(stdscr,server["name"],inc,server["dir"])
5415+
_scc = True
5416+
break
5417+
5418+
inc += 1
5419+
if not _scc:
5420+
cursesplus.messagebox.showerror(stdscr,["Unable to find requested","direct start ID."])
53655421

53665422
#send_telemetry()
53675423
if APPDATA["language"] is None:

0 commit comments

Comments
 (0)