serverwatcher 2.1.2__tar.gz → 2.2.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: serverwatcher
3
- Version: 2.1.2
3
+ Version: 2.2.3
4
4
  Summary: A HungerLib-powered Minecraft server automation engine.
5
5
  Author: iFamished
6
6
  License: MIT
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "serverwatcher"
10
- version = "2.1.2"
10
+ version = "2.2.3"
11
11
  description = "A HungerLib-powered Minecraft server automation engine."
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"
@@ -18,7 +18,8 @@ class WatcherMessages:
18
18
  })
19
19
 
20
20
  broadcast_second: dict = field(default_factory=lambda: {
21
- s: "{prefix} Restart in " + str(s) + " seconds!" for s in range(10, 0, -1)
21
+ s: "{prefix} Restart in " + str(s) + " seconds!"
22
+ for s in range(10, 0, -1)
22
23
  })
23
24
 
24
25
  # log messages
@@ -1,23 +1,90 @@
1
1
  import time
2
2
  from zoneinfo import ZoneInfo
3
3
 
4
+ from hungerlib import Panel, HungerLogger
5
+ from hungerlib.servers import MinecraftServer, GenericServer
4
6
  from hungerlib.addons import (
7
+ clearTerminal,
5
8
  Snapshot,
6
9
  snapSchedule,
7
10
  waitForOnline,
8
11
  validateAll,
9
- runCountdownEvents
12
+ runCountdownEvents,
10
13
  )
14
+ from hungerlib.addons import configloader
15
+
16
+ from .config import WatcherConfig
17
+ from .messages import WatcherMessages
18
+
19
+
20
+ DEFAULT_CONFIG = {
21
+ "panel": {
22
+ "name": "My Panel",
23
+ "url": "https://example.com",
24
+ "api_key": "CHANGE_ME",
25
+ },
26
+ "origin": {
27
+ "server_id": "CHANGE_ME",
28
+ },
29
+ "server": {
30
+ "name": "My SMP",
31
+ "server_id": "CHANGE_ME",
32
+ "domain": "example.com",
33
+ "port": 25565,
34
+ "rcon_port": 25575,
35
+ "rcon_password": "password",
36
+ "tps_command": "ticks",
37
+ },
38
+ "watcher": {},
39
+ "messages": {},
40
+ }
11
41
 
12
42
 
13
43
  class ServerWatcher:
14
- def __init__(self, server, origin, panel, logger, config, messages):
15
- self.server = server
16
- self.origin = origin
17
- self.panel = panel
18
- self.log = logger
19
- self.cfg = config
20
- self.msg = messages
44
+ def __init__(self, config_path: str = "config.yaml"):
45
+ # ensure config exists, then load it
46
+ ensure_yaml(config_path, DEFAULT_CONFIG)
47
+ raw = load_yaml(config_path)
48
+
49
+ # map watcher + messages sections into your dataclasses
50
+ self.cfg: WatcherConfig = map_to_dataclass(raw.get("watcher", {}), WatcherConfig)
51
+ self.msg: WatcherMessages = map_to_dataclass(
52
+ raw.get("messages", {}), WatcherMessages
53
+ )
54
+
55
+ # panel / origin / server wiring from YAML
56
+ p = raw["panel"]
57
+ self.panel = Panel(
58
+ name=p["name"],
59
+ url=p["url"],
60
+ api_key=p["api_key"],
61
+ )
62
+
63
+ o = raw["origin"]
64
+ self.origin = GenericServer(
65
+ name="Origin",
66
+ panel=self.panel,
67
+ server_id=o["server_id"],
68
+ )
69
+
70
+ s = raw["server"]
71
+ self.server = MinecraftServer(
72
+ name=s["name"],
73
+ panel=self.panel,
74
+ server_id=s["server_id"],
75
+ server_domain=s["domain"],
76
+ server_port=s["port"],
77
+ rcon_port=s["rcon_port"],
78
+ rcon_password=s["rcon_password"],
79
+ tpsCommand=s["tps_command"],
80
+ )
81
+
82
+ self.log = HungerLogger(
83
+ name=f"ServerWatcher-{s['name']}",
84
+ server=self.server,
85
+ log_path="/home/container/logs/",
86
+ console_backspaces=8,
87
+ )
21
88
 
22
89
  def fmt(self, template: str, **kwargs):
23
90
  return template.format(prefix=self.msg.prefix, **kwargs)
@@ -36,12 +103,12 @@ class ServerWatcher:
36
103
  alive = waitForOnline(
37
104
  self.server,
38
105
  timeout=self.cfg.restart_online_timeout,
39
- interval=self.cfg.restart_online_interval
106
+ interval=self.cfg.restart_online_interval,
40
107
  )
41
108
 
42
109
  if alive:
43
110
  self.log.info("Server is back online!")
44
- self.server.sendBroadcast(f'{self.msg.prefix}<green>Restart successful!')
111
+ self.server.sendBroadcast(f"{self.msg.prefix}<green>Restart successful!")
45
112
  self.origin.enableSchedule(self.cfg.origin_disable_schedule_id)
