level 1
import json
import base64
import zipfile
import io
import os
import sys
import re
def sanitize_filename(name):
return re.sub(r'[<>:"/\\|?*]', '_', name).strip()
def extract_song_name(xm_content):
try:
signature = b'Extended Module: '
offset = xm_content.find(signature)
if offset != -1:
name_bytes = xm_content[offset+17 : offset+17+20]
name = name_bytes.decode('ascii', errors='ignore').strip()
if name:
return name
header_segment = xm_content[:256]
strings = re.findall(b'[ -~]{3,}', header_segment)
decoded_strings = []
for s in strings:
try:
decoded = s.decode('ascii').strip()
decoded_strings.append(decoded)
except:
pass
ignore_list = ['[author]', '[link]', 'Extended Module:']
candidates = []
for s in decoded_strings:
is_ignored = False
for ign in ignore_list:
if ign in s:
is_ignored = True
break
if not is_ignored:
candidates.append(s)
if candidates:
return candidates[0]
except Exception as e:
print(f"警告: 提取歌曲名称时出错: {e}")
return "未知"
def process_file(file_path):
if not file_path.lower().endswith('.json'):
return
print(f"正在处理: {file_path}")
try:
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
track_blob = None
if 'tt' in data and isinstance(data['tt'], list):
for item in data['tt']:
if item.get('type') == 'XM_MUSIC_TRACK':
d_obj = item.get('d', {})
if 'track' in d_obj:
track_blob = d_obj['track']
break
if not track_blob:
print(f" X 已跳过: 在 {os.path.basename(file_path)} 中未找到 XM_MUSIC_TRACK")
return
try:
zip_content = base64.b64decode(track_blob)
except Exception as e:
print(f" X Base64解码错误: {e}")
return
xm_data = None
try:
with zipfile.ZipFile(io.BytesIO(zip_content)) as z:
target_file = 'module'
if target_file not in z.namelist():
if z.namelist():
target_file = z.namelist()[0]
else:
print(" X 错误: 压缩包为空")
return
xm_data = z.read(target_file)
except Exception as e:
print(f" X 解压错误: {e}")
return
if not xm_data:
return
song_name = extract_song_name(xm_data)
base_name = os.path.splitext(os.path.basename(file_path))[0]
safe_song_name = sanitize_filename(song_name)
output_filename = f"{base_name}-{safe_song_name}.xm"
output_path = os.path.join(os.path.dirname(file_path), output_filename)
with open(output_path, 'wb') as out_f:
out_f.write(xm_data)
print(f" V 已提取: {output_filename}")
except Exception as e:
print(f" X 处理文件时出错: {e}")
def process_input(path_str):
path_str = path_str.strip('"').strip("'")
if os.path.isfile(path_str):
process_file(path_str)
elif os.path.isdir(path_str):
print(f"正在扫描目录: {path_str}")
for root, dirs, files in os.walk(path_str):
for file in files:
if file.lower().endswith('.json'):
full_path = os.path.join(root, file)
process_file(full_path)
else:
print(f"无效路径: {path_str}")
def main():
print("Infinitode2 BGM提取\n---------------------------")
if len(sys.argv) > 1:
for arg in sys.argv[1:]:
process_input(arg)
else:
while True:
try:
user_input = input("\n请输入文件或文件夹路径 (输入 q 退出): ").strip()
if user_input.lower() == 'q':
break
if not user_input:
continue
process_input(user_input)
except KeyboardInterrupt:
break
print("\n处理完成。")
if __name__ == "__main__":
main()
2026年02月04日 10点02分
2
level 1
aW1wb3J0IGpzb24KaW1wb3J0IGJhc2U2NAppbXBvcnQgemlwZmlsZQppbXBvcnQgaW8KaW1wb3J0IG9zCmltcG9ydCBzeXMKaW1wb3J0IHJlCgpkZWYgc2FuaXRpemVfZmlsZW5hbWUobmFtZSk6CiAgICByZXR1cm4gcmUuc3ViKHInWzw+OiIvXFx8PypdJywgJ18nLCBuYW1lKS5zdHJpcCgpCgpkZWYgZXh0cmFjdF9zb25nX25hbWUoeG1fY29udGVudCk6CiAgICB0cnk6CiAgICAgICAgc2lnbmF0dXJlID0gYidFeHRlbmRlZCBNb2R1bGU6ICcKICAgICAgICBvZmZzZXQgPSB4bV9jb250ZW50LmZpbmQoc2lnbmF0dXJlKQogICAgICAgIGlmIG9mZnNldCAhPSAtMToKICAgICAgICAgICAgbmFtZV9ieXRlcyA9IHhtX2NvbnRlbnRbb2Zmc2V0KzE3IDogb2Zmc2V0KzE3KzIwXQogICAgICAgICAgICBuYW1lID0gbmFtZV9ieXRlcy5kZWNvZGUoJ2FzY2lpJywgZXJyb3JzPSdpZ25vcmUnKS5zdHJpcCgpCiAgICAgICAgICAgIGlmIG5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZQoKICAgICAgICBoZWFkZXJfc2VnbWVudCA9IHhtX2NvbnRlbnRbOjI1Nl0KICAgICAgICBzdHJpbmdzID0gcmUuZmluZGFsbChiJ1sgLX5dezMsfScsIGhlYWRlcl9zZWdtZW50KQogICAgICAgIAogICAgICAgIGRlY29kZWRfc3RyaW5ncyA9IFtdCiAgICAgICAgZm9yIHMgaW4gc3RyaW5nczoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZGVjb2RlZCA9IHMuZGVjb2RlKCdhc2NpaScpLnN0cmlwKCkKICAgICAgICAgICAgICAgIGRlY29kZWRfc3RyaW5ncy5hcHBlbmQoZGVjb2RlZCkKICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgCiAgICAgICAgaWdub3JlX2xpc3QgPSBbJ1thdXRob3JdJywgJ1tsaW5rXScsICdFeHRlbmRlZCBNb2R1bGU6J10KICAgICAgICAKICAgICAgICBjYW5kaWRhdGVzID0gW10KICAgICAgICBmb3IgcyBpbiBkZWNvZGVkX3N0cmluZ3M6CiAgICAgICAgICAgIG
lz
X2lnbm9yZWQgPSBGYWxzZQogICAgICAgICAgICBmb3IgaWduIGluIGlnbm9yZV9saXN0OgogICAgICAgICAgICAgICAgaWYgaWduIGluIHM6CiAgICAgICAgICAgICAgICAgICAgaXNfaWdub3JlZCA9IFRydWUKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBub3QgaXNfaWdub3JlZDoKICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMuYXBwZW5kKHMpCiAgICAgICAgCiAgICAgICAgaWYgY2FuZGlkYXRlczoKICAgICAgICAgICAgcmV0dXJuIGNhbmRpZGF0ZXNbMF0KICAgICAgICAgICAgCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiLorablkYo6IOaPkOWPluatjOabsuWQjeensOaXtuWHuumUmToge2V9IikKICAgICAgICAKICAgIHJldHVybiAi5pyq55+lIgoKZGVmIHByb2Nlc3NfZmlsZShmaWxlX3BhdGgpOgogICAgaWYgbm90IGZpbGVfcGF0aC5sb3dlcigpLmVuZHN3aXRoKCcuanNvbicpOgogICAgICAgIHJldHVybgoKICAgIHByaW50KGYi5q2j5Zyo5aSE55CGOiB7ZmlsZV9wYXRofSIpCiAgICAKICAgIHRyeToKICAgICAgICB3aXRoIG9wZW4oZmlsZV9wYXRoLCAncicsIGVuY29kaW5nPSd1dGYtOCcpIGFzIGY6CiAgICAgICAgICAgIGRhdGEgPSBqc29uLmxvYWQoZikKICAgICAgICAKICAgICAgICB0cmFja19ibG9iID0gTm9uZQogICAgICAgIAogICAgICAgIGlmICd0dCcgaW4gZGF0YSBhbmQgaXNpbnN0YW5jZShkYXRhWyd0dCddLCBsaXN0KToKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gZGF0YVsndHQnXToKICAgICAgICAgICAgICAgIGlmIGl0ZW0uZ2V0KCd0eXBlJykgPT0gJ1hNX01VU0lDX1RSQUNLJzoKICAgICAgICAgICAgICAgICAgICBkX29iaiA9IGl0ZW0uZ2V0KCdkJywge30pCiAgICAgICAgICAgICAgICAgICAgaWYgJ3RyYWNrJyBpbiBkX29iajoKICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tfYmxvYiA9IGRfb2JqWyd0cmFjayddCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgCiAgICAgICAgaWYgbm90IHRyYWNrX2Jsb2I6CiAgICAgICAgICAgIHByaW50KGYiICBYIOW3sui3s+i/hzog5ZyoIHtvcy5wYXRoLmJhc2VuYW1lKGZpbGVfcGF0aCl9IOS4reacquaJvuWIsCBYTV9NVVNJQ19UUkFDSyIpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHppcF9jb250ZW50ID0gYmFzZTY0LmI2NGRlY29kZSh0cmFja19ibG9iKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgcHJpbnQoZiIgIFggQmFzZTY06Kej56CB6ZSZ6K+vOiB7ZX0iKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgeG1fZGF0YSA9IE5vbmUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHdpdGggemlwZmlsZS5aaXBGaWxlKGlvLkJ5dGVzSU8oemlwX2NvbnRlbnQpKSBhcyB6OgogICAgICAgICAgICAgICAgdGFyZ2V0X2ZpbGUgPSAnbW9kdWxlJwogICAgICAgICAgICAgICAgaWYgdGFyZ2V0X2ZpbGUgbm90IGluIHoubmFtZWxpc3QoKToKICAgICAgICAgICAgICAgICAgICBpZiB6Lm5hbWVsaXN0KCk6CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF9maWxlID0gei5uYW1lbGlzdCgpWzBdCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiAgWCDplJnor686IOWOi+e8qeWMheS4uuepuiIpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHhtX2RhdGEgPSB6LnJlYWQodGFyZ2V0X2ZpbGUpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBwcmludChmIiAgWCDop6PljovplJnor686IHtlfSIpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBub3QgeG1fZGF0YToKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNvbmdfbmFtZSA9IGV4dHJhY3Rfc29uZ19uYW1lKHhtX2RhdGEpCiAgICAgICAgCiAgICAgICAgYmFzZV9uYW1lID0gb3MucGF0aC5zcGxpdGV4dChvcy5wYXRoLmJhc2VuYW1lKGZpbGVfcGF0aCkpWzBdCiAgICAgICAgc2FmZV9zb25nX25hbWUgPSBzYW5pdGl6ZV9maWxlbmFtZShzb25nX25hbWUpCiAgICAgICAgb3V0cHV0X2ZpbGVuYW1lID0gZiJ7YmFzZV9uYW1lfS17c2FmZV9zb25nX25hbWV9LnhtIgogICAgICAgIG91dHB1dF9wYXRoID0gb3MucGF0aC5qb2luKG9zLnBhdGguZGlybmFtZShmaWxlX3BhdGgpLCBvdXRwdXRfZmlsZW5hbWUpCiAgICAgICAgCiAgICAgICAgd2l0aCBvcGVuKG91dHB1dF9wYXRoLCAnd2InKSBhcyBvdXRfZjoKICAgICAgICAgICAgb3V0X2Yud3JpdGUoeG1fZGF0YSkKICAgICAgICAgICAgCiAgICAgICAgcHJpbnQoZiIgViDlt7Lmj5Dlj5Y6IHtvdXRwdXRfZmlsZW5hbWV9IikKCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiIgIFgg5aSE55CG5paH5Lu25pe25Ye66ZSZOiB7ZX0iKQoKZGVmIHByb2Nlc3NfaW5wdXQocGF0aF9zdHIpOgogICAgcGF0aF9zdHIgPSBwYXRoX3N0ci5zdHJpcCgnIicpLnN0cmlwKCInIikKICAgIAogICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aF9zdHIpOgogICAgICAgIHByb2Nlc3NfZmlsZShwYXRoX3N0cikKICAgIGVsaWYgb3MucGF0aC5pc2RpcihwYXRoX3N0cik6CiAgICAgICAgcHJpbnQoZiLmraPlnKjmiavmj4/nm67lvZU6IHtwYXRoX3N0cn0iKQogICAgICAgIGZvciByb290LCBkaXJzLCBmaWxlcyBpbiBvcy53YWxrKHBhdGhfc3RyKToKICAgICAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgICAgICBpZiBmaWxlLmxvd2VyKCkuZW5kc3dpdGgoJy5qc29uJyk6CiAgICAgICAgICAgICAgICAgICAgZnVsbF9wYXRoID0gb3MucGF0aC5qb2luKHJvb3QsIGZpbGUpCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc19maWxlKGZ1bGxfcGF0aCkKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoZiLml6DmlYjot6/lvoQ6IHtwYXRoX3N0cn0iKQoKZGVmIG1haW4oKToKICAgIHByaW50KCJJbmZpbml0b2RlMiBCR03mj5Dlj5Zcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpCiAgICAKICAgIGlmIGxlbihzeXMuYXJndikgPiAxOgogICAgICAgIGZvciBhcmcgaW4gc3lzLmFyZ3ZbMTpdOgogICAgICAgICAgICBwcm9jZXNzX2lucHV0KGFyZykKICAgIGVsc2U6CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdXNlcl9pbnB1dCA9IGlucHV0KCJcbuivt+i+k+WFpeaWh+S7tuaIluaWh+S7tuWkuei3r+W+hCAo6L6T5YWlIHEg6YCA5Ye6KTogIikuc3RyaXAoKQogICAgICAgICAgICAgICAgaWYgdXNlcl9pbnB1dC5sb3dlcigpID09ICdxJzoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgbm90IHVzZXJfaW5wdXQ6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHByb2Nlc3NfaW5wdXQodXNlcl9pbnB1dCkKICAgICAgICAgICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgICAgICAgICAgYnJlYWsKICAgIAogICAgcHJpbnQoIlxu5aSE55CG5a6M5oiQ44CCIikKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCk=
2026年02月04日 10点02分
6