Files
mirror_server/scripts/migrate_mc_structure.py
T

137 lines
4.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MC核心目录结构迁移脚本
将旧结构迁移到新结构:
旧: MCServerCore/{core}/{major}/{file.jar}
新: MCServerCore/{core}/{major}/{version}/{file.jar}
版本号提取规则:
- paper-1.20.1-6550.jar -> 1.20.1
- spongeneo-1.21.2-21.2.0-beta-13.0.0-RC1868-universal.jar -> 1.21.2
- spongevanilla-1.20.6-11.0.1-RC1916-universal.jar -> 1.20.6
"""
import os
import re
import shutil
from pathlib import Path
def extract_version(filename, core_name):
"""
从文件名中提取版本号
例如: spongevanilla-1.20.6-11.0.1-RC1916-universal.jar -> 1.20.6
例如: craftbukkit-1.9.jar -> 1.9
例如: spongevanilla-1.17-9.0.0-RC668-universal.jar -> 1.17
"""
# 去掉 .jar 后缀
name_without_jar = filename[:-4] if filename.endswith('.jar') else filename
# 模式:核心名-版本号-其他
# 版本号格式:数字.数字 或 数字.数字.数字 (如 1.9, 1.20.6, 1.21.2)
pattern = rf'^{re.escape(core_name)}-(\d+\.\d+(?:\.\d+)?)'
match = re.match(pattern, name_without_jar)
if match:
return match.group(1)
return None
def migrate_mc_structure(base_dir='./downloads/MCServerCore'):
"""迁移MC核心目录结构"""
mc_dir = Path(base_dir)
if not mc_dir.exists():
print(f"目录不存在: {mc_dir}")
return
migrated_count = 0
skipped_count = 0
errors = []
for jar_file in mc_dir.rglob('*.jar'):
try:
relative = jar_file.relative_to(mc_dir)
parts = relative.parts
except ValueError:
continue
# 格式: core/major/file.jar 或 core/major/version/file.jar
if len(parts) >= 3:
core_name = parts[0]
major = parts[1]
# 如果已经是新结构(len >= 4),跳过
if len(parts) >= 4:
print(f" 已在正确位置: {relative}")
continue
# 旧结构:core/major/file.jar
# 提取版本号
version = extract_version(jar_file.name, core_name)
if not version:
print(f" 无法提取版本号: {relative}")
skipped_count += 1
continue
# 构建新路径: core/major/version/file.jar
new_version_dir = jar_file.parent / version
new_path = new_version_dir / jar_file.name
# 如果目标目录已存在同名文件
if new_path.exists():
print(f" 目标已存在,跳过: {relative}")
skipped_count += 1
continue
try:
new_version_dir.mkdir(parents=True, exist_ok=True)
shutil.move(str(jar_file), str(new_path))
print(f" 移动: {relative} -> {new_path.relative_to(mc_dir)}")
migrated_count += 1
except Exception as e:
errors.append(f"移动失败 {relative}: {e}")
else:
print(f" 跳过(未知结构): {relative}")
skipped_count += 1
# 尝试清理空的目录
cleaned_dirs = 0
for dir_path in sorted(mc_dir.rglob('*'), reverse=True):
if dir_path.is_dir():
try:
if not any(dir_path.iterdir()):
dir_path.rmdir()
cleaned_dirs += 1
except OSError:
pass
print(f"\n迁移完成!")
print(f" 移动文件: {migrated_count}")
print(f" 跳过文件: {skipped_count}")
print(f" 清理空目录: {cleaned_dirs}")
if errors:
print(f"\n错误:")
for e in errors[:10]:
print(f" {e}")
if __name__ == '__main__':
import sys
base_dir = sys.argv[1] if len(sys.argv) > 1 else './downloads/MCServerCore'
print("=" * 60)
print("MC核心目录结构迁移工具")
print("旧结构: MCServerCore/{core}/{major}/{file.jar}")
print("新结构: MCServerCore/{core}/{major}/{version}/{file.jar}")
print("=" * 60)
print(f"基础目录: {base_dir}")
print()
migrate_mc_structure(base_dir)