Skip to content

Instantly share code, notes, and snippets.

@Zhou-Shilin
Last active October 20, 2024 06:21
Show Gist options
  • Save Zhou-Shilin/0addcd199db0d946829791eaa83a19a3 to your computer and use it in GitHub Desktop.
Save Zhou-Shilin/0addcd199db0d946829791eaa83a19a3 to your computer and use it in GitHub Desktop.
BaimoRegionManager

BaimoRegionManager

删几个区块,不想专门在Linux服务器上下载MCA Selector等地图编辑器?使用这个简单的Python脚本完成错误区块的删除和回溯!

BaimoRegionManager 是一款轻量化的 Minecraft 服务器地图块管理工具,专为管理区块文件的删除与回溯而设计。通过结合 SimpleBackup 提供的备份压缩包,它可以有效地删除、备份以及从备份中恢复特定区域的 MCA 文件。该工具非常适合在 Minecraft 服务器中对区域进行细粒度的管理与修复。

更新日志

  • 10/20/2024: 修复了回溯文件名错误为“w”的问题,并进行了一些小的优化和清理,以提高可读性和效率。现在choose_backup函数会返回完整的备份文件名和其加载状态,这样在mainrestore_mca_file函数中,我们可以直接使用返回的完整备份文件名。

功能

  • 备份回溯:从 SimpleBackup 生成的备份压缩包中,回溯并恢复指定区域的 MCA 文件。
  • 区块与方块坐标支持:用户可选择使用区块坐标或方块坐标进行操作。
  • 自动安装依赖:程序会自动安装所需的第三方库,无需手动配置。
  • 用户选择操作:通过交互式菜单,用户可以选择是删除区块还是从备份中回溯。
  • 备份状态显示:显示备份列表,并标明每个备份是否包含所需的 MCA 文件。

使用方法

1. 环境准备

确保你已经在服务器环境中安装了 Python 3.7 或更高版本。

2. 运行程序

  1. baimoregionmanager.py 文件放置在 Minecraft 服务器根目录中,该目录结构应包含 world/region 文件夹以及 SimpleBackup 的 simplebackups 文件夹。
  2. 打开终端(Linux)或命令提示符(Windows),进入程序目录并执行以下命令:
python BaimoRegionManager.py
  1. 功能选项 输入类型:程序会提示选择方块坐标或区块坐标。选择后,输入对应的坐标。 删除还是回溯:程序会询问是否要删除文件(将其重命名为 .bak),还是从备份中恢复。 备份选择:在回溯操作中,程序会展示所有备份,并标注该备份中是否包含指定的 MCA 文件。如果备份中没有所需文件,程序将继续执行删除操作。
  2. 示例流程 输入坐标后,程序会自动查找对应的 MCA 文件。 若文件存在,首先进行备份,然后询问是否删除或回溯。 如果选择回溯,程序会检查备份文件夹中的所有压缩包,判断其中是否包含所需的 MCA 文件,并根据用户选择进行恢复或删除操作。

依赖

BaimoRegionManager 依赖以下 Python 库:

- rich
- InquirerPy

若未安装,程序会自动安装这些库,无需手动干预。

作者

  • BaimoQilin - me.baimoqilin.top

  • Hypiworld 机械动力服务器 QQ群号:640159882

