serverwatcher 5.8.dev35__tar.gz → 5.9__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.
Files changed (24) hide show
  1. {serverwatcher-5.8.dev35/src/serverwatcher.egg-info → serverwatcher-5.9}/PKG-INFO +1 -1
  2. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/pyproject.toml +1 -1
  3. serverwatcher-5.9/src/serverwatcher/__main__.py +24 -0
  4. serverwatcher-5.9/src/serverwatcher/configclasses/config.py +28 -0
  5. serverwatcher-5.9/src/serverwatcher/configclasses/messages.py +56 -0
  6. serverwatcher-5.9/src/serverwatcher/configclasses/watcher.py +28 -0
  7. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/defaultconfigs/config.yaml +5 -3
  8. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/defaultconfigs/messages.yaml +0 -1
  9. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/validator.py +2 -2
  10. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/watcher.py +24 -15
  11. {serverwatcher-5.8.dev35 → serverwatcher-5.9/src/serverwatcher.egg-info}/PKG-INFO +1 -1
  12. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher.egg-info/SOURCES.txt +1 -0
  13. serverwatcher-5.8.dev35/src/serverwatcher/configclasses/config.py +0 -31
  14. serverwatcher-5.8.dev35/src/serverwatcher/configclasses/messages.py +0 -61
  15. serverwatcher-5.8.dev35/src/serverwatcher/configclasses/watcher.py +0 -32
  16. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/LICENSE +0 -0
  17. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/README.md +0 -0
  18. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/setup.cfg +0 -0
  19. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/__init__.py +0 -0
  20. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/configclasses/__init__.py +0 -0
  21. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher/defaultconfigs/watcher.yaml +0 -0
  22. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher.egg-info/dependency_links.txt +0 -0
  23. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher.egg-info/requires.txt +0 -0
  24. {serverwatcher-5.8.dev35 → serverwatcher-5.9}/src/serverwatcher.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: serverwatcher
3
- Version: 5.8.dev35
3
+ Version: 5.9
4
4
  Summary: A HungerLib-powered Minecraft server automation engine.
5
5
  Author: iFamished