46
113
  else:
47
114
  self.log.error("Server failed to restart!")
@@ -58,21 +125,19 @@ class ServerWatcher:
58
125
  )
59
126
 
60
127
  minute_callbacks = {
61
- m: (lambda msg=self.fmt(self.msg.broadcast_minute[m]):
62
- self.server.sendBroadcast(msg))
128
+ m: (lambda msg=self.fmt(self.msg.broadcast_minute[m]): self.server.sendBroadcast(msg))
63
129
  for m in self.msg.broadcast_minute
64
130
  }
65
131
 
66
132
  second_callbacks = {
67
- s: (lambda msg=self.fmt(self.msg.broadcast_second[s]):
68
- self.server.sendBroadcast(msg))
133
+ s: (lambda msg=self.fmt(self.msg.broadcast_second[s]): self.server.sendBroadcast(msg))
69
134
  for s in self.msg.broadcast_second
70
135
  }
71
136
 
72
137
  runCountdownEvents(
73
138
  target_time=scheduled,
74
139
  minute_callbacks=minute_callbacks,
75
- second_callbacks=second_callbacks
140
+ second_callbacks=second_callbacks,
76
141
  )
77
142
 
78
143
  def evaluate(self):
@@ -97,32 +162,51 @@ class ServerWatcher:
97
162
 
98
163
  if snap.ram >= self.cfg.ram_threshold:
99
164
  restart_reasons.append(
100
- self.fmt(self.msg.reason_ram, ram=snap.ram, threshold=self.cfg.ram_threshold)
165
+ self.fmt(
166
+ self.msg.reason_ram,
167
+ ram=snap.ram,
168
+ threshold=self.cfg.ram_threshold,
169
+ )
101
170
  )
102
171
  pro += round(snap.ram, 0) - 5
103
172
 
104
173
  if snap.cpu >= self.cfg.cpu_threshold:
105
174
  restart_reasons.append(
106
- self.fmt(self.msg.reason_cpu, cpu=snap.cpu, threshold=self.cfg.cpu_threshold)
175
+ self.fmt(
176
+ self.msg.reason_cpu,
177
+ cpu=snap.cpu,
178
+ threshold=self.cfg.cpu_threshold,
179
+ )
107
180
  )
108
181
  pro += self.cfg.weight_cpu
109
182
 
110
183
  if snap.uptime // 3600 >= self.cfg.uptime_hours_threshold:
111
184
  restart_reasons.append(
112
- self.fmt(self.msg.reason_uptime, uptime=snap.uptime_formatted, threshold=self.cfg.uptime_hours_threshold)
185
+ self.fmt(
186
+ self.msg.reason_uptime,
187
+ uptime=snap.uptime_formatted,
188
+ threshold=self.cfg.uptime_hours_threshold,
189
+ )
113
190
  )
114
191
  pro += self.cfg.weight_uptime
115
192
 
116
193
  if snap.tps <= self.cfg.tps_threshold:
117
194
  restart_reasons.append(
118
- self.fmt(self.msg.reason_tps, tps=snap.tps, threshold=self.cfg.tps_threshold)
195
+ self.fmt(
196
+ self.msg.reason_tps,
197
+ tps=snap.tps,
198
+ threshold=self.cfg.tps_threshold,
199
+ )
119
200
  )
120
201
  pro += self.cfg.weight_tps
121
202
 
122
203
  # ANTI-RESTART
123
204
  if snap.uptime // 60 < 30:
124
205
  no_restart_reasons.append(
125
- self.fmt(self.msg.reason_low_uptime, uptime=snap.uptime_formatted)
206
+ self.fmt(
207
+ self.msg.reason_low_uptime,
208
+ uptime=snap.uptime_formatted,
209
+ )
126
210
  )
127
211
  anti += self.cfg.weight_low_uptime
128
212
 
@@ -130,7 +214,12 @@ class ServerWatcher:
130
214
  verb = "are" if snap.players != 1 else "is"
131
215
  plural = "players" if snap.players != 1 else "player"
132
216
  no_restart_reasons.append(
133
- self.fmt(self.msg.reason_players, verb=verb, count=snap.players, plural=plural)
217
+ self.fmt(
218
+ self.msg.reason_players,
219
+ verb=verb,
220
+ count=snap.players,
221
+ plural=plural,
222
+ )
134
223
  )
135
224
  anti += snap.players * self.cfg.weight_per_player
136
225
 
@@ -164,3 +253,9 @@ class ServerWatcher:
164
253
  self.schedule_restart(self.cfg.high_gap_minutes)
165
254
 
166
255
  self.restart_and_wait()
256
+
257
+ def run(self):
258
+ clearTerminal()
259
+ while True:
260
+ self.evaluate()
261
+ time.sleep(60)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: serverwatcher
3
- Version: 2.1.2
3
+ Version: 2.2.3
4
4
  Summary: A HungerLib-powered Minecraft server automation engine.
5
5
  Author: iFamished
6
6
  License: MIT
File without changes
File without changes
File without changes