import os
import shutil
import zipfile
from datetime import datetime
# 尝试导入第三方库,若未安装则自动安装
try:
from rich.console import Console
from rich.table import Table
except ImportError:
os.system("pip install rich")
from rich.console import Console
from rich.table import Table
try:
from InquirerPy import inquirer
except ImportError:
os.system("pip install InquirerPy")
from InquirerPy import inquirer
console = Console()
def get_mca_file(x, z, is_chunk=False):
# 计算区块坐标,如果是方块坐标,需转换
if not is_chunk:
chunk_x = x // 16
chunk_z = z // 16
else:
chunk_x = x
chunk_z = z
# 计算地图块坐标
region_x = chunk_x // 32
region_z = chunk_z // 32
# 返回 MCA 文件名和路径
mca_file = f"r.{region_x}.{region_z}.mca"
path = os.path.join("world", "region", mca_file)
return mca_file, path
def backup_mca_file(mca_file, path):
# 备份文件:将其重命名为 .bak
bak_file = f"{mca_file}.bak"
bak_path = os.path.join("world", "region", bak_file)
shutil.move(path, bak_path)
console.print(f"[green]已备份文件为: {bak_file}[/green]")
return bak_path
def list_backups(backup_dir="simplebackups"):
# 获取备份文件夹中的所有zip文件
backups = [f for f in os.listdir(backup_dir) if f.endswith(".zip")]
backups.sort()
return backups
def check_backup_contains_mca(backup_zip, mca_file):
# 检查备份文件中是否含有指定mca文件
with zipfile.ZipFile(os.path.join("simplebackups", backup_zip), 'r') as zip_ref:
return f"world/region/{mca_file}" in zip_ref.namelist()
def choose_backup(backups, mca_file):
# 展示备份时间及是否含有指定mca文件
table = Table(title="可用备份列表")
table.add_column("编号", justify="center")
table.add_column("备份时间", justify="center")
table.add_column("状态", justify="center")
backup_status = []
for idx, backup in enumerate(backups):
# 获取备份时间戳
timestamp_str = backup.split("_")[1] + "_" + backup.split("_")[2].replace(".zip", "")
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d_%H-%M-%S")
formatted_date = timestamp.strftime("%Y年%m月%d日 %H:%M:%S")
# 检查备份中是否包含 .mca 文件
contains_mca = check_backup_contains_mca(backup, mca_file)
status = "[green]已加载[/green]" if contains_mca else "[red]未加载[/red]"
# 显示编号、时间和状态
table.add_row(str(idx), formatted_date, status)
backup_status.append((backup, contains_mca)) # 保存备份文件和加载状态
console.print(table)
# 为用户选择提供带编号、时间和状态的选项
choices = [f"{idx}. {datetime.strptime(backup.split('_')[1] + '_' + backup.split('_')[2].replace('.zip', ''), '%Y-%m-%d_%H-%M-%S').strftime('%Y年%m月%d日 %H:%M:%S')} [{status}]"
for idx, (backup, contains_mca) in enumerate(backup_status)]
# 用户选择备份
choice = inquirer.select(
message="请选择要回溯的备份编号:",
choices=choices
).execute()
selected_index = int(choice.split('.')[0]) # 提取用户选择的编号
return backups[selected_index], backup_status[selected_index][1] # 返回所选的备份文件名及其状态
def restore_mca_file(backup_zip, mca_file):
# 从备份zip中解压出指定的mca文件
with zipfile.ZipFile(os.path.join("simplebackups", backup_zip), 'r') as zip_ref:
file_to_extract = f"world/region/{mca_file}"
zip_ref.extract(file_to_extract, ".")
console.print(f"[green]已从备份恢复文件: {mca_file}[/green]")
def display_welcome_message():
console.print("[bold blue]欢迎使用BaimoRegionManager.py,一款专为Minecraft服务器设计的轻量化区块删除/回溯器。[/bold blue]")
console.print("[bold cyan]适配SimpleBackup提供回溯功能。[/bold cyan]")
console.print("[bold yellow]了解作者:https://me.baimoqilin.top/[/bold yellow]")
console.print("[bold magenta]广告位招租联系[email protected][/bold magenta]")
console.print("[bold green]Hypiworld机械动力服务器 QQ群号640159882[/bold green]")
def main():
# 显示欢迎信息
display_welcome_message()
# 选择输入方块坐标或区块坐标
coord_type = inquirer.select(
message="请选择输入类型:",
choices=["方块坐标", "区块坐标"],
).execute()
if coord_type == "方块坐标":
x = int(inquirer.text(message="请输入X坐标").execute())
z = int(inquirer.text(message="请输入Z坐标").execute())
mca_file, path = get_mca_file(x, z, is_chunk=False)
else:
chunk_x = int(inquirer.text(message="请输入区块X坐标").execute())
chunk_z = int(inquirer.text(message="请输入区块Z坐标").execute())
mca_file, path = get_mca_file(chunk_x, chunk_z, is_chunk=True)
if not os.path.exists(path):
console.print(f"[red]MCA文件不存在: {path}[/red]")
return
# 备份文件
bak_path = backup_mca_file(mca_file, path)
# 询问用户是否删除或回溯
action = inquirer.select(
message="是否要删除文件(重命名为.bak),还是从备份中回溯?",
choices=["删除", "回溯"],
).execute()
if action == "删除":
console.print("[bold red]已将文件重命名为.bak,删除成功。[/bold red]")
return
# 获取备份列表
backups = list_backups()
if not backups:
console.print("[red]没有可用的备份[/red]")
return
# 选择要回溯的备份
selected_backup, is_loaded = choose_backup(backups, mca_file)
# 如果备份未加载,进行删除操作
if not is_loaded:
console.print("[bold red]备份中未找到对应的mca文件,执行删除操作。[/bold red]")
return
# 从备份中恢复文件
restore_mca_file(selected_backup, mca_file)
# 提示用户重启服务器
console.print("[bold green]文件已成功恢复,重启服务器以使更改生效。[/bold green]")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment