|
1 | 1 | import re |
2 | 2 | import time |
3 | | -from typing import Any |
4 | 3 |
|
5 | 4 | from dowhen import when |
6 | 5 | from dowhen.handler import EventHandler |
7 | 6 | from mcdreforged import * |
8 | 7 |
|
| 8 | +from kill_server.config import Config |
9 | 9 |
|
10 | | -class Config(Serializable): |
11 | | - waiting_time: float = 60 |
12 | | - """等待时间, 超时之后才强制关闭服务器, 单位为秒""" |
13 | | - |
14 | | - def validate_attribute(self, attr_name: str, attr_value: Any, **kwargs): |
15 | | - if attr_value <= 0: |
16 | | - raise ValueError(f"配置项 waiting_time 必须是正值, 实际配置: {attr_value}") |
17 | | - if attr_value <= 3: |
18 | | - server_interface.logger.warning(f"配置项 waiting_time 单位为秒, 实际配置 {attr_value} 可能过小") |
19 | | - |
20 | | - |
21 | | -server_interface: PluginServerInterface |
| 10 | +psi: PluginServerInterface |
22 | 11 | config: Config |
23 | | - |
24 | 12 | handler: EventHandler |
25 | | -is_world_saved: bool = False |
26 | 13 |
|
| 14 | +ServerStoppingEvent = LiteralEvent("kill_server.server_stopping") |
| 15 | +PluginStoppingServerEvent = LiteralEvent("kill_server.plugin_stopping_server") |
| 16 | +WorldSavedEvent = LiteralEvent("kill_server.world_saved") |
27 | 17 |
|
| 18 | + |
| 19 | +@event_listener(ServerStoppingEvent) |
| 20 | +@new_thread("KillServer") |
28 | 21 | def force_kill_server(): |
29 | 22 | """强制关闭服务器""" |
| 23 | + if not config.enable: |
| 24 | + return |
| 25 | + |
| 26 | + psi.logger.info("检测到服务器关闭命令执行, 等待服务器自动关闭") |
30 | 27 |
|
31 | | - @new_thread("KillServer") |
32 | | - def logic(): |
33 | | - """开新线程运行并且保证 force_kill_server 返回 None""" |
34 | | - server_interface.logger.info("检测到服务器关闭命令执行, 等待服务器自动关闭") |
| 28 | + time.sleep(config.waiting_time) |
| 29 | + if not psi.is_server_running(): |
| 30 | + return |
| 31 | + psi.logger.info("等待服务器关闭超时, 正在强制关闭服务器") |
| 32 | + # TODO: 检查世界是否保存 |
| 33 | + psi.kill() |
35 | 34 |
|
36 | | - time.sleep(config.waiting_time) |
37 | | - if not server_interface.is_server_running(): |
38 | | - return |
39 | | - server_interface.logger.info("等待服务器关闭超时, 正在强制关闭服务器") |
40 | | - # TODO: 检查世界是否保存 |
41 | | - # if not is_world_saved: |
42 | | - # server_interface.logger.warning("世界未完全保存, 重新等待") |
43 | | - # goto("time.sleep(config.waiting_time)") |
44 | | - # return |
45 | | - server_interface.kill() |
46 | 35 |
|
47 | | - logic() |
| 36 | +def dispatch(event: PluginEvent): |
| 37 | + psi.dispatch_event(event, ()) |
48 | 38 |
|
49 | 39 |
|
50 | 40 | def on_load(server: PluginServerInterface, prev_module): |
51 | | - global server_interface, config, handler |
52 | | - server_interface = server |
| 41 | + global psi, config, handler |
| 42 | + psi = server |
53 | 43 | config = server.load_config_simple(target_class=Config) |
54 | 44 |
|
55 | 45 | if prev_module is not None: |
56 | 46 | prev_module.handler.remove() |
57 | 47 |
|
58 | | - handler = when(server.stop, "return").do(force_kill_server) |
59 | | - |
60 | | - |
61 | | -def on_server_startup(_server: PluginServerInterface): |
62 | | - global is_world_saved |
63 | | - is_world_saved = False |
| 48 | + # noinspection PyTypeChecker |
| 49 | + handler = when(server.stop, "return").do(lambda: dispatch(PluginStoppingServerEvent)) |
64 | 50 |
|
65 | 51 |
|
66 | 52 | def on_info(_server: PluginServerInterface, info: Info): |
| 53 | + if re.fullmatch(r"Stopping the server", info.content): |
| 54 | + dispatch(ServerStoppingEvent) |
67 | 55 | if re.fullmatch(r".*All dimensions are saved", info.content): |
68 | | - global is_world_saved |
69 | | - is_world_saved = True |
| 56 | + dispatch(WorldSavedEvent) |
0 commit comments