Skip to content

Commit 660d198

Browse files
committed
add scripts & small refactor
1 parent 11434db commit 660d198

File tree

1 file changed

+108
-54
lines changed

1 file changed

+108
-54
lines changed

hooks/__init__.py

Lines changed: 108 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
import time
44
from enum import Enum
55
from io import StringIO
6-
from typing import List, Any
6+
from typing import List, Any, Union
77

88
from mcdreforged.api.all import *
99
from mcdreforged.api.utils import serializer
10+
from ruamel import yaml
1011

12+
scripts_folder: str = ''
13+
14+
scripts_list: dict[str, str] = {}
1115

12-
##################################################################
13-
##################### Basic Function #############################
14-
##################################################################
1516

1617
class Hooks(Enum):
1718
undefined = 'undefined'
@@ -75,14 +76,12 @@ def execute_task(self, server: PluginServerInterface, hook: str, var_dict: dict
7576
command.write('"')
7677
command.write(str(var_dict.get(key)))
7778
command.write('" && ')
78-
7979
command.write(self.command)
8080

8181
os.system(command.getvalue())
8282
elif self.task_type == TaskType.server_command:
8383
# 替换参数
8484
command = self.command
85-
8685
if var_dict is not None:
8786
for key in var_dict.keys():
8887
command = command.replace('{$' + key + '}', str(var_dict.get(key)))
@@ -91,7 +90,6 @@ def execute_task(self, server: PluginServerInterface, hook: str, var_dict: dict
9190
elif self.task_type == TaskType.mcdr_command:
9291
# 替换参数
9392
command = self.command
94-
9593
if var_dict is not None:
9694
for key in var_dict.keys():
9795
command = command.replace('{$' + key + '}', str(var_dict.get(key)))
@@ -103,11 +101,16 @@ def execute_task(self, server: PluginServerInterface, hook: str, var_dict: dict
103101

104102

105103
class Configuration(Serializable):
106-
107104
def __init__(self, **kwargs):
108105
super().__init__(**kwargs)
109106

110107
automatically: bool = True
108+
109+
110+
class TempConfig(Serializable):
111+
112+
def __init__(self, **kwargs):
113+
super().__init__(**kwargs)
111114

112115
hooks: dict[str, List[str]] = {
113116
'undefined': [],
@@ -132,6 +135,8 @@ def __init__(self, **kwargs):
132135
task: dict[str, Task] = {}
133136

134137

138+
temp_config: TempConfig = TempConfig()
139+
135140
config: Configuration
136141

137142

@@ -142,7 +147,7 @@ def trigger_hooks(hook: Hooks, server: PluginServerInterface, objects_dict: dict
142147
try:
143148
server.logger.debug(f'Triggered hooks {hook.value}')
144149
server.logger.debug(f'objects_dict: {str(objects_dict)}')
145-
if len(config.hooks.get(hook.value)) != 0:
150+
if len(temp_config.hooks.get(hook.value)) != 0:
146151
_trigger_hooks(hook, server, objects_dict)
147152
except Exception as e:
148153
server.logger.exception(f'Unexpected exception when triggering hook {hook.value}', e)
@@ -173,30 +178,25 @@ def _trigger_hooks(hook: Hooks, server: PluginServerInterface, objects_dict: dic
173178
var_inner_attr_value: Any = var_inner_attr_dict.get(var_inner_attr_key)
174179

175180
finally_var_dict[an_object_key + '_' + var_inner_attr_key] = var_inner_attr_value
176-
181+
177182
server.logger.debug(f'Executing hook {hook.value}')
178183
# 遍历被挂载到此hook的task的key
179-
for task in config.hooks.get(hook.value):
180-
if config.task.get(task) is None:
184+
for task in temp_config.hooks.get(hook.value):
185+
if temp_config.task.get(task) is None:
181186
server.logger.warning(f'Task {task} is not exist, unmount it from hook {hook.value}!')
182-
config.hooks.get(hook.value).remove(task)
187+
temp_config.hooks.get(hook.value).remove(task)
183188
return
184189
# 执行任务
185190
try:
186-
config.task.get(task).execute_task(server, hook.value, finally_var_dict)
191+
temp_config.task.get(task).execute_task(server, hook.value, finally_var_dict)
187192
except Exception as e:
188193
server.logger.exception(
189-
f'Unexpected exception when executing task {task}, hook {hook.value}, task_type {config.task.get(task).task_type}, command {config.task.get(task).command}',
194+
f'Unexpected exception when executing task {task}, hook {hook.value}, task_type {temp_config.task.get(task).task_type}, command {temp_config.task.get(task).command}',
190195
e)
191196

192197

193-
##################################################################
194-
######################### For Commands ###########################
195-
##################################################################
196-
197-
@new_thread('hooks - mount')
198198
def mount_task(hook: str, task: str, src: CommandSource, server: PluginServerInterface):
199-
h = config.hooks.get(hook)
199+
h = temp_config.hooks.get(hook)
200200

201201
if h is None:
202202
src.reply(RTextMCDRTranslation('hooks.mount.hook_not_exist', hook))
@@ -211,9 +211,8 @@ def mount_task(hook: str, task: str, src: CommandSource, server: PluginServerInt
211211
server.logger.info(f'Successfully mounted task {task}')
212212

213213

214-
@new_thread('hooks - unmount')
215214
def unmount_task(hook: str, task: str, src: CommandSource, server: PluginServerInterface):
216-
h = config.hooks.get(hook)
215+
h = temp_config.hooks.get(hook)
217216

218217
if h is None:
219218
src.reply(RTextMCDRTranslation('hooks.mount.hook_not_exist', hook))
@@ -228,9 +227,8 @@ def unmount_task(hook: str, task: str, src: CommandSource, server: PluginServerI
228227
server.logger.info(f'Successfully unmounted task {task}')
229228

230229

231-
@new_thread('hooks - create')
232230
def create_task(task_type: str, command: str, name: str, src: CommandSource, server: PluginServerInterface):
233-
if name in config.task:
231+
if name in temp_config.task:
234232
src.reply(RTextMCDRTranslation('hooks.create.already_exist'))
235233
return
236234

@@ -240,34 +238,33 @@ def create_task(task_type: str, command: str, name: str, src: CommandSource, ser
240238
src.reply(RTextMCDRTranslation('hooks.create.task_type_wrong', task_type))
241239
return
242240

243-
config.task[name] = Task(name=name, task_type=tsk_type, command=command)
241+
temp_config.task[name] = Task(name=name, task_type=tsk_type, command=command)
244242

245243
server.logger.info(f'Successfully created task {name}')
246244
src.reply(RTextMCDRTranslation('hooks.create.success', name))
247245

248246

249-
@new_thread('hooks - delete')
250247
def delete_task(name: str, src: CommandSource, server: PluginServerInterface):
251-
if name not in config.task.keys():
248+
if name not in temp_config.task.keys():
252249
src.reply(RTextMCDRTranslation('hooks.mount.task_not_exist', name))
253250
return
254251

255252
server.logger.info(f'Successfully deleted task {name}')
256253
src.reply(RTextMCDRTranslation('hooks.delete.success', name))
257254

258-
config.task.pop(name)
255+
temp_config.task.pop(name)
259256

260257

261258
@new_thread('hooks - list')
262259
def list_task(src: CommandSource):
263260
rtext_list = RTextList()
264261

265-
if len(config.task.values()) == 0:
262+
if len(temp_config.task.values()) == 0:
266263
rtext_list.append(RText('Nothing', color=RColor.dark_gray, styles=RStyle.italic))
267264
src.reply(RTextMCDRTranslation('hooks.list.task', rtext_list))
268265
return
269266

270-
for t in config.task.values():
267+
for t in temp_config.task.values():
271268
rtext_list.append(RText(t.name + ' ', color=RColor.red).h(t.task_type.name + ' -> ' + t.command))
272269

273270
src.reply(RTextMCDRTranslation('hooks.list.task', rtext_list))
@@ -277,31 +274,35 @@ def list_task(src: CommandSource):
277274
def list_mount(src: CommandSource):
278275
src.reply(
279276
RTextMCDRTranslation('hooks.list.mount',
280-
config.hooks.get(Hooks.on_plugin_loaded.value),
281-
config.hooks.get(Hooks.on_plugin_unloaded.value),
282-
config.hooks.get(Hooks.on_server_starting.value),
283-
config.hooks.get(Hooks.on_server_started.value),
284-
config.hooks.get(Hooks.on_server_stopped.value),
285-
config.hooks.get(Hooks.on_server_crashed.value),
286-
config.hooks.get(Hooks.on_mcdr_started.value),
287-
config.hooks.get(Hooks.on_mcdr_stopped.value),
288-
config.hooks.get(Hooks.on_player_joined.value),
289-
config.hooks.get(Hooks.on_player_left.value),
290-
config.hooks.get(Hooks.on_info.value),
291-
config.hooks.get(Hooks.on_user_info.value),
292-
config.hooks.get(Hooks.undefined.value),
277+
temp_config.hooks.get(Hooks.on_plugin_loaded.value),
278+
temp_config.hooks.get(Hooks.on_plugin_unloaded.value),
279+
temp_config.hooks.get(Hooks.on_server_starting.value),
280+
temp_config.hooks.get(Hooks.on_server_started.value),
281+
temp_config.hooks.get(Hooks.on_server_stopped.value),
282+
temp_config.hooks.get(Hooks.on_server_crashed.value),
283+
temp_config.hooks.get(Hooks.on_mcdr_started.value),
284+
temp_config.hooks.get(Hooks.on_mcdr_stopped.value),
285+
temp_config.hooks.get(Hooks.on_player_joined.value),
286+
temp_config.hooks.get(Hooks.on_player_left.value),
287+
temp_config.hooks.get(Hooks.on_info.value),
288+
temp_config.hooks.get(Hooks.on_user_info.value),
289+
temp_config.hooks.get(Hooks.undefined.value),
293290
)
294291
)
295292

296293

297294
def reload_config(src: CommandSource, server: PluginServerInterface):
298-
server.load_config_simple(target_class=Configuration)
295+
global config, temp_config
296+
297+
temp_config = TempConfig()
298+
config = server.load_config_simple(target_class=Configuration)
299+
load_scripts(server)
299300
server.logger.info('Config reloaded.')
300301
src.reply(RTextMCDRTranslation('hooks.reload.success'))
301-
302+
302303

303304
def man_run_task(task: str, env_str: str, src: CommandSource, server: PluginServerInterface):
304-
if task not in config.task.keys():
305+
if task not in temp_config.task.keys():
305306
src.reply(RTextMCDRTranslation('hooks.man_run.task_not_exist'))
306307
return
307308

@@ -312,14 +313,66 @@ def man_run_task(task: str, env_str: str, src: CommandSource, server: PluginServ
312313
return
313314

314315
try:
315-
config.task.get(task).execute_task(server, Hooks.undefined.value, env_dict)
316+
temp_config.task.get(task).execute_task(server, Hooks.undefined.value, env_dict)
316317
src.reply(RTextMCDRTranslation('hooks.man_run.success', task))
317318
except Exception as e:
318319
server.logger.exception(
319-
f'Unexpected exception when executing task {task}, hook {Hooks.undefined.value}, task_type {config.task.get(task).task_type}, command {config.task.get(task).command}',
320+
f'Unexpected exception when executing task {task}, hook {Hooks.undefined.value}, task_type {temp_config.task.get(task).task_type}, command {temp_config.task.get(task).command}',
320321
e)
321322

322323

324+
def register_scripts(script_path: str):
325+
# 将绝对路径添加进入script_list
326+
scripts_list[os.path.basename(script_path)] = script_path
327+
328+
329+
def parse_and_load_scripts(script: str, server: PluginServerInterface):
330+
# 读取
331+
with open(scripts_list.get(script), 'r') as f:
332+
content: dict[str, Union[str, Union[list, dict]]] = yaml.load(f.read(), Loader=yaml.Loader)
333+
334+
for task in content.get('tasks').values():
335+
# 创建task
336+
create_task(task.get('task_type'), task.get('command'), task.get('name'), server.get_plugin_command_source(),
337+
server)
338+
for hook in task.get('hooks'):
339+
# 挂载
340+
mount_task(hook, task.get('name'), server.get_plugin_command_source(), server)
341+
342+
343+
def load_scripts(server: PluginServerInterface):
344+
global scripts_list
345+
346+
if not os.path.isdir(scripts_folder):
347+
# 创建脚本目录
348+
os.makedirs(scripts_folder)
349+
return
350+
351+
def list_all_files(root_dir) -> list[str]:
352+
# 显示一个文件夹及子文件夹中的所有yaml文件
353+
_files_in_a_folder: list[str] = []
354+
355+
for file in os.listdir(root_dir):
356+
file_path = os.path.join(root_dir, file)
357+
358+
if os.path.isdir(file_path):
359+
# 遍历子文件夹
360+
_files_in_a_folder.extend(list_all_files(file_path))
361+
if os.path.isfile(file_path) and (file_path.endswith('.yaml') or file_path.endswith('.yml')):
362+
# 添加文件路径
363+
_files_in_a_folder.append(file_path)
364+
365+
return _files_in_a_folder
366+
367+
# 遍历所有文件
368+
for script_path in list_all_files(scripts_folder):
369+
register_scripts(script_path)
370+
371+
# 遍历所有已成功注册的脚本
372+
for script in scripts_list.keys():
373+
parse_and_load_scripts(script, server)
374+
375+
323376
def process_arg_server(server: PluginServerInterface) -> PluginServerInterface:
324377
server.func_is_server_running = server.is_server_running()
325378
server.func_is_server_startup = server.is_server_startup()
@@ -337,15 +390,16 @@ def process_arg_server(server: PluginServerInterface) -> PluginServerInterface:
337390
return server
338391

339392

340-
##################################################################
341-
############################ Triggers ############################
342-
##################################################################
343-
344393
def on_load(server: PluginServerInterface, old_module):
345-
global config
394+
global config, scripts_folder, temp_config
395+
396+
temp_config = TempConfig()
346397

347398
config = server.load_config_simple(target_class=Configuration)
348399

400+
scripts_folder = os.path.join(server.get_data_folder(), 'scripts')
401+
load_scripts(server)
402+
349403
server.register_command(
350404
Literal('!!hooks')
351405
.then(

0 commit comments

Comments
 (0)