海盜王客戶端的紋理貼圖bmp文件有些是加密,很多人想解密并修改替換,現在給出解密的python代碼:
import os
import struct
import copy
from pathlib import Pathclass TexEncode:def __init__(self):self.MAGIC_BYTES = b'mp.x' # 魔法字節標識符def _decode0(self, data):"""基礎解密操作:交換數據前后部分"""i = 44 # 固定交換長度s = len(data)if s > i:# 保存前i字節tmp = data[:i]# 交換:前i字節替換為后i字節data[:i] = data[s-i:s]# 后i字節替換為之前保存的前i字節data[s-i:s] = tmpreturn datadef _decode1(self, data):"""帶標識的解密"""# 檢查是否已加密(末尾是否有魔法字節)if len(data) < 4 or data[-4:] != self.MAGIC_BYTES:return None # 未加密或數據不完整# 移除魔法字節標識data = data[:-4]# 執行基礎解密data = self._decode0(data)return datadef decode(self, data):"""對外接口:解密"""return self._decode1(data)def is_encrypted_bmp(file_path):"""檢查文件是否為加密的BMP圖片"""try:# 檢查文件擴展名if file_path.suffix.lower() not in ['.bmp']:return False# 讀取文件末尾檢查魔法字節with open(file_path, 'rb') as f:f.seek(-4, 2) # 定位到文件末尾4字節magic_bytes = f.read(4)return magic_bytes == b'mp.x'except:return Falsedef process_file(file_path, encoder):"""處理單個文件"""try:# 讀取文件數據with open(file_path, 'rb') as f:data = bytearray(f.read())print(f"正在處理: {file_path}")# 嘗試解密decrypted_data = encoder.decode(data)if decrypted_data is not None:# 解密成功,寫回原文件with open(file_path, 'wb') as f:f.write(decrypted_data)print(f"? 成功解密并替換: {file_path}")return Trueelse:print(f" 文件未加密或解密失敗: {file_path}")return Falseexcept Exception as e:print(f"? 處理文件時出錯 {file_path}: {str(e)}")return Falsedef traverse_and_decrypt(root_folder):"""遍歷文件夾,查找并解密加密的BMP圖片"""root_path = Path(root_folder)encoder = TexEncode()if not root_path.exists():print(f"錯誤: 文件夾不存在 - {root_folder}")returnprocessed_count = 0decrypted_count = 0print(f"開始遍歷文件夾: {root_folder}")print("=" * 50)# 遍歷所有文件for file_path in root_path.rglob('*'):if file_path.is_file():processed_count += 1# 檢查是否為加密的BMP文件if is_encrypted_bmp(file_path):if process_file(file_path, encoder):decrypted_count += 1print("=" * 50)print(f"處理完成!")print(f"總共檢查文件數: {processed_count}")print(f"成功解密文件數: {decrypted_count}")def main():# 指定要處理的文件夾路徑folder_path = input("請輸入要處理的文件夾路徑: ").strip()if not folder_path:# 默認使用當前目錄folder_path = "."try:traverse_and_decrypt(folder_path)except KeyboardInterrupt:print("\n用戶中斷操作")except Exception as e:print(f"程序執行出錯: {str(e)}")# 批量處理多個文件夾的版本
def batch_process_folders(folder_list):"""批量處理多個文件夾"""encoder = TexEncode()for folder_path in folder_list:print(f"\n處理文件夾: {folder_path}")print("-" * 30)traverse_and_decrypt(folder_path)# 安全版本:備份原文件后再處理
def safe_traverse_and_decrypt(root_folder, backup_suffix=".encrypted"):"""安全版本:先備份再處理"""root_path = Path(root_folder)encoder = TexEncode()if not root_path.exists():print(f"錯誤: 文件夾不存在 - {root_folder}")returnprocessed_count = 0decrypted_count = 0print(f"開始安全遍歷文件夾: {root_folder}")print("=" * 50)# 遍歷所有文件for file_path in root_path.rglob('*'):if file_path.is_file():processed_count += 1# 檢查是否為加密的BMP文件if is_encrypted_bmp(file_path):try:# 創建備份backup_path = file_path.with_suffix(file_path.suffix + backup_suffix)if not backup_path.exists():file_path.rename(backup_path)print(f"已創建備份: {backup_path}")# 從備份文件讀取并解密with open(backup_path, 'rb') as f:data = bytearray(f.read())decrypted_data = encoder.decode(data)if decrypted_data is not None:# 寫入解密后的文件到原位置with open(file_path, 'wb') as f:f.write(decrypted_data)print(f"? 成功解密: {file_path}")decrypted_count += 1else:print(f" 解密失敗,恢復原文件: {file_path}")backup_path.rename(file_path) # 恢復原文件except Exception as e:print(f"? 處理文件時出錯 {file_path}: {str(e)}")print("=" * 50)print(f"安全處理完成!")print(f"總共檢查文件數: {processed_count}")print(f"成功解密文件數: {decrypted_count}")if __name__ == "__main__":# 運行主程序# main()# 或者使用安全版本safe_traverse_and_decrypt("E:/HDW2/hdw-2022-64/Client64/bin/texture2")# 或者批量處理# batch_process_folders(["./folder1", "./folder2", "./folder3"])
運行這段代碼后,會將指定文件夾下的所有bmp文件解密,就可以用ps等編輯更換了。