This commit is contained in:
手瓜一十雪 2024-04-25 20:40:32 +08:00
parent 59565f7d90
commit 16d8d04aaa
3 changed files with 1 additions and 236 deletions

View File

@ -59,7 +59,6 @@
"silk-wasm": "^3.3.4",
"sqlite3": "^5.1.7",
"uuid": "^9.0.1",
"ws": "^8.16.0",
"yaml": "^2.4.1"
"ws": "^8.16.0"
}
}

View File

@ -1,208 +0,0 @@
import path from 'node:path';
import fs from 'node:fs';
import * as log4js from 'log4js';
import * as YAML from 'yaml';
import qrcode from 'qrcode-terminal';
import { NapCatCore, napCatCore } from '@/core';
import { NapCatOnebot11 } from '@/onebot11/main';
import PackageInfo from '@/../package.json';
import { INapCatConfig } from './types';
import { RawMessage } from '@/core/qqnt/entities';
const DefaultNapCatConfig: INapCatConfig = {
account: {
uin: '10086',
password: 'password',
noQuickLogin: false,
},
heartbeat: {
interval: 5,
},
adapters: {
onebot: {
address: '0.0.0.0',
port: 8123,
accessToken: 'token123456',
}
},
log: {
level: 'info',
},
};
function getLog4jConfig(logLevel = 'info', writeFile = false): log4js.Configuration {
const outputMethod = [ 'console' ];
if (writeFile) outputMethod.push('file');
const defaultCategory = {
appenders: outputMethod,
level: logLevel,
};
return {
appenders: {
console: {
type: 'stdout'
},
file: {
type: 'file',
},
ascii: {
type: 'stdout',
layout: {
type: 'pattern',
pattern: '%[%m%]',
},
},
asciiNoColor: {
type: 'stdout',
layout: {
type: 'pattern',
pattern: '%m',
},
},
},
categories: {
default: defaultCategory,
ascii: {
appenders: [ 'ascii' ],
level: 'info',
},
asciiNoColor: {
appenders: [ 'asciiNoColor' ],
level: 'info',
}
},
};
}
export class NapCat {
readonly dataPath: string;
readonly config: INapCatConfig;
readonly core: NapCatCore;
readonly onebot: NapCatOnebot11;
readonly log: log4js.Logger;
readonly logMsg: log4js.Logger;
constructor() {
// Get data path (usually the same path of NapCat)
this.dataPath = path.resolve(__dirname, './');
// Init core
this.core = napCatCore;
this.onebot = new NapCatOnebot11();
// Get user config
if (!fs.existsSync(path.resolve(this.dataPath, './config.yml'))) { // Detect if no config file exist
// Use default logger
log4js.configure(getLog4jConfig('all'));
this.log = log4js.getLogger('App');
this.logMsg = log4js.getLogger('Message');
this.drawBootAscii();
this.config = DefaultNapCatConfig;
fs.writeFileSync(path.resolve(this.dataPath, './config.yml'), YAML.stringify(DefaultNapCatConfig));
this.log.error('未找到配置文件!');
this.log.error('已为您创建了默认配置文件,请关闭 NapCatQQ 后填写配置文件再启动');
this.log.error('完整的配置文件详解可前往 [DOC_URL] 查看');
return;
}
this.config = YAML.parse(fs.readFileSync(path.resolve(this.dataPath, './config.yml'), { encoding: 'utf8' }));
// Apply log4j config before use it
log4js.configure(getLog4jConfig('all'));
// log4js.configure(getLog4jConfig(this.config.log.level));
this.log = log4js.getLogger('App');
this.logMsg = log4js.getLogger('Message');
this.drawBootAscii();
// Init app
this.initApp();
}
// Output ASCII because i love it
private drawBootAscii() {
const logAscii = log4js.getLogger('ascii');
[
'',
' _ _ _____ _ ____ ____',
' | \\ | | / ____| | | / __ \\ / __ \\',
' | \\| | __ _ _ __ | | __ _ | |_ | | | || | | |',
' | . ` | / _` || \'_ \\ | | / _` || __|| | | || | | |',
' | |\\ || (_| || |_) || |____ | (_| || |_ | |__| || |__| |',
' |_| \\_| \\__,_|| .__/ \\_____| \\__,_| \\__| \\___\\_\\ \\___\\_\\',
' | |',
' |_| ',
].forEach(i => {
logAscii.info(i);
});
logAscii.info(`---------------------< NapCatQQ v${PackageInfo.version} >---------------------`);
}
private initApp() {
this.core.on('system.login.qrcode', ({ url }: { url: string }) => {
this.log.info('请扫描下面的二维码然后在手Q上授权登录');
const ascii = log4js.getLogger('asciiNoColor');
qrcode.generate(url, { small: true }, (res) => {
ascii.info(res);
});
});
this.core.on('system.login.slider', ({ url }: { url: string }) => {
this.log.info('登录需要验证,请访问下面的滑块验证链接,然后按下回车:');
const ascii = log4js.getLogger('asciiNoColor');
ascii.info(url);
});
this.core.on('system.online', () => {
this.onLoginSuccess();
});
this.core.on('system.login.error', ({ code, message }: { code: string, message: string }) => {
this.log.error(`登录出现问题(${code}`);
this.log.error(message);
});
if (!this.config.account || !this.config.account.uin) {
this.log.info('未读取到账号配置,终止初始化...');
return;
}
this.log.info(`正在尝试登录账号 ${this.config.account.uin} ...`);
if (this.config.account.password) this.core.login.password(this.config.account.uin, this.config.account.password);
else if (!this.config.account.noQuickLogin) this.core.login.quick(this.config.account.uin);
else this.core.login.qrcode();
}
private onLoginSuccess() {
this.log.info('登录成功');
this.core.on('message.private', (e) => {
this.logMsg.info(`[Private] ${e.peerName}(${e.senderUin}) -> ${msgElementParser(e)}`);
});
this.core.on('message.group', (e) => {
this.logMsg.info(`[Group] ${e.peerName}(${e.peerUin}) - ${e.sendMemberName ? e.sendMemberName : e.sendNickName}(${e.senderUin}) -> ${msgElementParser(e)}`);
});
}
}
const msgElementParser = (msg: RawMessage) => {
let result = '';
for (const element of msg.elements) {
if (element.textElement) {
if (element.textElement.atType === 0) result += element.textElement.content;
else result += `[@${element.textElement.atType === 2 ? element.textElement.atUid : 'all'}]`;
}
if (element.picElement) result += `[Pic=${element.picElement.fileName}]`;
if (element.pttElement) result += '[Voice]';
if (element.faceElement) result += `[Face=${element.faceElement.faceIndex}]`;
if (element.videoElement) result += `[Video=${element.videoElement.fileName}]`;
if (element.fileElement) result += `[File=${element.fileElement.fileName}]`;
if (element.marketFaceElement) result += `[MarketFace=${element.marketFaceElement.faceName}]`;
}
return result;
};

View File

@ -1,26 +0,0 @@
export interface INapCatConfig {
account: INapCatConfigAccount,
heartbeat: INapCatConfigHeartbeat,
adapters: Record<string, INapCatConfigAdapterBase>,
log: INapCatConfigLog,
}
export interface INapCatConfigAccount {
uin: string,
password?: string,
noQuickLogin?: boolean,
}
export interface INapCatConfigHeartbeat {
interval: number,
}
export interface INapCatConfigLog {
level: string,
}
export interface INapCatConfigAdapterBase {
address: string,
port: number,
accessToken?: string,
}