extract_player.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python3
  2. """
  3. Minecraft 基岩版角色提取工具
  4. 输入: .mcworld 文件
  5. 输出: 角色数据文件 (.dat)
  6. """
  7. import os
  8. import sys
  9. import zipfile
  10. import tempfile
  11. import shutil
  12. from datetime import datetime
  13. def extract_player(mcworld_path, output_dir="output"):
  14. """从 .mcworld 文件提取角色数据"""
  15. if not os.path.exists(mcworld_path):
  16. print(f"错误: 文件不存在 - {mcworld_path}")
  17. return None
  18. if not mcworld_path.endswith('.mcworld'):
  19. print("错误: 请提供 .mcworld 文件")
  20. return None
  21. # 创建输出目录
  22. os.makedirs(output_dir, exist_ok=True)
  23. # 获取世界名称
  24. world_name = os.path.splitext(os.path.basename(mcworld_path))[0]
  25. # 创建临时目录解压
  26. temp_dir = tempfile.mkdtemp()
  27. try:
  28. print(f"正在解压: {mcworld_path}")
  29. with zipfile.ZipFile(mcworld_path, 'r') as zip_ref:
  30. zip_ref.extractall(temp_dir)
  31. # 查找 db 目录
  32. db_path = os.path.join(temp_dir, 'db')
  33. if not os.path.exists(db_path):
  34. # 可能在子目录里
  35. for root, dirs, files in os.walk(temp_dir):
  36. if 'db' in dirs:
  37. db_path = os.path.join(root, 'db')
  38. break
  39. if not os.path.exists(db_path):
  40. print("错误: 找不到 db 目录")
  41. return None
  42. print(f"找到数据库: {db_path}")
  43. # 打开 LevelDB
  44. import leveldb
  45. db = leveldb.LevelDB(db_path)
  46. # 提取玩家数据
  47. player_data = db.get(b'~local_player')
  48. if not player_data:
  49. print("错误: 找不到本地玩家数据")
  50. return None
  51. # 保存到输出目录
  52. timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
  53. output_file = os.path.join(output_dir, f"{world_name}_{timestamp}.dat")
  54. with open(output_file, 'wb') as f:
  55. f.write(player_data)
  56. print(f"\n✓ 提取成功!")
  57. print(f" 世界名称: {world_name}")
  58. print(f" 数据大小: {len(player_data)} bytes")
  59. print(f" 输出文件: {output_file}")
  60. del db
  61. return output_file
  62. finally:
  63. # 清理临时目录
  64. shutil.rmtree(temp_dir, ignore_errors=True)
  65. def main():
  66. if len(sys.argv) < 2:
  67. print("""
  68. Minecraft 基岩版角色提取工具
  69. ============================
  70. 用法:
  71. python extract_player.py <.mcworld文件> [输出目录]
  72. 示例:
  73. python extract_player.py "World.mcworld"
  74. python extract_player.py "World.mcworld" ./output
  75. 输出:
  76. 角色数据文件 (.dat),可导入到其他存档
  77. """)
  78. return
  79. mcworld_path = sys.argv[1]
  80. output_dir = sys.argv[2] if len(sys.argv) > 2 else "output"
  81. extract_player(mcworld_path, output_dir)
  82. if __name__ == '__main__':
  83. main()