6
6
  License: GPL-3.0
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "serverwatcher"
10
- version = "5.8.dev35"
10
+ version = "5.9"
11
11
  description = "A HungerLib-powered Minecraft server automation engine."
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.14"
@@ -0,0 +1,24 @@
1
+ # serverwatcher/__main__.py
2
+
3
+ import argparse
4
+ from .watcher import ServerWatcher
5
+ from serverwatcher.validator import validate_all
6
+
7
+ def main():
8
+ parser = argparse.ArgumentParser()
9
+ parser.add_argument("--init", action="store_true")
10
+ args = parser.parse_args()
11
+
12
+ if args.init:
13
+ # Create default configs
14
+ from .initializer import initialize
15
+ initialize()
16
+ return
17
+
18
+ validate_all()
19
+
20
+ watcher = ServerWatcher()
21
+ watcher.run()
22
+
23
+ if __name__ == "__main__":
24
+ main()
@@ -0,0 +1,28 @@
1
+ from hungerlib import datamap, datamap_api
2
+
3
+ @datamap(syntax=datamap_api.braces, mode="config")
4
+ class GlobalConfig:
5
+ timezone: str = "timezone"
6
+
7
+ panel_name: str = "panel.name"
8
+ panel_url: str = "panel.url"
9
+ panel_api_key: str = "panel.api_key"
10
+
11
+ origin_server_id: str = "origin.server_id"
12
+
13
+ server_name: str = "server.name"
14
+ server_id: str = "server.server_id"
15
+ server_domain: str = "server.domain"
16
+ server_port: int = "server.port"
17
+
18
+ tps_command: str = "server.tps_command"
19
+
20
+ bridge_token: str = "hungerbridge.token"
21
+ bridge_url: str = "hungerbridge.url"
22
+ bridge_port: int = "hungerbridge.port"
23
+
24
+ enable_logging: bool = "logger.enabled"
25
+ logger_name: str = "logger.name"
26
+ log_path: str = "logger.log_path"
27
+
28
+ clear_terminal: bool = "terminal.enable_clearing"
@@ -0,0 +1,56 @@
1
+ from hungerlib import datamap, datamap_api
2
+
3
+ @datamap(syntax=datamap_api.braces, mode="config")
4
+ class MessagesConfig:
5
+ prefix: str = "prefix"
6
+ bullet: str = "bullet"
7
+
8
+ broadcast_restart_at: str = "broadcast_restart_at"
9
+
10
+ minute_120: str = "broadcast_minutes.120"
11
+ minute_60: str = "broadcast_minutes.60"
12
+ minute_45: str = "broadcast_minutes.45"
13
+ minute_30: str = "broadcast_minutes.30"
14
+ minute_15: str = "broadcast_minutes.15"
15
+ minute_5: str = "broadcast_minutes.5"
16
+ minute_1: str = "broadcast_minutes.1"
17
+
18
+ second_10: str = "broadcast_seconds.10"
19
+ second_9: str = "broadcast_seconds.9"
20
+ second_8: str = "broadcast_seconds.8"
21
+ second_7: str = "broadcast_seconds.7"
22
+ second_6: str = "broadcast_seconds.6"
23
+ second_5: str = "broadcast_seconds.5"
24
+ second_4: str = "broadcast_seconds.4"
25
+ second_3: str = "broadcast_seconds.3"
26
+ second_2: str = "broadcast_seconds.2"
27
+ second_1: str = "broadcast_seconds.1"
28
+
29
+ status_check: str = "logging.status_check"
30
+ validation_fail: str = "logging.validation_fail"
31
+ validation_ok: str = "logging.validation_ok"
32
+ shutdown: str = "logging.shutdown"
33
+ immediate_restart: str = "logging.immediate_restart"
34
+ no_restart: str = "logging.no_restart"
35
+ scheduled: str = "logging.scheduled"
36
+ gap_low: str = "logging.gap_low"
37
+ gap_high: str = "logging.gap_high"
38
+
39
+ pro_restart_splash: str = "reasons.pro_splash"
40
+ anti_restart_splash: str = "reasons.anti_splash"
41
+
42
+ reason_restart_soon: str = "reasons.restart_soon"
43
+ reason_ram: str = "reasons.ram"
44
+ reason_cpu: str = "reasons.cpu"
45
+ reason_uptime: str = "reasons.uptime"
46
+ reason_tps: str = "reasons.tps"
47
+ reason_low_uptime: str = "reasons.low_uptime"
48
+ reason_players: str = "reasons.players"
49
+
50
+ pro_restart_number: str = "reasons.pro_restart_number"
51
+ anti_restart_number: str = "reasons.anti_restart_number"
52
+
53
+ restart_action_sent: str = "restarts.restart_action_sent"
54
+ server_back_online: str = "restarts.back_online"
55
+ server_back_online_broadcast: str = "restarts.back_online_broadcast"
56
+ server_failed_restart: str = "restarts.failed_restart"
@@ -0,0 +1,28 @@
1
+ from hungerlib import datamap, datamap_api
2
+
3
+ @datamap(syntax=datamap_api.braces, mode="config")
4
+ class WatcherConfig:
5
+ watch_interval: int = "watch_interval"
6
+ schedule_control: bool = "schedule_control.enabled"
7
+ restart_soon_id: int = "schedule_control.restart_soon_id"
8
+
9
+ threshold_ram: int = "thresholds.ram"
10
+ threshold_cpu: int = "thresholds.cpu"
11
+ threshold_uptime: int = "thresholds.uptime"
12
+ threshold_tps: float = "thresholds.tps"
13
+
14
+ weight_restart_soon: int = "weights.restart_soon"
15
+ weight_ram: int = "weights.ram"
16
+ weight_cpu: int = "weights.cpu"
17
+ weight_uptime: int = "weights.uptime"
18
+ weight_tps: int = "weights.tps"
19
+
20
+ weight_low_uptime: int = "weights.low_uptime"
21
+ weight_per_player: int = "weights.per_player"
22
+
23
+ low_gap_minutes: int = "gaps.low_gap_minutes"
24
+ high_gap_minutes: int = "gaps.high_gap_minutes"
25
+
26
+ restart_wait_seconds: int = "restart.wait_seconds"
27
+ restart_timeout: int = "restart.online_timeout"
28
+ restart_online_interval: int = "restart.online_interval"
@@ -13,15 +13,17 @@ server:
13
13
  server_id: 'CHANGE_ME'
