From 89108c0cd595e1e7522c920cd0e85eeec76b3028 Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Sun, 7 Nov 2021 20:23:30 +1100 Subject: [PATCH 1/7] add region protection --- region_file_updater/__init__.py | 46 +++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index b43d4a4..8b2aa30 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -34,6 +34,8 @@ class Config(Serializable): §7{0} del §r删除玩家所在位置的区域文件 §7{0} del §6[d] [x] [z] [d] §r删除指定的区域文件 §7{0} del-all §r删除所有区域文件 +§7{0} protect §r将玩家所在位置的区域文件设为保护状态 +§7{0} deprotect §r取消保护玩家所在位置的区域文件 §7{0} list §r列出待更新的区域文件 §7{0} history §r输出上一次update的结果 §7{0} update §r更新列表中的区域文件,这将重启服务器 @@ -44,6 +46,7 @@ class Config(Serializable): '''.strip().format(Prefix, PLUGIN_METADATA.name, PLUGIN_METADATA.version) regionList = [] # type: List[Region] +protectedRegionList = [] # type: List[Region] historyList = [] # type: List[Tuple[Region, bool]] server_inst: PluginServerInterface @@ -87,10 +90,11 @@ def print_log(server: ServerInterface, msg: str): def add_region(source: CommandSource, region: Region): if region in regionList: source.reply('列表中已存在该区域文件') - else: + elif region not in protectedRegionList: regionList.append(region) source.reply('区域文件§6{}§r已添加'.format(region)) - + else: + source.reply('该区域已设保护') def delete_region(source: CommandSource, region: Region): if region not in regionList: @@ -105,6 +109,25 @@ def clean_region_list(source): source.reply('区域文件列表已清空') +def protect_region(source: CommandSource, region: Region): + if region in protectedRegionList: + source.reply('该区域文件已设保护') + if region in regionList: + regionList.remove(region) + protectedRegionList.append(region) + source.reply('区域文件§6{}§r已从列表移除并设保护'.format(region)) + else: + protectedRegionList.append(region) + source.reply('区域文件§6{}§r已设保护'.format(region)) + + +def deprotect_region(source: CommandSource, region: Region): + if region in protectedRegionList: + protectedRegionList.remove(region) + source.reply('区域文件§6{}§r已取消保护'.format(region)) + else: + source.reply('该区域文件未被保护') + def get_region_from_source(source: PlayerCommandSource) -> Region: api = source.get_server().get_plugin_instance('minecraft_data_api') coord = api.get_player_coordinate(source.player) @@ -127,6 +150,19 @@ def delete_region_from_player(source: CommandSource): else: source.reply('该指令仅支持玩家执行') +@new_thread(PLUGIN_METADATA.name) +def protect_region_from_player(source: CommandSource): + if isinstance(source, PlayerCommandSource): + protect_region(source, get_region_from_source(source)) + else: + source.reply('该指令仅支持玩家执行') + +@new_thread(PLUGIN_METADATA.name) +def deprotect_region_from_player(source: CommandSource): + if isinstance(source, PlayerCommandSource): + deprotect_region(source, get_region_from_source(source)) + else: + source.reply('该指令仅支持玩家执行') def show_region_list(source: CommandSource): source.reply('更新列表中共有{}个待更新的区域文件'.format(len(regionList))) @@ -219,6 +255,12 @@ def get_region_parm_node(callback): then(get_region_parm_node(lambda src, ctx: delete_region(src, Region(ctx['x'], ctx['z'], ctx['dim'])))) ). then(Literal('del-all').runs(clean_region_list)). + then( + Literal('protect').runs(protect_region_from_player). + then(get_region_parm_node(lambda src, ctx: protect_region(src, Region(ctx['x'], ctx['z'], ctx['dim']))))). + then( + Literal('deprotect').runs(deprotect_region_from_player). + then(get_region_parm_node(lambda src, ctx: deprotect_region(src, Region(ctx['x'], ctx['z'], ctx['dim']))))). then(Literal('list').runs(show_region_list)). then(Literal('history').runs(show_history)). then( From 79622cd83b1e3145ba827249e9fee76d6ef1c964 Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Sun, 7 Nov 2021 21:00:22 +1100 Subject: [PATCH 2/7] Add protection list, deprotect-all; update readme --- README.md | 12 ++++++++++++ region_file_updater/__init__.py | 23 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1277f90..ad7269b 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,20 @@ A MCDR plugin to help you update region files in game `!!region delete-all` 删除所有区域文件 / delete all region files +`!!region protect` 将玩家所在位置的区域文件设为保护状态 / protect the region file where the player is in + +`!!region protect` 保护指定的区域文件 / protect a specific region file + +`!!region deprotect` 取消保护玩家所在位置的区域文件 / deprotect the region file where the player is in + +`!!region deprotect` 取消保护指定的区域文件 / deprotect a specific region file + +`!!region deprotect-all` 取消保护所有的区域文件 / deprotect all region files + `!!region list` 列出待更新的区域文件 / list all added region files +`!!region list-protect` 列出受保护的区域文件 / list all protected region files + `!!region history` 输出上一次update的结果 / print the result of the latest update `!!region update` 更新列表中的区域文件,这将重启服务器 / update all selected region files, which will restart the server diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index 8b2aa30..7fddea6 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -35,8 +35,12 @@ class Config(Serializable): §7{0} del §6[d] [x] [z] [d] §r删除指定的区域文件 §7{0} del-all §r删除所有区域文件 §7{0} protect §r将玩家所在位置的区域文件设为保护状态 +§7{0} protect §6[x] [z] [d] §r保护指定的区域文件 §7{0} deprotect §r取消保护玩家所在位置的区域文件 +§7{0} deprotect §6[x] [z] [d] §r取消保护指定的区域文件 +§7{0} deprotect-all §r取消保护所有的区域文件 §7{0} list §r列出待更新的区域文件 +§7{0} list-protect §r列出受保护的区域文件 §7{0} history §r输出上一次update的结果 §7{0} update §r更新列表中的区域文件,这将重启服务器 §7{0} reload §r重新载入配置文件 @@ -112,7 +116,7 @@ def clean_region_list(source): def protect_region(source: CommandSource, region: Region): if region in protectedRegionList: source.reply('该区域文件已设保护') - if region in regionList: + elif region in regionList: regionList.remove(region) protectedRegionList.append(region) source.reply('区域文件§6{}§r已从列表移除并设保护'.format(region)) @@ -128,6 +132,12 @@ def deprotect_region(source: CommandSource, region: Region): else: source.reply('该区域文件未被保护') + +def deprotect_all_regions(source): + protectedRegionList.clear() + source.reply('所有受保护区域文件已去保护') + + def get_region_from_source(source: PlayerCommandSource) -> Region: api = source.get_server().get_plugin_instance('minecraft_data_api') coord = api.get_player_coordinate(source.player) @@ -150,6 +160,7 @@ def delete_region_from_player(source: CommandSource): else: source.reply('该指令仅支持玩家执行') + @new_thread(PLUGIN_METADATA.name) def protect_region_from_player(source: CommandSource): if isinstance(source, PlayerCommandSource): @@ -157,6 +168,7 @@ def protect_region_from_player(source: CommandSource): else: source.reply('该指令仅支持玩家执行') + @new_thread(PLUGIN_METADATA.name) def deprotect_region_from_player(source: CommandSource): if isinstance(source, PlayerCommandSource): @@ -164,6 +176,7 @@ def deprotect_region_from_player(source: CommandSource): else: source.reply('该指令仅支持玩家执行') + def show_region_list(source: CommandSource): source.reply('更新列表中共有{}个待更新的区域文件'.format(len(regionList))) for region in regionList: @@ -177,6 +190,12 @@ def show_history(source: CommandSource): source.reply('§6{}§r: {}'.format(region, msg[flag])) +def show_protected_regions(source: CommandSource): + source.reply('已保护区域列表中共有{}个受保护的区域文件'.format(len(protectedRegionList))) + for region in protectedRegionList: + source.reply('- §6{}§r'.format(region)) + + @new_thread(PLUGIN_METADATA.name) def region_update(source: CommandSource): show_region_list(source) @@ -261,7 +280,9 @@ def get_region_parm_node(callback): then( Literal('deprotect').runs(deprotect_region_from_player). then(get_region_parm_node(lambda src, ctx: deprotect_region(src, Region(ctx['x'], ctx['z'], ctx['dim']))))). + then(Literal('deprotect-all').runs(deprotect_all_regions)). then(Literal('list').runs(show_region_list)). + then(Literal('list-protect').runs(show_protected_regions)). then(Literal('history').runs(show_history)). then( Literal('update'). From dab57bca4542745af8d9977d225ebc9117d5b30a Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Sun, 7 Nov 2021 21:25:58 +1100 Subject: [PATCH 3/7] bump version to 1.6.0 --- mcdreforged.plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcdreforged.plugin.json b/mcdreforged.plugin.json index ccfc7f3..36839a2 100644 --- a/mcdreforged.plugin.json +++ b/mcdreforged.plugin.json @@ -1,6 +1,6 @@ { "id": "region_file_updater", - "version": "1.5.0", + "version": "1.6.0", "name": "Region file Updater", "description": { "en_us": "A MCDR plugin to help you update region files in game", From 0b17788ffa01352fa23ee4a36428b00919e16b7a Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Mon, 8 Nov 2021 02:15:13 +1100 Subject: [PATCH 4/7] fix not loading previous protected list on load --- region_file_updater/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index 7fddea6..d4ceaca 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -233,9 +233,10 @@ def region_update(source: CommandSource): def on_load(server: PluginServerInterface, old): try: - global historyList, regionList + global historyList, regionList, protectedRegionList historyList = old.historyList regionList = old.regionList + protectedRegionList = old.protectedRegionList except AttributeError: pass From 5d62f970f8c8c8c3b526f8a85ecf20f28be51593 Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Tue, 9 Nov 2021 08:40:18 +1100 Subject: [PATCH 5/7] save protected region list to file (No testing yet --- region_file_updater/__init__.py | 63 ++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index d4ceaca..0591f8a 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -2,11 +2,13 @@ import os import shutil import time +import json from typing import Dict, Iterable, List, Tuple, Optional, Union from mcdreforged.api.all import * PLUGIN_METADATA = ServerInterface.get_instance().as_plugin_server_interface().get_self_metadata() +PROTECTED_REGION_FILE_NAME = 'protected-regions.json' class Config(Serializable): @@ -50,12 +52,12 @@ class Config(Serializable): '''.strip().format(Prefix, PLUGIN_METADATA.name, PLUGIN_METADATA.version) regionList = [] # type: List[Region] -protectedRegionList = [] # type: List[Region] +protectedRegionList = [] # type: List[Region] historyList = [] # type: List[Tuple[Region, bool]] server_inst: PluginServerInterface -class Region: +class Region(Serializable): def __init__(self, x: int, z: int, dim: int): self.x = x self.z = z @@ -88,7 +90,8 @@ def __repr__(self): def print_log(server: ServerInterface, msg: str): server.logger.info(msg) with open(LogFilePath, 'a') as logfile: - logfile.write(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + ': ' + msg + '\n') + logfile.write(time.strftime('%Y-%m-%d %H:%M:%S', + time.localtime(time.time())) + ': ' + msg + '\n') def add_region(source: CommandSource, region: Region): @@ -100,6 +103,7 @@ def add_region(source: CommandSource, region: Region): else: source.reply('该区域已设保护') + def delete_region(source: CommandSource, region: Region): if region not in regionList: source.reply('列表中不存在该区域文件') @@ -120,15 +124,18 @@ def protect_region(source: CommandSource, region: Region): regionList.remove(region) protectedRegionList.append(region) source.reply('区域文件§6{}§r已从列表移除并设保护'.format(region)) + save_protected_region_file() else: protectedRegionList.append(region) source.reply('区域文件§6{}§r已设保护'.format(region)) + save_protected_region_file() def deprotect_region(source: CommandSource, region: Region): if region in protectedRegionList: protectedRegionList.remove(region) source.reply('区域文件§6{}§r已取消保护'.format(region)) + save_protected_region_file() else: source.reply('该区域文件未被保护') @@ -136,6 +143,29 @@ def deprotect_region(source: CommandSource, region: Region): def deprotect_all_regions(source): protectedRegionList.clear() source.reply('所有受保护区域文件已去保护') + save_protected_region_file() + + +def save_protected_region_file(): + file_path = os.path.join( + config.destination_world_directory, PROTECTED_REGION_FILE_NAME) + with open(file_path, 'w', encoding='utf8') as file: + json.dump(serialize(protectedRegionList), file) + + +def load_protected_region_file(): + global protectedRegionList + file_path = os.path.join( + config.destination_world_directory, PROTECTED_REGION_FILE_NAME) + if os.path.isfile(file_path): + with open(file_path, 'r', encoding='utf8') as file: + try: + data = json.load(file) + protectedRegionList = deserialize(data, List[Region]) + except Exception as e: + server_inst.logger.error( + 'Fail to load protected regions from {}: {}'.format(file_path, e)) + protectedRegionList = [] def get_region_from_source(source: PlayerCommandSource) -> Region: @@ -200,20 +230,25 @@ def show_protected_regions(source: CommandSource): def region_update(source: CommandSource): show_region_list(source) countdown = 5 - source.reply('[{}]: {}秒后重启服务器更新列表中的区域文件'.format(PluginName, countdown), isBroadcast=True) + source.reply('[{}]: {}秒后重启服务器更新列表中的区域文件'.format( + PluginName, countdown), isBroadcast=True) for i in range(1, countdown): - source.reply('[{}]: 还有{}秒'.format(PluginName, countdown - i), isBroadcast=True) + source.reply('[{}]: 还有{}秒'.format( + PluginName, countdown - i), isBroadcast=True) time.sleep(1) source.get_server().stop() source.get_server().wait_for_start() - print_log(source.get_server(), '{} 更新了 {} 个区域文件:'.format(source, len(regionList))) + print_log(source.get_server(), '{} 更新了 {} 个区域文件:'.format( + source, len(regionList))) historyList.clear() for region in regionList: for region_file in region.to_file_list(): - source_dir = os.path.join(config.source_world_directory, region_file) - destination = os.path.join(config.destination_world_directory, region_file) + source_dir = os.path.join( + config.source_world_directory, region_file) + destination = os.path.join( + config.destination_world_directory, region_file) try: source.get_server().logger.info('- "{}" -> "{}"'.format(source_dir, destination)) shutil.copyfile(source_dir, destination) @@ -249,8 +284,10 @@ def on_load(server: PluginServerInterface, old): def load_config(source: Optional[CommandSource]): global config, server_inst - config_file_path = os.path.join('config', '{}.json'.format(PLUGIN_METADATA.id)) - config = server_inst.load_config_simple(config_file_path, in_data_folder=False, source_to_reply=source, echo_in_console=False, target_class=Config) + config_file_path = os.path.join( + 'config', '{}.json'.format(PLUGIN_METADATA.id)) + config = server_inst.load_config_simple( + config_file_path, in_data_folder=False, source_to_reply=source, echo_in_console=False, target_class=Config) def reload_config(source: CommandSource): @@ -268,11 +305,13 @@ def get_region_parm_node(callback): on_error(UnknownArgument, lambda src: src.reply('参数错误!请输入§7{}§r以获取插件帮助'.format(Prefix)), handled=True). then( Literal('add').runs(add_region_from_player). - then(get_region_parm_node(lambda src, ctx: add_region(src, Region(ctx['x'], ctx['z'], ctx['dim'])))) + then(get_region_parm_node(lambda src, ctx: add_region( + src, Region(ctx['x'], ctx['z'], ctx['dim'])))) ). then( Literal('del').runs(delete_region_from_player). - then(get_region_parm_node(lambda src, ctx: delete_region(src, Region(ctx['x'], ctx['z'], ctx['dim'])))) + then(get_region_parm_node(lambda src, ctx: delete_region( + src, Region(ctx['x'], ctx['z'], ctx['dim'])))) ). then(Literal('del-all').runs(clean_region_list)). then( From b7215af472ccca1ac66945771e851d6931dab787 Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Tue, 9 Nov 2021 11:16:19 +1100 Subject: [PATCH 6/7] fix --- region_file_updater/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index 0591f8a..732daf9 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -160,13 +160,14 @@ def load_protected_region_file(): if os.path.isfile(file_path): with open(file_path, 'r', encoding='utf8') as file: try: - data = json.load(file) - protectedRegionList = deserialize(data, List[Region]) + protected_list_data = json.load(file) except Exception as e: server_inst.logger.error( 'Fail to load protected regions from {}: {}'.format(file_path, e)) protectedRegionList = [] - + else: + for r in protected_list_data: + protectedRegionList.append(Region(r['x'], r['z'], r['dim'])) def get_region_from_source(source: PlayerCommandSource) -> Region: api = source.get_server().get_plugin_instance('minecraft_data_api') @@ -271,13 +272,13 @@ def on_load(server: PluginServerInterface, old): global historyList, regionList, protectedRegionList historyList = old.historyList regionList = old.regionList - protectedRegionList = old.protectedRegionList except AttributeError: pass global server_inst server_inst = server load_config(None) + load_protected_region_file() register_commands(server) server.register_help_message(Prefix, '从指定存档处更新region文件至本服') From cd2b747abf6e4f668733d05e40b528c798697795 Mon Sep 17 00:00:00 2001 From: Track07-cda Date: Tue, 9 Nov 2021 11:33:03 +1100 Subject: [PATCH 7/7] move protected file name to config --- region_file_updater/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/region_file_updater/__init__.py b/region_file_updater/__init__.py index 732daf9..1d77c87 100644 --- a/region_file_updater/__init__.py +++ b/region_file_updater/__init__.py @@ -1,20 +1,19 @@ # -*- coding: utf-8 -*- +import json import os import shutil import time -import json from typing import Dict, Iterable, List, Tuple, Optional, Union from mcdreforged.api.all import * PLUGIN_METADATA = ServerInterface.get_instance().as_plugin_server_interface().get_self_metadata() -PROTECTED_REGION_FILE_NAME = 'protected-regions.json' - class Config(Serializable): enabled: bool = True, source_world_directory: str = './qb_multi/slot1/world' destination_world_directory: str = './server/world' + protected_region_file_name = 'protected-regions.json' dimension_region_folder: Dict[str, Union[str, List[str]]] = { '-1': 'DIM-1/region', '0': 'region', @@ -148,7 +147,7 @@ def deprotect_all_regions(source): def save_protected_region_file(): file_path = os.path.join( - config.destination_world_directory, PROTECTED_REGION_FILE_NAME) + config.destination_world_directory, config.protected_region_file_name) with open(file_path, 'w', encoding='utf8') as file: json.dump(serialize(protectedRegionList), file) @@ -156,7 +155,7 @@ def save_protected_region_file(): def load_protected_region_file(): global protectedRegionList file_path = os.path.join( - config.destination_world_directory, PROTECTED_REGION_FILE_NAME) + config.destination_world_directory, config.protected_region_file_name) if os.path.isfile(file_path): with open(file_path, 'r', encoding='utf8') as file: try: @@ -165,9 +164,12 @@ def load_protected_region_file(): server_inst.logger.error( 'Fail to load protected regions from {}: {}'.format(file_path, e)) protectedRegionList = [] + save_protected_region_file() else: for r in protected_list_data: - protectedRegionList.append(Region(r['x'], r['z'], r['dim'])) + protectedRegionList.append( + Region(r['x'], r['z'], r['dim'])) + def get_region_from_source(source: PlayerCommandSource) -> Region: api = source.get_server().get_plugin_instance('minecraft_data_api')