serverwatcher 5.7__tar.gz → 5.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {serverwatcher-5.7/src/serverwatcher.egg-info → serverwatcher-5.8}/PKG-INFO +1 -1
- {serverwatcher-5.7 → serverwatcher-5.8}/pyproject.toml +1 -1
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/configclasses/config.py +5 -5
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/configclasses/messages.py +23 -26
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/configclasses/watcher.py +4 -2
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/defaultconfigs/config.yaml +1 -2
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/defaultconfigs/messages.yaml +4 -22
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/defaultconfigs/watcher.yaml +2 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/validator.py +4 -18
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/watcher.py +49 -62
- {serverwatcher-5.7 → serverwatcher-5.8/src/serverwatcher.egg-info}/PKG-INFO +1 -1
- {serverwatcher-5.7 → serverwatcher-5.8}/LICENSE +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/README.md +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/setup.cfg +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/__init__.py +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher/configclasses/__init__.py +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher.egg-info/SOURCES.txt +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher.egg-info/dependency_links.txt +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher.egg-info/requires.txt +0 -0
- {serverwatcher-5.7 → serverwatcher-5.8}/src/serverwatcher.egg-info/top_level.txt +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import field
|
|
2
|
+
from hungerlib import datamap, datamap_api
|
|
2
3
|
|
|
3
4
|
def yaml_key(path: str, default=None):
|
|
4
5
|
return field(default=default, metadata={"yaml_key": path})
|
|
5
6
|
|
|
6
|
-
@
|
|
7
|
+
@datamap(syntax=datamap_api.braces)
|
|
7
8
|
class GlobalConfig:
|
|
8
|
-
|
|
9
|
+
timezone: str = yaml_key("timezone")
|
|
9
10
|
|
|
10
11
|
panel_name: str = yaml_key("panel.name")
|
|
11
12
|
panel_url: str = yaml_key("panel.url")
|
|
@@ -25,7 +26,6 @@ class GlobalConfig:
|
|
|
25
26
|
enable_logging: bool = yaml_key("logger.enabled")
|
|
26
27
|
logger_name: str = yaml_key("logger.name")
|
|
27
28
|
log_path: str = yaml_key("logger.log_path")
|
|
28
|
-
timezone: str = yaml_key("logger.timezone")
|
|
29
29
|
|
|
30
30
|
console_backspaces: int = yaml_key("terminal.backspaces")
|
|
31
|
-
clear_terminal: bool = yaml_key("terminal.enable_clearing")
|
|
31
|
+
clear_terminal: bool = yaml_key("terminal.enable_clearing")
|
|
@@ -1,36 +1,35 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import field
|
|
2
|
+
from hungerlib import datamap, datamap_api
|
|
2
3
|
|
|
3
4
|
def yaml_key(path: str, default=None):
|
|
4
5
|
return field(default=default, metadata={"yaml_key": path})
|
|
5
6
|
|
|
6
|
-
@
|
|
7
|
+
@datamap(syntax=datamap_api.braces)
|
|
7
8
|
class MessagesConfig:
|
|
8
|
-
prefix: str = yaml_key("prefix")
|
|
9
|
-
broadcast_restart_at: str = yaml_key("broadcast_restart_at")
|
|
9
|
+
prefix: str = yaml_key("prefix", "<aqua>[Server Watcher]")
|
|
10
10
|
bullet: str = yaml_key("bullet")
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
minute_120: str = yaml_key("broadcast_minutes.120")
|
|
14
|
-
minute_60: str = yaml_key("broadcast_minutes.60")
|
|
15
|
-
minute_45: str = yaml_key("broadcast_minutes.45")
|
|
16
|
-
minute_30: str = yaml_key("broadcast_minutes.30")
|
|
17
|
-
minute_15: str = yaml_key("broadcast_minutes.15")
|
|
18
|
-
minute_5: str = yaml_key("broadcast_minutes.5")
|
|
19
|
-
minute_1: str = yaml_key("broadcast_minutes.1")
|
|
12
|
+
broadcast_restart_at: str = yaml_key("broadcast_restart_at")
|
|
20
13
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
minute_120: str = yaml_key("broadcast_minutes.120", "{prefix} Restart in 2 hours!")
|
|
15
|
+
minute_60: str = yaml_key("broadcast_minutes.60", "{prefix} Restart in 1 hour!")
|
|
16
|
+
minute_45: str = yaml_key("broadcast_minutes.45", "{prefix} Restart in 45 minutes!")
|
|
17
|
+
minute_30: str = yaml_key("broadcast_minutes.30", "{prefix} Restart in 30 minutes!")
|
|
18
|
+
minute_15: str = yaml_key("broadcast_minutes.15", "{prefix} Restart in 15 minutes!")
|
|
19
|
+
minute_5: str = yaml_key("broadcast_minutes.5", "{prefix} Restart in 5 minutes!")
|
|
20
|
+
minute_1: str = yaml_key("broadcast_minutes.1", "{prefix} Restart in 1 minute!")
|
|
21
|
+
|
|
22
|
+
second_10: str = yaml_key("broadcast_seconds.10", "{prefix} Restart in 10 seconds!")
|
|
23
|
+
second_9: str = yaml_key("broadcast_seconds.9", "{prefix} Restart in 9 seconds!")
|
|
24
|
+
second_8: str = yaml_key("broadcast_seconds.8", "{prefix} Restart in 8 seconds!")
|
|
25
|
+
second_7: str = yaml_key("broadcast_seconds.7", "{prefix} Restart in 7 seconds!")
|
|
26
|
+
second_6: str = yaml_key("broadcast_seconds.6", "{prefix} Restart in 6 seconds!")
|
|
27
|
+
second_5: str = yaml_key("broadcast_seconds.5", "{prefix} Restart in 5 seconds!")
|
|
28
|
+
second_4: str = yaml_key("broadcast_seconds.4", "{prefix} Restart in 4 seconds!")
|
|
29
|
+
second_3: str = yaml_key("broadcast_seconds.3", "{prefix} Restart in 3 seconds!")
|
|
30
|
+
second_2: str = yaml_key("broadcast_seconds.2", "{prefix} Restart in 2 seconds!")
|
|
31
|
+
second_1: str = yaml_key("broadcast_seconds.1", "{prefix} Restart in 1 second!")
|
|
32
32
|
|
|
33
|
-
# logging
|
|
34
33
|
startup: str = yaml_key("logging.startup")
|
|
35
34
|
status_check: str = yaml_key("logging.status_check")
|
|
36
35
|
validation_fail: str = yaml_key("logging.validation_fail")
|
|
@@ -42,7 +41,6 @@ class MessagesConfig:
|
|
|
42
41
|
gap_low: str = yaml_key("logging.gap_low")
|
|
43
42
|
gap_high: str = yaml_key("logging.gap_high")
|
|
44
43
|
|
|
45
|
-
# reasons
|
|
46
44
|
pro_restart_splash: str = yaml_key("reasons.pro_splash")
|
|
47
45
|
anti_restart_splash: str = yaml_key("reasons.anti_splash")
|
|
48
46
|
|
|
@@ -57,7 +55,6 @@ class MessagesConfig:
|
|
|
57
55
|
pro_restart_number: str = yaml_key("reasons.pro_restart_number")
|
|
58
56
|
anti_restart_number: str = yaml_key("reasons.anti_restart_number")
|
|
59
57
|
|
|
60
|
-
# restarts
|
|
61
58
|
restart_action_sent: str = yaml_key("restarts.restart_action_sent")
|
|
62
59
|
server_back_online: str = yaml_key("restarts.back_online")
|
|
63
60
|
server_back_online_broadcast: str = yaml_key("restarts.back_online_broadcast")
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import field
|
|
2
|
+
from hungerlib import datamap, datamap_api
|
|
2
3
|
|
|
3
4
|
def yaml_key(path: str, default=None):
|
|
4
5
|
return field(default=default, metadata={"yaml_key": path})
|
|
5
6
|
|
|
6
|
-
@
|
|
7
|
+
@datamap(syntax=datamap_api.braces)
|
|
7
8
|
class WatcherConfig:
|
|
9
|
+
watch_interval: int = yaml_key("watch_interval")
|
|
8
10
|
schedule_control: bool = yaml_key("schedule_control.enabled")
|
|
9
11
|
restart_soon_id: int = yaml_key("schedule_control.restart_soon_id")
|
|
10
12
|
|
|
@@ -1,28 +1,10 @@
|
|
|
1
1
|
prefix: '<aqua>[Server Watcher]'
|
|
2
|
-
|
|
3
|
-
broadcast_restart_at: '{prefix} The server will restart at {time} CDT.'
|
|
4
2
|
bullet: '-'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
'120': '{prefix} Restart in 2 hours!'
|
|
8
|
-
'60': '{prefix} Restart in 1 hour!'
|
|
9
|
-
'45': '{prefix} Restart in 45 minutes!'
|
|
10
|
-
'30': '{prefix} Restart in 30 minutes!'
|
|
11
|
-
'15': '{prefix} Restart in 15 minutes!'
|
|
12
|
-
'5': '{prefix} Restart in 5 minutes!'
|
|
13
|
-
'1': '{prefix} Restart in 1 minute!'
|
|
4
|
+
broadcast_restart_at: '{prefix} The server will restart at {time} CDT.'
|
|
14
5
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'9': '{prefix} Restart in 9 seconds!'
|
|
18
|
-
'8': '{prefix} Restart in 8 seconds!'
|
|
19
|
-
'7': '{prefix} Restart in 7 seconds!'
|
|
20
|
-
'6': '{prefix} Restart in 6 seconds!'
|
|
21
|
-
'5': '{prefix} Restart in 5 seconds!'
|
|
22
|
-
'4': '{prefix} Restart in 4 seconds!'
|
|
23
|
-
'3': '{prefix} Restart in 3 seconds!'
|
|
24
|
-
'2': '{prefix} Restart in 2 seconds!'
|
|
25
|
-
'1': '{prefix} Restart in 1 second!'
|
|
6
|
+
broadcast_minutes: {}
|
|
7
|
+
broadcast_seconds: {}
|
|
26
8
|
|
|
27
9
|
logging:
|
|
28
10
|
startup: 'ServerWatcher is running!'
|
|
@@ -46,7 +28,7 @@ reasons:
|
|
|
46
28
|
uptime: 'Uptime {uptime} exceeds {threshold}h'
|
|
47
29
|
tps: 'TPS {tps} is lower than {threshold}'
|
|
48
30
|
low_uptime: 'Uptime {uptime} is shorter than 30m'
|
|
49
|
-
players: 'There {verb} {count} {plural} online'
|
|
31
|
+
players: 'There {verb} {count} {plural} online' # produces: "There are 2 players online" or "There is 1 player online"
|
|
50
32
|
|
|
51
33
|
pro_restart_number: 'Pro-restart: '
|
|
52
34
|
anti_restart_number: 'Anti-restart:'
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from dataclasses import fields
|
|
3
|
-
|
|
4
|
-
from hungerlib.addons import loadConfig, clearTerminal
|
|
3
|
+
from hungerlib import utils, loadConfig
|
|
5
4
|
|
|
6
5
|
from serverwatcher.configclasses.config import GlobalConfig
|
|
7
6
|
from serverwatcher.configclasses.messages import MessagesConfig
|
|
8
7
|
from serverwatcher.configclasses.watcher import WatcherConfig
|
|
9
8
|
|
|
10
|
-
clearTerminal()
|
|
9
|
+
utils.clearTerminal()
|
|
11
10
|
|
|
12
11
|
def deep_get_attr(obj, dotted):
|
|
13
12
|
parts = dotted.split(".")
|
|
@@ -18,22 +17,18 @@ def deep_get_attr(obj, dotted):
|
|
|
18
17
|
cur = getattr(cur, p)
|
|
19
18
|
return cur
|
|
20
19
|
|
|
21
|
-
|
|
22
20
|
def validate_type(name, value, expected_type, errors):
|
|
23
21
|
if not isinstance(value, expected_type):
|
|
24
22
|
errors.append(f"{name}: expected {expected_type.__name__}, got {type(value).__name__}")
|
|
25
23
|
|
|
26
|
-
|
|
27
24
|
def validate_positive(name, value, errors):
|
|
28
25
|
if isinstance(value, (int, float)) and value < 0:
|
|
29
26
|
errors.append(f"{name}: must be >= 0 (got {value})")
|
|
30
27
|
|
|
31
|
-
|
|
32
28
|
def validate_nonempty(name, value, errors):
|
|
33
29
|
if isinstance(value, str) and value.strip() == "":
|
|
34
30
|
errors.append(f"{name}: cannot be empty")
|
|
35
31
|
|
|
36
|
-
|
|
37
32
|
def validate_dataclass(config_obj, schema, errors):
|
|
38
33
|
for f in fields(schema):
|
|
39
34
|
name = f.name
|
|
@@ -48,18 +43,13 @@ def validate_dataclass(config_obj, schema, errors):
|
|
|
48
43
|
if expected_type in (int, float):
|
|
49
44
|
validate_positive(name, value, errors)
|
|
50
45
|
|
|
51
|
-
|
|
52
46
|
def validate_global_config(config, errors):
|
|
53
|
-
if config.watch_interval < 1:
|
|
54
|
-
errors.append(f"watch_interval: must be >= 1 (got {config.watch_interval})")
|
|
55
|
-
|
|
56
47
|
if config.server_port <= 0 or config.server_port > 65535:
|
|
57
48
|
errors.append(f"server_port: must be 1–65535 (got {config.server_port})")
|
|
58
49
|
|
|
59
50
|
if config.rcon_port <= 0 or config.rcon_port > 65535:
|
|
60
51
|
errors.append(f"rcon_port: must be 1–65535 (got {config.rcon_port})")
|
|
61
52
|
|
|
62
|
-
|
|
63
53
|
def validate_watcher_config(watcherconfig, errors):
|
|
64
54
|
if watcherconfig.restart_wait_seconds < 1:
|
|
65
55
|
errors.append(f"restart_wait_seconds: must be >= 1 (got {watcherconfig.restart_wait_seconds})")
|
|
@@ -73,13 +63,12 @@ def validate_watcher_config(watcherconfig, errors):
|
|
|
73
63
|
if watcherconfig.threshold_tps <= 0 or watcherconfig.threshold_tps > 20:
|
|
74
64
|
errors.append(f"threshold_tps: must be 1–20 (got {watcherconfig.threshold_tps})")
|
|
75
65
|
|
|
76
|
-
|
|
77
66
|
def validate_messages_config(messages, errors):
|
|
78
|
-
for
|
|
67
|
+
for f in fields(MessagesConfig):
|
|
68
|
+
value = getattr(messages, f.name)
|
|
79
69
|
if isinstance(value, str) and "{prefix}" not in value:
|
|
80
70
|
pass
|
|
81
71
|
|
|
82
|
-
|
|
83
72
|
def ensure_no_global_defaults(config, defaults):
|
|
84
73
|
if config.panel_url == "https://example.com":
|
|
85
74
|
defaults.append('panel_url')
|
|
@@ -99,12 +88,10 @@ def ensure_no_global_defaults(config, defaults):
|
|
|
99
88
|
if config.rcon_password == 'password':
|
|
100
89
|
defaults.append('rcon_password')
|
|
101
90
|
|
|
102
|
-
|
|
103
91
|
def ensure_no_watcher_defaults(watcherconfig, defaults):
|
|
104
92
|
if watcherconfig.schedule_control and watcherconfig.restart_soon_id == 0:
|
|
105
93
|
defaults.append('restart_soon_id')
|
|
106
94
|
|
|
107
|
-
|
|
108
95
|
def validate_all():
|
|
109
96
|
errors = []
|
|
110
97
|
defaults = []
|
|
@@ -140,6 +127,5 @@ def validate_all():
|
|
|
140
127
|
|
|
141
128
|
print("✅ All configs are valid.")
|
|
142
129
|
|
|
143
|
-
|
|
144
130
|
if __name__ == "__main__":
|
|
145
131
|
validate_all()
|
|
@@ -1,43 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import time
|
|
3
|
-
import re
|
|
4
3
|
from zoneinfo import ZoneInfo
|
|
5
4
|
|
|
6
|
-
from hungerlib import
|
|
7
|
-
from hungerlib.servers import MinecraftServer, GenericServer
|
|
8
|
-
from hungerlib.addons import (
|
|
9
|
-
clearTerminal,
|
|
10
|
-
Snapshot,
|
|
11
|
-
snapSchedule,
|
|
12
|
-
waitForOnline,
|
|
13
|
-
validateAll,
|
|
14
|
-
runCountdownEvents,
|
|
15
|
-
loadConfig,
|
|
16
|
-
)
|
|
5
|
+
from hungerlib import servers, MessageRouter, loadConfig, utils, datamap_api, mapit
|
|
17
6
|
|
|
18
7
|
from serverwatcher.configclasses.config import GlobalConfig
|
|
19
8
|
from serverwatcher.configclasses.messages import MessagesConfig
|
|
20
9
|
from serverwatcher.configclasses.watcher import WatcherConfig
|
|
21
|
-
|
|
22
10
|
from serverwatcher.validator import validate_all
|
|
23
11
|
|
|
24
12
|
validate_all()
|
|
25
13
|
|
|
26
|
-
_T_EXPR = re.compile(r"{([^{}]+)}")
|
|
27
|
-
|
|
28
|
-
def t_eval(template: str, /, **ctx):
|
|
29
|
-
def repl(match):
|
|
30
|
-
expr = match.group(1).strip()
|
|
31
|
-
try:
|
|
32
|
-
return str(eval(expr, {}, ctx))
|
|
33
|
-
except Exception as e:
|
|
34
|
-
return f"<err:{e}>"
|
|
35
|
-
|
|
36
|
-
return _T_EXPR.sub(repl, template)
|
|
37
14
|
|
|
38
15
|
class ServerWatcher:
|
|
39
16
|
def __init__(self):
|
|
40
|
-
|
|
41
17
|
self.config = loadConfig(
|
|
42
18
|
"config/config.yaml",
|
|
43
19
|
"/defaultconfigs/config.yaml",
|
|
@@ -56,19 +32,26 @@ class ServerWatcher:
|
|
|
56
32
|
WatcherConfig
|
|
57
33
|
)
|
|
58
34
|
|
|
59
|
-
|
|
35
|
+
datamap_api.set_default_maps(
|
|
36
|
+
utils.ASCII_COLOR_MAP,
|
|
37
|
+
self.config,
|
|
38
|
+
self.messages,
|
|
39
|
+
self.watcherconfig
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
self.panel = servers.Panel(
|
|
60
43
|
name=self.config.panel_name,
|
|
61
44
|
url=self.config.panel_url,
|
|
62
45
|
api_key=self.config.panel_api_key,
|
|
63
46
|
)
|
|
64
47
|
|
|
65
|
-
self.origin =
|
|
48
|
+
self.origin = servers.Generic(
|
|
66
49
|
name="Origin",
|
|
67
50
|
panel=self.panel,
|
|
68
51
|
server_id=self.config.origin_server_id
|
|
69
52
|
)
|
|
70
53
|
|
|
71
|
-
self.server =
|
|
54
|
+
self.server = servers.Minecraft(
|
|
72
55
|
name=self.config.server_name,
|
|
73
56
|
panel=self.panel,
|
|
74
57
|
server_id=self.config.server_id,
|
|
@@ -79,27 +62,31 @@ class ServerWatcher:
|
|
|
79
62
|
tpsCommand=self.config.tps_command,
|
|
80
63
|
)
|
|
81
64
|
|
|
82
|
-
logger_name = self.config.logger_name.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
self.log = HungerLogger(
|
|
87
|
-
name=self.config.logger_name,
|
|
65
|
+
logger_name = mapit(self.config.logger_name, server_name=self.config.server_name)
|
|
66
|
+
|
|
67
|
+
self.router = MessageRouter(
|
|
68
|
+
name=logger_name,
|
|
88
69
|
server=self.server,
|
|
89
70
|
log_path=self.config.log_path,
|
|
71
|
+
formatter=self._fmt,
|
|
90
72
|
console_backspaces=self.config.console_backspaces,
|
|
91
73
|
)
|
|
92
74
|
|
|
93
75
|
self.tz = ZoneInfo(self.config.timezone)
|
|
94
76
|
|
|
95
|
-
def
|
|
96
|
-
return
|
|
77
|
+
def _fmt(self, template: str, **ctx):
|
|
78
|
+
return mapit(template, **ctx)
|
|
97
79
|
|
|
98
|
-
def say(self, template, level="info", **
|
|
80
|
+
def say(self, template, level="info", **ctx):
|
|
99
81
|
if not template:
|
|
100
82
|
return
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
msg = mapit(template, **ctx)
|
|
84
|
+
self.router.say(
|
|
85
|
+
msg,
|
|
86
|
+
level=level,
|
|
87
|
+
log=self.config.enable_logging,
|
|
88
|
+
**ctx
|
|
89
|
+
)
|
|
103
90
|
|
|
104
91
|
def shutdown(self):
|
|
105
92
|
self.say(self.messages.shutdown)
|
|
@@ -108,12 +95,13 @@ class ServerWatcher:
|
|
|
108
95
|
def restart_and_wait(self):
|
|
109
96
|
if self.watcherconfig.schedule_control:
|
|
110
97
|
self.origin.disableSchedule(self.watcherconfig.restart_soon_id)
|
|
98
|
+
|
|
111
99
|
self.server.restart()
|
|
112
100
|
self.say(self.messages.restart_action_sent)
|
|
113
101
|
time.sleep(self.watcherconfig.restart_wait_seconds)
|
|
114
102
|
|
|
115
103
|
self.say(self.messages.status_check, level="warn")
|
|
116
|
-
alive = waitForOnline(
|
|
104
|
+
alive = utils.waitForOnline(
|
|
117
105
|
self.server,
|
|
118
106
|
timeout=self.watcherconfig.restart_timeout,
|
|
119
107
|
interval=self.watcherconfig.restart_online_interval,
|
|
@@ -121,7 +109,7 @@ class ServerWatcher:
|
|
|
121
109
|
|
|
122
110
|
if alive:
|
|
123
111
|
self.say(self.messages.server_back_online)
|
|
124
|
-
self.say(self.messages.server_back_online_broadcast)
|
|
112
|
+
self.say(self.messages.server_back_online_broadcast, broadcast=True)
|
|
125
113
|
else:
|
|
126
114
|
self.say(self.messages.server_failed_restart, level="error")
|
|
127
115
|
|
|
@@ -132,12 +120,12 @@ class ServerWatcher:
|
|
|
132
120
|
local_time = scheduled.astimezone(self.tz)
|
|
133
121
|
time_str = local_time.strftime("%I:%M %p")
|
|
134
122
|
|
|
135
|
-
self.
|
|
123
|
+
self.router.broadcast(mapit(self.messages.broadcast_restart_at, time=time_str))
|
|
136
124
|
|
|
137
125
|
minute_callbacks = {
|
|
138
126
|
int(k.split("_")[1]): (
|
|
139
|
-
lambda msg=
|
|
140
|
-
self.
|
|
127
|
+
lambda msg=mapit(getattr(self.messages, k)):
|
|
128
|
+
self.router.broadcast(msg)
|
|
141
129
|
)
|
|
142
130
|
for k in vars(self.messages)
|
|
143
131
|
if k.startswith("minute_")
|
|
@@ -145,8 +133,8 @@ class ServerWatcher:
|
|
|
145
133
|
|
|
146
134
|
second_callbacks = {
|
|
147
135
|
int(k.split("_")[1]): (
|
|
148
|
-
lambda msg=
|
|
149
|
-
self.
|
|
136
|
+
lambda msg=mapit(getattr(self.messages, k)):
|
|
137
|
+
self.router.broadcast(msg)
|
|
150
138
|
)
|
|
151
139
|
for k in vars(self.messages)
|
|
152
140
|
if k.startswith("second_")
|
|
@@ -161,12 +149,12 @@ class ServerWatcher:
|
|
|
161
149
|
def evaluate(self):
|
|
162
150
|
self.say(self.messages.startup)
|
|
163
151
|
|
|
164
|
-
if not validateAll(self.panel, self.server):
|
|
152
|
+
if not utils.validateAll(self.panel, self.server):
|
|
165
153
|
self.say(self.messages.validation_fail, level="error")
|
|
166
154
|
self.shutdown()
|
|
167
155
|
|
|
168
156
|
self.server.refresh()
|
|
169
|
-
snap = Snapshot(self.server, 2, True)
|
|
157
|
+
snap = utils.Snapshot(self.server, 2, True)
|
|
170
158
|
|
|
171
159
|
pro = 0
|
|
172
160
|
anti = 0
|
|
@@ -178,46 +166,45 @@ class ServerWatcher:
|
|
|
178
166
|
pro += self.watcherconfig.weight_restart_soon
|
|
179
167
|
|
|
180
168
|
if snap.ram >= self.watcherconfig.threshold_ram:
|
|
181
|
-
restart_reasons.append(
|
|
169
|
+
restart_reasons.append(mapit(self.messages.reason_ram, ram=snap.ram, threshold=self.watcherconfig.threshold_ram))
|
|
182
170
|
pro += int(round(snap.ram, 0) - (self.watcherconfig.threshold_ram - 1))
|
|
183
171
|
|
|
184
172
|
if snap.cpu >= self.watcherconfig.threshold_cpu:
|
|
185
|
-
restart_reasons.append(
|
|
173
|
+
restart_reasons.append(mapit(self.messages.reason_cpu, cpu=snap.cpu, threshold=self.watcherconfig.threshold_cpu))
|
|
186
174
|
pro += self.watcherconfig.weight_cpu
|
|
187
175
|
|
|
188
176
|
if snap.uptime // 3600 >= self.watcherconfig.threshold_uptime:
|
|
189
177
|
restart_reasons.append(
|
|
190
|
-
|
|
191
|
-
threshold=self.watcherconfig.threshold_uptime)
|
|
178
|
+
mapit(self.messages.reason_uptime, uptime=snap.uptime_formatted, threshold=self.watcherconfig.threshold_uptime)
|
|
192
179
|
)
|
|
193
180
|
pro += self.watcherconfig.weight_uptime
|
|
194
181
|
|
|
195
182
|
if (snap.tps if snap.tps is not None else 20) <= self.watcherconfig.threshold_tps:
|
|
196
|
-
restart_reasons.append(
|
|
183
|
+
restart_reasons.append(mapit(self.messages.reason_tps, tps=snap.tps, threshold=self.watcherconfig.threshold_tps))
|
|
197
184
|
pro += self.watcherconfig.weight_tps
|
|
198
185
|
|
|
199
186
|
if snap.uptime // 60 < 30:
|
|
200
|
-
no_restart_reasons.append(
|
|
187
|
+
no_restart_reasons.append(mapit(self.messages.reason_low_uptime, uptime=snap.uptime_formatted))
|
|
201
188
|
anti += self.watcherconfig.weight_low_uptime
|
|
202
189
|
|
|
203
190
|
if snap.players > 0:
|
|
204
191
|
verb = "are" if snap.players != 1 else "is"
|
|
205
192
|
plural = "players" if snap.players != 1 else "player"
|
|
206
|
-
no_restart_reasons.append(
|
|
193
|
+
no_restart_reasons.append(mapit(self.messages.reason_players, verb=verb, count=snap.players, plural=plural))
|
|
207
194
|
anti += snap.players * self.watcherconfig.weight_per_player
|
|
208
195
|
|
|
209
196
|
if restart_reasons:
|
|
210
197
|
self.say(self.messages.pro_restart_splash, level="warn")
|
|
211
198
|
for r in restart_reasons:
|
|
212
|
-
self.
|
|
199
|
+
self.say(f"{self.messages.bullet} {r}", level="warn")
|
|
213
200
|
|
|
214
201
|
if no_restart_reasons:
|
|
215
202
|
self.say(self.messages.anti_restart_splash, level="warn")
|
|
216
203
|
for r in no_restart_reasons:
|
|
217
|
-
self.
|
|
204
|
+
self.say(f"{self.messages.bullet} {r}", level="warn")
|
|
218
205
|
|
|
219
|
-
self.
|
|
220
|
-
self.
|
|
206
|
+
self.say(f"{self.messages.pro_restart_number} {pro}", level="warn")
|
|
207
|
+
self.say(f"{self.messages.anti_restart_number} {anti}", level="warn")
|
|
221
208
|
|
|
222
209
|
gap = abs(pro - anti)
|
|
223
210
|
|
|
@@ -243,9 +230,9 @@ class ServerWatcher:
|
|
|
243
230
|
|
|
244
231
|
def run(self):
|
|
245
232
|
if self.config.clear_terminal:
|
|
246
|
-
clearTerminal()
|
|
233
|
+
utils.clearTerminal()
|
|
247
234
|
while True:
|
|
248
235
|
if self.config.clear_terminal:
|
|
249
|
-
clearTerminal()
|
|
236
|
+
utils.clearTerminal()
|
|
250
237
|
self.evaluate()
|
|
251
|
-
time.sleep(self.
|
|
238
|
+
time.sleep(self.watcherconfig.watch_interval)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|