Merge pull request 'Fix STag Filtering & README improvement & Update Supported Extensions' (#28) from xhacker-zzz/web:master into master

Reviewed-on: https://git.unlock-music.dev/um/web/pulls/28
Reviewed-by: jixunmoe <jixunmoe@noreply.unlock-music.dev>
Reviewed-by: Unlock Music Dev <dev@unlock-music.dev>
remotes/origin/HEAD
Unlock Music Dev 2 years ago
commit 0b4444d0d2

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2019-2022 MengYX Copyright (c) 2019-2023 MengYX
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

@ -27,6 +27,7 @@
- [x] 酷我音乐格式 (.kwm) - [x] 酷我音乐格式 (.kwm)
- [x] 酷狗音乐格式 (.kgm/.vpr) - [x] 酷狗音乐格式 (.kgm/.vpr)
- [x] Android版喜马拉雅文件格式 (.x2m/.x3m) - [x] Android版喜马拉雅文件格式 (.x2m/.x3m)
- [x] 咪咕音乐格式 (.mg3d)
### 其他特性 ### 其他特性
@ -35,7 +36,7 @@
- [x] 批量解锁 - [x] 批量解锁
- [x] 渐进式 Web 应用 (PWA) - [x] 渐进式 Web 应用 (PWA)
- [x] 多线程 - [x] 多线程
- [x] 写入元信息与专辑封面 - [x] 写入和编辑元信息与专辑封面
## 使用方法 ## 使用方法

@ -131,6 +131,10 @@ public:
int PreDecode(std::string ext) { int PreDecode(std::string ext) {
cipherType = checkType(ext); cipherType = checkType(ext);
size_t tailSize = 0; size_t tailSize = 0;
if (cipherType == "invalid" || cipherType == "STag") {
error = "file is invalid or not supported (Please downgrade your app).";
return -1;
}
if (cipherType == "QTag") { if (cipherType == "QTag") {
tailSize = 8; tailSize = 8;
} }
@ -156,10 +160,6 @@ public:
} }
rawKeyBuf = tmp; rawKeyBuf = tmp;
} }
if (cipherType == "invalid") {
error = "file is invalid or not supported(Please downgrade your app.)";
return -1;
}
return keySize + tailSize; return keySize + tailSize;
} }

@ -50,9 +50,12 @@ export async function Decrypt(file: FileInfo, config: Record<string, any>): Prom
case 'tm3': // QQ Music IOS Mp3 case 'tm3': // QQ Music IOS Mp3
rt_data = await RawDecrypt(file.raw, raw.name, 'mp3'); rt_data = await RawDecrypt(file.raw, raw.name, 'mp3');
break; break;
case 'qmc0': //QQ Music Android Mp3
case 'qmc3': //QQ Music Android Mp3 case 'qmc3': //QQ Music Android Mp3
case 'qmc2': //QQ Music Android Ogg case 'qmc2': //QQ Music Android Ogg
case 'qmc0': //QQ Music Android Mp3 case 'qmc4': //QQ Music Android Ogg
case 'qmc6': //QQ Music Android Ogg
case 'qmc8': //QQ Music Android Ogg
case 'qmcflac': //QQ Music Android Flac case 'qmcflac': //QQ Music Android Flac
case 'qmcogg': //QQ Music Android Ogg case 'qmcogg': //QQ Music Android Ogg
case 'tkm': //QQ Music Accompaniment M4a case 'tkm': //QQ Music Accompaniment M4a
@ -68,6 +71,7 @@ export async function Decrypt(file: FileInfo, config: Record<string, any>): Prom
case 'mggl': //QQ Music Mac case 'mggl': //QQ Music Mac
case 'mflac': //QQ Music New Flac case 'mflac': //QQ Music New Flac
case 'mflac0': //QQ Music New Flac case 'mflac0': //QQ Music New Flac
case 'mflach': //QQ Music New Flac
case 'mgg': //QQ Music New Ogg case 'mgg': //QQ Music New Ogg
case 'mgg1': //QQ Music New Ogg case 'mgg1': //QQ Music New Ogg
case 'mgg0': case 'mgg0':
@ -98,6 +102,8 @@ export async function Decrypt(file: FileInfo, config: Record<string, any>): Prom
case 'x3m': case 'x3m':
rt_data = await XimalayaDecrypt(file.raw, raw.name, raw.ext); rt_data = await XimalayaDecrypt(file.raw, raw.name, raw.ext);
break; break;
case 'mflach': //QQ Music New Flac
throw '网页版无法解锁,请使用<a target="_blank" href="https://git.unlock-music.dev/um/cli">CLI版本</a>'
default: default:
throw '不支持此文件格式'; throw '不支持此文件格式';
} }

@ -28,8 +28,16 @@ export const HandlerMap: { [key: string]: Handler } = {
qmc0: { ext: 'mp3', version: 2 }, qmc0: { ext: 'mp3', version: 2 },
qmc2: { ext: 'ogg', version: 2 }, qmc2: { ext: 'ogg', version: 2 },
qmc3: { ext: 'mp3', version: 2 }, qmc3: { ext: 'mp3', version: 2 },
qmc4: { ext: 'ogg', version: 2 },
qmc6: { ext: 'ogg', version: 2 },
qmc8: { ext: 'ogg', version: 2 },
bkcmp3: { ext: 'mp3', version: 1 }, bkcmp3: { ext: 'mp3', version: 1 },
bkcm4a: { ext: 'm4a', version: 1 },
bkcflac: { ext: 'flac', version: 1 }, bkcflac: { ext: 'flac', version: 1 },
bkcwav: { ext: 'wav', version: 1 },
bkcape: { ext: 'ape', version: 1 },
bkcogg: { ext: 'ogg', version: 1 },
bkcwma: { ext: 'wma', version: 1 },
tkm: { ext: 'm4a', version: 1 }, tkm: { ext: 'm4a', version: 1 },
'666c6163': { ext: 'flac', version: 1 }, '666c6163': { ext: 'flac', version: 1 },
'6d7033': { ext: 'mp3', version: 1 }, '6d7033': { ext: 'mp3', version: 1 },
@ -131,7 +139,9 @@ export class QmcDecoder {
private searchKey() { private searchKey() {
const last4Byte = this.file.slice(-4); const last4Byte = this.file.slice(-4);
const textEnc = new TextDecoder(); const textEnc = new TextDecoder();
if (textEnc.decode(last4Byte) === 'QTag') { if (textEnc.decode(last4Byte) === 'STag') {
throw new Error('文件中没有写入密钥无法解锁请降级App并重试');
} else if (textEnc.decode(last4Byte) === 'QTag') {
const sizeBuf = this.file.slice(-8, -4); const sizeBuf = this.file.slice(-8, -4);
const sizeView = new DataView(sizeBuf.buffer, sizeBuf.byteOffset); const sizeView = new DataView(sizeBuf.buffer, sizeBuf.byteOffset);
const keySize = sizeView.getUint32(0, false); const keySize = sizeView.getUint32(0, false);

Loading…
Cancel
Save