Compare commits
4 Commits
0458ee469b
...
4fec47201e
Author | SHA1 | Date | |
---|---|---|---|
4fec47201e | |||
6d8389ce19 | |||
8e361691bc | |||
c48532121d |
2
LICENSE
2
LICENSE
@ -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…
Reference in New Issue
Block a user