14
14
  domain: 'mc.example.com'
15
15
  port: 25565
16
- rcon_port: 25575
17
- rcon_password: 'password'
18
16
  tps_command: 'ticks'
19
17
 
18
+ hungerbridge:
19
+ token: 'CHANGE_ME'
20
+ url: 'http://example.com'
21
+ port: 1913
22
+
20
23
  logger:
21
24
  enabled: True
22
25
  name: 'Server Watcher'
23
26
  log_path: '/home/container/logs/'
24
27
 
25
28
  terminal:
26
- backspaces: 8
27
29
  enable_clearing: True
@@ -7,7 +7,6 @@ broadcast_minutes: {}
7
7
  broadcast_seconds: {}
8
8
 
9
9
  logging:
10
- startup: 'ServerWatcher is running!'
11
10
  status_check: 'Checking server status...'
12
11
  validation_fail: 'Validation FAILED.'
13
12
  validation_ok: 'All validation checks succeeded.'
@@ -47,8 +47,8 @@ def validate_global_config(config, errors):
47
47
  if config.server_port <= 0 or config.server_port > 65535:
48
48
  errors.append(f"server_port: must be 1–65535 (got {config.server_port})")
49
49
 
50
- if config.rcon_port <= 0 or config.rcon_port > 65535:
51
- errors.append(f"rcon_port: must be 1–65535 (got {config.rcon_port})")
50
+ if config.bridge_port <= 0 or config.rcon_port > 65535:
51
+ errors.append(f"bridge_port: must be 1–65535 (got {config.bridge_port})")
52
52
 
53
53
  def validate_watcher_config(watcherconfig, errors):
54
54
  if watcherconfig.restart_wait_seconds < 1:
@@ -7,9 +7,7 @@ from hungerlib import servers, MessageRouter, loadConfig, utils, datamap_api, ma
7
7
  from serverwatcher.configclasses.config import GlobalConfig
8
8
  from serverwatcher.configclasses.messages import MessagesConfig
9
9
  from serverwatcher.configclasses.watcher import WatcherConfig
10
- from serverwatcher.validator import validate_all
11
10
 
12
- validate_all()
13
11
 
14
12
 
15
13
  class ServerWatcher:
@@ -57,8 +55,8 @@ class ServerWatcher:
57
55
  server_id=self.config.server_id,
58
56
  server_domain=self.config.server_domain,
59
57
  server_port=self.config.server_port,
60
- rcon_port=self.config.rcon_port,
61
- rcon_password=self.config.rcon_password,
58
+ bridge_url=self.config.bridge_url.rstrip("/") + ":" + self.config.bridge_port,
59
+ bridge_token=self.config.bridge_token,
62
60
  tpsCommand=self.config.tps_command,
63
61
  )
64
62
 
@@ -69,7 +67,6 @@ class ServerWatcher:
69
67
  server=self.server,
70
68
  log_path=self.config.log_path,
71
69
  formatter=self._fmt,
72
- console_backspaces=self.config.console_backspaces,
73
70
  )
74
71
 
75
72
  self.tz = ZoneInfo(self.config.timezone)
@@ -77,17 +74,29 @@ class ServerWatcher:
77
74
  def _fmt(self, template: str, **ctx):
78
75
  return mapit(template, **ctx)
79
76
 
80
- def say(self, template, level="info", **ctx):
77
+ def say(self, template, level="info", only_maps=None, disable=None, enable=None, **ctx):
81
78
  if not template:
82
79
  return
83
- msg = mapit(template, **ctx)
80
+
81
+ msg = mapit(
82
+ template,
83
+ only_maps=only_maps,
84
+ disable=disable,
85
+ enable=enable,
86
+ )
87
+
84
88
  self.router.say(
85
89
  msg,
86
90
  level=level,
87
91
  log=self.config.enable_logging,
88
- **ctx
89
92
  )
90
93
 
94
+ def say_mc(self, template, level="info", only_maps=None, disable=None, enable=None, **ctx):
95
+ disable = (disable or []) + [utils.ASCII_COLOR_MAP]
96
+ enable = (enable or []) + [utils.MC_COLOR_MAP]
97
+ msg = mapit(template, only_maps=only_maps, disable=disable, enable=enable, **ctx)
98
+ self.router.broadcast(msg)
99
+
91
100
  def shutdown(self):
