Skip to content

Commit 836c7c5

Browse files
committed
1.53
1 parent ef74462 commit 836c7c5

File tree

11 files changed

+541
-297
lines changed

11 files changed

+541
-297
lines changed

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,28 @@ echo "Installation finished with no errors."
6666

6767
## Other Important Things
6868

69-
ATTENTION - If you use an old version of this software, it might ask you for a "product key." This system has been retired, so it may confuse you. Please paste the code `4p6jgtnatqj5svb4` if it asks you for one.
69+
ATTENTION - If you use an old version of this software, it might ask you for a "product key." This system has been retired, so it may confuse you. Please paste the code `4p6jgtnatqj5svb4` if it asks you for one.
70+
71+
## Integrating Third Party Software
72+
73+
If you would like to make your application work with CRSS, here is how to do so
74+
75+
### Server automatic restarts
76+
77+
You can control whether or not CRSS automatically restarts a server by writing a file in the server's root directory named `autorestart`
78+
79+
** Requirements **
80+
- CRSS v1.53 or newer
81+
- User must set Autorestart Source to allow external file
82+
83+
This `autorestart` must contain some certain recognized words, in any case, seperated by a space. Recognized words include:
84+
- `never` - Never automatically restart the server (May not be used with safe/unsafe) *Optional - if neither safe nor unsafe are provided, this is the default behaviour*
85+
- `safe` - Automatically restart the server if it exited safely (may not be used with never)
86+
- `unsafe` - Automatically restart the server if it did not exit safely. (may not be used with never)
87+
- `disposable` - "Consume" this autorestart file so that it may be only read once. (may not be used with persistent) *Optional - if persistent is not provided, this is the default behaviour*
88+
- `persistent` - Keep this file (do not delete it when it is read)
89+
90+
**For example**
91+
92+
`safe persistent` - Autorestart the server if it doesn't crash. This file may be used multiple times.
93+
`safe unsafe` - Autorestart the server all the time, no matter what.

changelog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
- Remove all references to anything monetary
88
- Including ads, product keys, etc
99
- Fix bug where screen spam would occur if API server was down
10+
- Remove showprog setting as it was completely useless
11+
- Add autorestart
12+
- Add autorestarttimeout setting, which defaults to 30 seconds timeout
13+
- This means you have 30s to abort the autorestart after it triggers.
14+
- Autorestart settings are found in advanced config -> startup options -> Autorestart options
1015
1.52.2:
1116
- Add the ability to change the server's java installation
1217
- Fix bugs

doc/build.txt

Lines changed: 0 additions & 15 deletions
This file was deleted.

doc/craftserversetup.epdoc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,6 @@ The most important keys are the arrow keys and enter. These are used to navigate
7979
Message boxes are dismissed with the enter key and navigated around with the left and right arrow keys. Message boxes are in a rectangle and do not take up the full screen.
8080

8181
In most widgets, all of the key-bindings are layed out for you. The only exception to this is the file dialogues. If you need help with keybinds on the file dialog boxes, simply press H to bring up a list.
82-
$Using GumRoad
83-
If you use GumRoad to purchase CraftServerSetup you will recieve a longer product key. Check the section "Product Keys" for more info
84-
$Product Keys:
85-
In the OOBE you will be asked to input a product key. You can get a product key by paying the $2 fee and telling Enderbyte Programs that you send it. You will recieve your product key shortly. Product keys remove advertisements and bypass the 1 server limit. Product keys as of 1.30 are 16 characters long. THey have latters and numbers, but are case insensitive. For crack artists looking to crack this program, good luck! Though the hashed keys are publicly available on pastebin, you still need to reverse engineer. 26 letters + 10 numbers = 36 characters. 36 ^ 16 characters divided by 100 keys in system means that you have to generate 1.8*10^48 hashes before you should stumble on a correct one. Trust me, it is not worth it.
86-
FOR GUMROAD USERS: When asked where you got your key, select "From GumRoad". From there paste in your key.
87-
Old product keys were 8 numbers and incredibly easy to crack. Not anymore...
88-
$Advertisements:
89-
Advertisements are what you recieve if you do not input a product key. In every option menu, there is an advertisement. If you press A, the ad will be opened in your browser. Prior to 0.18.3, you had a 20% chance of encountering an ad while navigating. This was removed because it could be quite annoying
9082
$Starting a new server:
9183
To start a new server, simply select Set up a new server, then Create a new server from the main menu. From there, choose a software. As of 1.30, CraftServerSetup supports 4 softwares: Vanilla, Spigot, Paper, and Purpur. For each software, proceed down the list of documentation pages. However, before you do that, you will be asked for a name. A name MUST NOT have any special characters like / or \ because that will damage the file system. Spaces are OK.
9284
$Preparing Vanilla Software:

