feat: add kgm support

This commit is contained in:
鲁树人 2024-09-16 22:13:27 +01:00
parent a75ca7aabb
commit 7fef8da083
5 changed files with 47 additions and 10 deletions

View File

@ -24,7 +24,7 @@
"@emotion/styled": "^11.11.0",
"@reduxjs/toolkit": "^2.0.1",
"@um/libparakeet": "0.4.5",
"@unlock-music/crypto": "0.0.0-alpha.11",
"@unlock-music/crypto": "0.0.0-alpha.12",
"framer-motion": "^10.16.16",
"nanoid": "^5.0.4",
"radash": "^11.0.0",

View File

@ -42,8 +42,8 @@ importers:
specifier: 0.4.5
version: 0.4.5
'@unlock-music/crypto':
specifier: 0.0.0-alpha.11
version: 0.0.0-alpha.11
specifier: 0.0.0-alpha.12
version: 0.0.0-alpha.12
framer-motion:
specifier: ^10.16.16
version: 10.16.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@ -1927,8 +1927,8 @@ packages:
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
'@unlock-music/crypto@0.0.0-alpha.11':
resolution: {integrity: sha512-lA3xryziHULhkPbuQFI2HrfwDREUD9YoaZOTMQqcu/8mKF2/hA3sCK0Uoq0miYr+7VUbE5sMBvl9dcrnCI1UWA==, tarball: https://git.unlock-music.dev/api/packages/um/npm/%40unlock-music%2Fcrypto/-/0.0.0-alpha.11/crypto-0.0.0-alpha.11.tgz}
'@unlock-music/crypto@0.0.0-alpha.12':
resolution: {integrity: sha512-Q24cq653CmD8sj/D1M6wHYtXJIX3YIgnvbPtO+aHnY07J0ZXvkqNh+6a3hBrGGLYzcSWioAw2xxf2rFEQ3q35A==, tarball: https://git.unlock-music.dev/api/packages/um/npm/%40unlock-music%2Fcrypto/-/0.0.0-alpha.12/crypto-0.0.0-alpha.12.tgz}
'@vitejs/plugin-react@4.2.1':
resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==}
@ -6118,7 +6118,7 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
'@unlock-music/crypto@0.0.0-alpha.11': {}
'@unlock-music/crypto@0.0.0-alpha.12': {}
'@vitejs/plugin-react@4.2.1(vite@5.0.10(@types/node@20.10.5)(sass@1.69.5)(terser@5.27.0))':
dependencies:

View File

@ -3,6 +3,7 @@ import { TransparentDecipher } from './decipher/Transparent.ts';
import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts';
import { QQMusicV1Decipher, QQMusicV2Decipher } from '~/decrypt-worker/decipher/QQMusic.ts';
import { KuwoMusicDecipher } from '~/decrypt-worker/decipher/KuwoMusic.ts';
import { KugouMusicDecipher } from '~/decrypt-worker/decipher/KugouMusic.ts';
export enum Status {
OK = 0,
@ -40,7 +41,7 @@ export const allCryptoFactories: DecipherFactory[] = [
NetEaseCloudMusicDecipher.make,
// KGM (*.kgm, *.vpr)
// KGMCrypto.make,
KugouMusicDecipher.make,
// KWMv1 (*.kwm)
KuwoMusicDecipher.make,

View File

@ -0,0 +1,36 @@
import { DecipherInstance, DecipherOK, DecipherResult, Status } from '~/decrypt-worker/Deciphers';
import { KuGouDecipher, KuGouHeader } from '@unlock-music/crypto';
import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts';
import { chunkBuffer } from '~/decrypt-worker/util/buffer.ts';
export class KugouMusicDecipher implements DecipherInstance {
cipherName = 'Kugou';
async decrypt(buffer: Uint8Array, _options: DecryptCommandOptions): Promise<DecipherResult | DecipherOK> {
let kgm: KuGouDecipher | undefined;
let header: KuGouHeader | undefined;
try {
header = KuGouHeader.parse(buffer.subarray(0, 0x400));
kgm = new KuGouDecipher(header);
const audioBuffer = new Uint8Array(buffer.subarray(0x400));
for (const [block, offset] of chunkBuffer(audioBuffer)) {
kgm.decrypt(block, offset);
}
return {
status: Status.OK,
cipherName: this.cipherName,
data: audioBuffer,
};
} finally {
kgm?.free();
header?.free();
}
}
public static make() {
return new KugouMusicDecipher();
}
}

View File

@ -1,5 +1,5 @@
import { DecipherInstance, DecipherOK, DecipherResult, Status } from '~/decrypt-worker/Deciphers';
import { KuwoHeader, KWMCipher } from '@unlock-music/crypto';
import { KuwoHeader, KWMDecipher } from '@unlock-music/crypto';
import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts';
import { chunkBuffer } from '~/decrypt-worker/util/buffer.ts';
@ -8,11 +8,11 @@ export class KuwoMusicDecipher implements DecipherInstance {
async decrypt(buffer: Uint8Array, options: DecryptCommandOptions): Promise<DecipherResult | DecipherOK> {
let header: KuwoHeader | undefined;
let kwm: KWMCipher | undefined;
let kwm: KWMDecipher | undefined;
try {
header = KuwoHeader.parse(buffer.subarray(0, 0x400));
kwm = header.makeCipher(options.kwm2key);
kwm = new KWMDecipher(header, options.kwm2key);
const audioBuffer = new Uint8Array(buffer.subarray(0x400));
for (const [block, offset] of chunkBuffer(audioBuffer)) {