92
101
  self.say(self.messages.shutdown)
93
102
  raise SystemExit
@@ -109,23 +118,23 @@ class ServerWatcher:
109
118
 
110
119
  if alive:
111
120
  self.say(self.messages.server_back_online)
112
- self.say(self.messages.server_back_online_broadcast, broadcast=True)
121
+ self.say_mc(self.messages.server_back_online_broadcast)
113
122
  else:
114
123
  self.say(self.messages.server_failed_restart, level="error")
115
124
 
116
125
  def schedule_restart(self, minutes):
117
- info = snapSchedule(minimumMinutes=minutes)
126
+ info = utils.snapSchedule(minimumMinutes=minutes)
118
127
  scheduled = info["scheduled"]
119
128
 
120
129
  local_time = scheduled.astimezone(self.tz)
121
130
  time_str = local_time.strftime("%I:%M %p")
122
131
 
123
- self.router.broadcast(mapit(self.messages.broadcast_restart_at, time=time_str))
132
+ self.say_mc(self.messages.broadcast_restart_at, time=time_str)
124
133
 
125
134
  minute_callbacks = {
126
135
  int(k.split("_")[1]): (
127
136
  lambda msg=mapit(getattr(self.messages, k)):
128
- self.router.broadcast(msg)
137
+ self.say_mc(msg)
129
138
  )
130
139
  for k in vars(self.messages)
131
140
  if k.startswith("minute_")
@@ -134,20 +143,20 @@ class ServerWatcher:
134
143
  second_callbacks = {
135
144
  int(k.split("_")[1]): (
136
145
  lambda msg=mapit(getattr(self.messages, k)):
137
- self.router.broadcast(msg)
146
+ self.say_mc(msg)
138
147
  )
139
148
  for k in vars(self.messages)
140
149
  if k.startswith("second_")
141
150
  }
142
151
 
143
- runCountdownEvents(
152
+ utils.runCountdownEvents(
144
153
  target_time=scheduled,
145
154
  minute_callbacks=minute_callbacks,
146
155
  second_callbacks=second_callbacks,
147
156
  )
148
157
 
149
158
  def evaluate(self):
150
- self.say(self.messages.startup)
159
+ self.say("ServerWatcher is running!")
151
160
 
152
161
  if not utils.validateAll(self.panel, self.server):
153
162
  self.say(self.messages.validation_fail, level="error")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: serverwatcher
3
- Version: 5.8.dev35
3
+ Version: 5.9
4
4
  Summary: A HungerLib-powered Minecraft server automation engine.
5
5
  Author: iFamished
6
6
  License: GPL-3.0
@@ -2,6 +2,7 @@ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  src/serverwatcher/__init__.py
5
+ src/serverwatcher/__main__.py
5
6
  src/serverwatcher/validator.py
6
7
  src/serverwatcher/watcher.py
7
8
  src/serverwatcher.egg-info/PKG-INFO
@@ -1,31 +0,0 @@
1
- from dataclasses import field
2
- from hungerlib import datamap, datamap_api
3
-
4
- def yaml_key(path: str, default=None):
5
- return field(default=default, metadata={"yaml_key": path})
6
-
7
- @datamap(syntax=datamap_api.braces)
8
- class GlobalConfig:
9
- timezone: str = yaml_key("timezone")
10
-
11
- panel_name: str = yaml_key("panel.name")
12
- panel_url: str = yaml_key("panel.url")
13
- panel_api_key: str = yaml_key("panel.api_key")
14
-
15
- origin_server_id: str = yaml_key("origin.server_id")
16
-
17
- server_name: str = yaml_key("server.name")
18
- server_id: str = yaml_key("server.server_id")
19
- server_domain: str = yaml_key("server.domain")
20
- server_port: int = yaml_key("server.port")
21
-
22
- rcon_port: int = yaml_key("server.rcon_port")
23
- rcon_password: str = yaml_key("server.rcon_password")
24
- tps_command: str = yaml_key("server.tps_command")
25
-
26
- enable_logging: bool = yaml_key("logger.enabled")
27
- logger_name: str = yaml_key("logger.name")
28
- log_path: str = yaml_key("logger.log_path")
29
-
30
- console_backspaces: int = yaml_key("terminal.backspaces")
31
- clear_terminal: bool = yaml_key("terminal.enable_clearing")
@@ -1,61 +0,0 @@
1
- from dataclasses import field
2
- from hungerlib import datamap, datamap_api
3
-
4
- def yaml_key(path: str, default=None):
5
- return field(default=default, metadata={"yaml_key": path})
6
-
7
- @datamap(syntax=datamap_api.braces)
8
- class MessagesConfig:
9
- prefix: str = yaml_key("prefix", "<aqua>[Server Watcher]")
10
- bullet: str = yaml_key("bullet")
11
-
12
- broadcast_restart_at: str = yaml_key("broadcast_restart_at")
13
-
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
-
33
- startup: str = yaml_key("logging.startup")
34
- status_check: str = yaml_key("logging.status_check")
35
- validation_fail: str = yaml_key("logging.validation_fail")
36
- validation_ok: str = yaml_key("logging.validation_ok")
37
- shutdown: str = yaml_key("logging.shutdown")
38
- immediate_restart: str = yaml_key("logging.immediate_restart")
39
- no_restart: str = yaml_key("logging.no_restart")
40
- scheduled: str = yaml_key("logging.scheduled")
41
- gap_low: str = yaml_key("logging.gap_low")
42
- gap_high: str = yaml_key("logging.gap_high")
43
-
44
- pro_restart_splash: str = yaml_key("reasons.pro_splash")
45
- anti_restart_splash: str = yaml_key("reasons.anti_splash")
46
-
47
- reason_restart_soon: str = yaml_key("reasons.restart_soon")
48
- reason_ram: str = yaml_key("reasons.ram")
49
- reason_cpu: str = yaml_key("reasons.cpu")
50
- reason_uptime: str = yaml_key("reasons.uptime")
51
- reason_tps: str = yaml_key("reasons.tps")
52
- reason_low_uptime: str = yaml_key("reasons.low_uptime")
53
- reason_players: str = yaml_key("reasons.players")
54
-
55
- pro_restart_number: str = yaml_key("reasons.pro_restart_number")
56
- anti_restart_number: str = yaml_key("reasons.anti_restart_number")
57
-
58
- restart_action_sent: str = yaml_key("restarts.restart_action_sent")
59
- server_back_online: str = yaml_key("restarts.back_online")
60
- server_back_online_broadcast: str = yaml_key("restarts.back_online_broadcast")
61
- server_failed_restart: str = yaml_key("restarts.failed_restart")
@@ -1,32 +0,0 @@
1
- from dataclasses import field
2
- from hungerlib import datamap, datamap_api
3
-
4
- def yaml_key(path: str, default=None):
5
- return field(default=default, metadata={"yaml_key": path})
6
-
7
- @datamap(syntax=datamap_api.braces)
8
- class WatcherConfig:
9
- watch_interval: int = yaml_key("watch_interval")
10
- schedule_control: bool = yaml_key("schedule_control.enabled")
11
- restart_soon_id: int = yaml_key("schedule_control.restart_soon_id")
12
-
13
- threshold_ram: int = yaml_key("thresholds.ram")
14
- threshold_cpu: int = yaml_key("thresholds.cpu")
15
- threshold_uptime: int = yaml_key("thresholds.uptime")
16
- threshold_tps: float = yaml_key("thresholds.tps")
17
-
18
- weight_restart_soon: int = yaml_key("weights.restart_soon")
19
- weight_ram: int = yaml_key("weights.ram")
20
- weight_cpu: int = yaml_key("weights.cpu")
21
- weight_uptime: int = yaml_key("weights.uptime")
22
- weight_tps: int = yaml_key("weights.tps")
23
-
24
- weight_low_uptime: int = yaml_key("weights.low_uptime")
25
- weight_per_player: int = yaml_key("weights.per_player")
26
-
27
- low_gap_minutes: int = yaml_key("gaps.low_gap_minutes")
28
- high_gap_minutes: int = yaml_key("gaps.high_gap_minutes")
29
-
30
- restart_wait_seconds: int = yaml_key("restart.wait_seconds")
31
- restart_timeout: int = yaml_key("restart.online_timeout")
32
- restart_online_interval: int = yaml_key("restart.online_interval")
File without changes
File without changes
File without changes