src/appdata.py

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import random
33
import json
44
import gzip
5+
import typing
56

67
def compatibilize_appdata(data:dict) -> dict:
78
"""This function ensures that appdata is brought up to the latest version. It is compatible to the beginning."""
@@ -19,7 +20,7 @@ def compatibilize_appdata(data:dict) -> dict:
1920
"transitions":{
2021
"display" : "Show Transitions?",
2122
"type" : "bool",
22-
"value" : True
23+
"value" : False
2324
},
2425
"oldmenu":{
2526
"name" : "oldmenu",
@@ -32,26 +33,19 @@ def compatibilize_appdata(data:dict) -> dict:
3233
#Update data
3334
data["settings"] = {
3435

35-
"transitions":{
36-
"display" : "Show Transitions?",
37-
"type" : "bool",
38-
"value" : data["settings"][1]["value"]
39-
},
40-
"oldmenu":{
41-
"name" : "oldmenu",
42-
"display" : "Use legacy style menus?",
43-
"type" : "bool",
44-
"value" : data["settings"][2]["value"]
45-
}
36+
"transitions":{
37+
"display" : "Show Transitions?",
38+
"type" : "bool",
39+
"value" : data["settings"][1]["value"]
40+
},
41+
"oldmenu":{
42+
"name" : "oldmenu",
43+
"display" : "Use legacy style menus?",
44+
"type" : "bool",
45+
"value" : data["settings"][2]["value"]
46+
}
4647

4748
}
48-
if not "showprog" in data["settings"]:
49-
data["settings"]["showprog"] = {
50-
"name" : "showprog",
51-
"display" : "Show progress bar startup?",
52-
"type" : "bool",
53-
"value":False
54-
}
5549
if not "editor" in data["settings"]:
5650
data["settings"]["editor"] = {
5751
"name" : "editor",
@@ -85,13 +79,21 @@ def compatibilize_appdata(data:dict) -> dict:
8579
if not "settings" in svr:
8680
data["servers"][svri]["settings"] = {}#New empty settings
8781
if data["servers"][svri]["settings"] == {}:
88-
data["servers"][svri]["settings"] = {"launchcommands":[],"exitcommands":[]}
82+
data["servers"][svri]["settings"] = {"launchcommands":[],"exitcommands":[],"restartsource" : 0,"autorestart" : 0,"legacy" : True,"flags":""}#0 - disabled, 1 - file-controlled, 2 - crss-controlled.
8983
if not "legacy" in data["servers"][svri]["settings"]:
9084
data['servers'][svri]["settings"]["legacy"] = True
9185
if not "backupdir" in svr:
9286
data['servers'][svri]["backupdir"] = SERVERS_BACKUP_DIR + os.sep + str(data['servers'][svri]["id"])
9387
if data["servers"][svri]["software"] == 0:
9488
data["servers"][svri]["software"] = 5#v1.48
89+
90+
if not "autorestart" in data["servers"][svri]["settings"]:
91+
data["servers"][svri]["settings"]["autorestart"] = 0
92+
data["servers"][svri]["settings"]["restartsource"] = 0
93+
94+
if not "flags" in data["servers"][svri]["settings"]:
95+
data["servers"][svri]["settings"]["flags"] = ""
96+
9597

9698
#1.49.1
9799
if not "flags" in svr["settings"]:
@@ -134,6 +136,17 @@ def compatibilize_appdata(data:dict) -> dict:
134136
del data["productKey"]
135137
del data["pkd"]
136138

139+
if "showprog" in data["settings"]:
140+
del data["settings"]["showprog"]
141+
142+
if not "autorestarttimeout" in data["settings"]:
143+
data["settings"]["autorestarttimeout"] = {
144+
"name" : "autorestarttimeout",
145+
"display" : "Autorestart timeout in seconds",
146+
"type" : "int",
147+
"value" : 30
148+
}
149+
137150
return data
138151

139152
__DEFAULTAPPDATA__ = {
@@ -158,17 +171,29 @@ def compatibilize_appdata(data:dict) -> dict:
158171
"type" : "bool",
159172
"value" : False
160173
},
161-
"showprog" : {
162-
"name" : "showprog",
163-
"display" : "Show progress bar on startup?",
164-
"type" : "bool",
165-
"value" : False
166-
},
167174
"reswarn" : {
168175
"name" :"reswarn",
169-
"display" : "Give warnings for high-resource operations",
176+
"display" : "Give warnings for high-resource operations?",
170177
"type" : "bool",
171178
"value" : True
179+
},
180+
"autorestarttimeout" : {
181+
"name" : "autorestarttimeout",
182+
"display" : "Autorestart timeout in seconds",
183+
"type" : "int",
184+
"value" : 30
185+
},
186+
"editor": {
187+
"name": "editor",
188+
"display": "Text Editor",
189+
"type": "str",
190+
"value": "/usr/bin/editor %s"
191+
},
192+
"autoupdate": {
193+
"name": "autoupdate",
194+
"display": "Update automatically",
195+
"type": "bool",
196+
"value": True
172197
}
173198
},
174199
"idata" : {
@@ -185,6 +210,7 @@ def compatibilize_appdata(data:dict) -> dict:
185210
UUID_INDEX:dict = {}
186211

187212
def setup_appdata():
213+
"""Load appdata from the file and populate the appdata.APPDATA variable."""
188214
global APPDATA
189215
global APPDATAFILE
190216
global UUIDFILE
@@ -217,12 +243,22 @@ def setup_appdata():
217243
with open(UUIDFILE,"wb+") as f:
218244
f.write(gzip.compress(json.dumps({}).encode()))
219245

246+
def self_compatibilize():
247+
"""Execute a compatibilization and repair routine on appdata.APPDATA"""
248+
global APPDATA
249+
250+
APPDATA = compatibilize_appdata(APPDATA)
251+
220252
def updateappdata():
253+
"""Write in-memory appdata and UUID cache to the disk"""
221254

222255
global APPDATAFILE
223256
global UUID_INDEX
224257
global UUIDFILE
225258
with open(APPDATAFILE,"w+") as f:
226259
f.write(json.dumps(APPDATA,indent=2))
227260
with open(UUIDFILE,"wb+") as f:
228-
f.write(gzip.compress(json.dumps(UUID_INDEX).encode()))#Write compressed file
261+
f.write(gzip.compress(json.dumps(UUID_INDEX).encode()))#Write compressed file
262+
263+
def get_setting_value(key:str) -> typing.Any:
264+
return APPDATA["settings"][key]["value"]

src/arguments.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@ def get_file_to_import() -> str:
7070
return _file_to_import
7171

7272
def should_run_import_mode() -> bool:
73-
return _file_to_import != ""
73+
return _file_to_import != "" and os.path.isfile(_file_to_import)

src/autorestart.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""A module to control the automatic server restart feature for v1.53"""
2+
import enum
3+
import os
4+
import cursesplus
5+
import uicomponents
6+
7+
class AutoRestartSourceOptions(enum.Enum):
8+
NOAUTORESTART = 0#Auto restart will never occur, no matterwhat
9+
EXTERNALFILE = 1#CRSS will search for the SERVERDIR/autorestart file and attempt to follow it. If it cannot find it, it will execute the insturction in the CRSS options
10+
CRSSONLY = 2#CRSS will only honour the setting in the internal configuration (CRSS options)
11+
12+
class AutoRestartOptions(enum.Enum):
13+
NORESTART = 0#No auto restart, no matter what
14+
SAFEEXIT = 1#Auto restart only if exit code is 0 (signifying a safe shutdown)
15+
ALWAYS = 2 #Auto restart no matter what
16+
17+
class ExternalAutoRestartProfile:
18+
"""Store a friendly representation of the auto restart profile stored in a file"""
19+
def __init__(self,file_data:str):
20+
self.restart_always:bool = False
21+
self.restart_if_safe:bool = False
22+
self.is_persistent: bool = False
23+
24+
for word in file_data.lower().strip().split():
25+
if word == "safe":
26+
self.restart_if_safe = True
27+
elif word == "unsafe":
28+
self.restart_always = True
29+
elif word == "persistent":
30+
self.is_persistent = True
31+
elif word == "disposable":
32+
self.is_persistent = False
33+
elif word == "never":
34+
self.restart_always = False
35+
self.restart_if_safe = False
36+
37+
38+
def does_server_have_autorestart_file(serverdir:str) -> bool:
39+
"""Does the server in serverdir have an autorestart file?"""
40+
return os.path.isfile(serverdir + os.sep + "autorestart")
41+
42+
def get_recommended_action(server_configuration:dict,clear_nonpersistent=True) -> AutoRestartOptions:
43+
"""Using all of the configurations, suggest the action to restart or not"""
44+
serverdir:str = server_configuration["dir"]
45+
startsource = server_configuration["settings"]["restartsource"]
46+
47+
if startsource == AutoRestartSourceOptions.NOAUTORESTART:
48+
return AutoRestartOptions.NORESTART
49+
50+
elif startsource == AutoRestartSourceOptions.CRSSONLY or not does_server_have_autorestart_file(serverdir):#Disregard foreign if startsource is set to or if there is no autorestart file
51+
return AutoRestartOptions(server_configuration["settings"]["autorestart"])
52+
53+
else:
54+
with open(serverdir+os.sep+"autorestart") as f:
55+
rd = f.read()
56+
57+
ob = ExternalAutoRestartProfile(rd)
58+
if not ob.is_persistent and clear_nonpersistent:
59+
os.remove(serverdir+os.sep+"autorestart")
60+
61+
if ob.restart_always:
62+
return AutoRestartOptions.ALWAYS
63+
64+
if ob.restart_if_safe:
65+
return AutoRestartOptions.SAFEEXIT
66+
67+
return AutoRestartOptions.NORESTART
68+
69+
def autorestart_settings(stdscr,serverdata:dict) -> dict:
70+
"""UI portion for configuring autorestart"""
71+
while True:
72+
wtd = uicomponents.menu(stdscr,["Back","Autorestart Mode","Autorestart Source"])
73+
if wtd == 0:
74+
return serverdata
75+
elif wtd == 1:
76+
serverdata["settings"]["autorestart"] = uicomponents.menu(stdscr,["Do not automatically restart","Automatically restart only if the server has not crashed","Always automatically restart the server"],"Select the CRSS-based autorestart mode to use","If you set the source to be external, this setting will be ignored.")
77+
elif wtd == 2:
78+
serverdata["settings"]["restartsource"] = uicomponents.menu(stdscr,["Do not automatically restart","Pull settings from $DIR/autorestart file, then CRSS.","Pull settings from CRSS only"],"Choose a data source for autorestart")

0 commit comments

Comments
 (0)