Skip to content

Commit

Permalink
feat: 多账户支持
Browse files Browse the repository at this point in the history
  • Loading branch information
msojocs committed Oct 30, 2024
1 parent 64484a9 commit 4946535
Show file tree
Hide file tree
Showing 15 changed files with 4,153 additions and 203 deletions.
2,249 changes: 2,093 additions & 156 deletions docs/function.md

Large diffs are not rendered by default.

1,937 changes: 1,937 additions & 0 deletions docs/functions/func.log

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/common/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ interface LoggerConfigType {
*/
type InterceptorFuncType = (config: LoggerConfigType) => void

const isLogEnabled = process.env['YUKIHANA_LOG'] === 'true'
const isLogEnabled = process.env['YUI_LOG'] === 'true'

if (!isLogEnabled) {
_console.info('================================日志打印已关闭!=======================================')
Expand Down
4 changes: 0 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useLogger } from "./common/log"
import { hook } from "./hook";
import { initNative } from "./native/init";
import { NTInitialize } from "./ntqq";
import { initOnebot } from "./onebot/onebot";
import { startServer } from "./server";
Expand All @@ -26,9 +25,6 @@ try {
log.info('hookWrapper')
hookWrapper()
}

log.info('initNTQQ')
// initNative()

log.info('initOnebot')
initOnebot()
Expand Down
24 changes: 18 additions & 6 deletions src/native/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useConfigStore } from '../store/config'
import { useLogger } from '../common/log'

const log = useLogger('NativeInit')
export const initNative = () => {
export const initNative = (name: string) => {
// 获取函数签名
const { getSignature } = useConfigStore()
const sig = getSignature()
Expand All @@ -23,9 +23,21 @@ export const initNative = () => {
sigData.hosts = sigArr
}
}
setTimeout(() => {
log.info('install:', sigData)
const result = install(sigData)
log.info('install result:', result)
}, 2000)
if (sig?.msf_task) {
const signature = sig?.msf_task
const sigArr = signature?.match(/[a-zA-Z0-9]{2}/g)?.map(e=>parseInt(`0x${e}`))
if (sigArr !== undefined) {
sigData.msf = sigArr
}
}
if (sig?.msf_resp) {
const signature = sig?.msf_resp
const sigArr = signature?.match(/[a-zA-Z0-9]{2}/g)?.map(e=>parseInt(`0x${e}`))
if (sigArr !== undefined) {
sigData.msf_resp = sigArr
}
}
log.info('install:', sigData)
const result = install(name, sigData)
log.info('install result:', result)
}
12 changes: 5 additions & 7 deletions src/ntqq/core/service/nt-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import { useNTUserStore } from "../../store/user"
import { useLogger } from "../../../common/log";
import EventEmitter from "events";
import { CustomError } from "../../../server/error/custom-error";
import { initNative } from "../../../native/init";

const log = useLogger('NTWrapper')
const wrapper = useWrapper(1)
const loginService = new wrapper.NodeIKernelLoginService()
const wrapperSession = new wrapper.NodeIQQNTWrapperSession()
const wrapperEngine = new wrapper.NodeIQQNTWrapperEngine()
export const useNTWrapper = () => {
// QQ号索引处理
const asyncStore = useAsyncStore()
Expand All @@ -34,10 +31,11 @@ export const useNTWrapper = () => {
userNick: ""
},
dispatcher: new EventEmitter(),
loginService,
wrapperSession,
wrapperEngine,
loginService: new wrapper.NodeIKernelLoginService(),
wrapperSession: new wrapper.NodeIQQNTWrapperSession(),
wrapperEngine: new wrapper.NodeIQQNTWrapperEngine(),
}
initNative(`wrapper-${idx}.node`)
}
return useWrapper(userStore[uin].moduleIndex)
}
5 changes: 4 additions & 1 deletion src/ntqq/types/native.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ declare namespace YuiNativeWrapper {
*
* @param signature 函数签名
*/
const install: (signature: SignatureType) => Record<string, boolean>
const install: (name: string, signature: SignatureType) => Record<string, boolean>
/**
* 添加消息
*/
const addMsg: (msg: AddMsgType) => boolean
const test: () => boolean
}
interface SignatureType {
sqlite3_stmt?: number[]
hosts?: number[]
msf?: number[]
msf_resp?: number[]
}
interface AddMsgType {
msgId: `${number}`
Expand Down
13 changes: 12 additions & 1 deletion src/ntqq/types/wrapper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,24 @@ declare namespace NTNativeWrapper {
vendorType: 0
}

interface SSOFilter {
ssoRetCode: number
trpcRetCode: number
trpcFuncCode: number
errorMsg: string
pbBuffer: string
rpcMap: {
entries: () => void
next: () => void
}
}
class NodeIQQNTWrapperEngine {
constructor()
getDeviceInfo(): any
getECDHService(): import('./services/NodeIKernelECDHService').NodeIKernelECDHService
initWithDeskTopConfig(config: NodeIQQNTWrapperEngineType.Init, adapter: import("./adapters/NodeIGlobalAdapter").NodeIGlobalAdapter): boolean
initWithMobileConfig(config: NodeIQQNTWrapperEngineType.Init, adapter: import("./adapters/NodeIGlobalAdapter").NodeIGlobalAdapter): boolean
// onSendSSOReply(cb: NodeISendECDHRequestCallback): void
onSendSSOReply(a: number, a2: number, a3: number, a4: number, a5: SSOFilter): void
}

// #endregion
Expand Down
9 changes: 7 additions & 2 deletions src/onebot/event/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ const onRecvMsg = () => {
// 频道消息暂不处理
if (msg.chatType === 4) continue

const senderUserInfo = await getUserInfoByUid(msg.senderUid)
let uin: number = 0
if (msg.senderUid)
{
const senderUserInfo = await getUserInfoByUid(msg.senderUid)
uin = parseInt(senderUserInfo.uin)
}
const ret: EventDataType<BotMessageData> = {
self: {
id: parseInt(user.uin),
Expand All @@ -46,7 +51,7 @@ const onRecvMsg = () => {
messageSeq: msg.msgSeq,
groupId: 0,
groupName: '',
senderId: parseInt(senderUserInfo.uin),
senderId: uin,
senderUid: msg.senderUid,
senderMemberName: msg.sendMemberName,
time: parseInt(msg.msgTime),
Expand Down
2 changes: 2 additions & 0 deletions src/store/config-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ export interface YuiConfig {
export interface SingatureInfo {
sqlite3_stmt: string
get_ip_by_domain: string
msf_task: string
msf_resp: string
}
21 changes: 11 additions & 10 deletions src/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,23 @@ import vm from 'vm'
import v8 from 'v8'
import events from 'events'
import { app } from 'electron'
import { test as ttt} from 'yui-native'


const { registerActionHandle } = useStore()
const log = useLogger('Test')

const testSendMsg = async (p: any): Promise<BotActionResponse<any>> => {
const testSendMsg = async (p: any): Promise<any> => {
log.info('testSendMsg')
const { getWrapperEngine } = useNTCore()
const engine = getWrapperEngine()
const ecdh = engine.getECDHService()
// ecdh.sendSSORequest()
const resp: BotActionResponse = {
id: "",
status: "ok",
retcode: 0,
data: {},
message: ""
}
return Promise.resolve(resp)

log.info('test:', p)
const ret = await (ecdh as any)[p.method](...p.args)
// if (p.test)
// ttt()
return ret
}

class ScriptHook extends Script{
Expand Down Expand Up @@ -271,6 +269,7 @@ import async_hooks from 'node:async_hooks';
import { stdout } from 'node:process';
import { useNTCore } from "../ntqq/core/core"
import { DESTRUCTION } from "dns"
import { useNTWrapper } from "../ntqq/core/service/nt-wrapper"
const hookAsync = () => {
const { fd } = stdout;

Expand Down Expand Up @@ -465,5 +464,7 @@ export const test = (m: NodeModule) => {
log.error('error:', err)
process.exit(1)
}
const wrapper = useNTCore()
// wrapper.getWrapperEngine().onSendSSOReply
registerActionHandle('test', testSendMsg)
}
12 changes: 6 additions & 6 deletions tools/dev.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ const ActionHandle = {
stdio: 'inherit',
env: {
...process.env,
YUKIHANA_LOG: true,
YUI_LOG: true,
// ELECTRON_RUN_AS_NODE: '1',
// ELECTRON_ATTACH_CONSOLE: '1',
YUKIHANA_ACTION: 'ui',
YUKIHANA_NATIVE: "D:/GitHub/Yui-native/build/nt_native.node",
YUI_ACTION: 'ui',
YUI_NATIVE: "D:/GitHub/Yui-native/build/nt_native.node",
QQV8BytecodeDebug: '1'
},
cwd: path.resolve(__dirname, '../program'),
Expand All @@ -153,11 +153,11 @@ const ActionHandle = {
stdio: 'inherit',
env: {
...process.env,
YUKIHANA_LOG: true,
YUI_LOG: true,
// ELECTRON_RUN_AS_NODE: true,
YUKIHANA_ACTION: 'dev',
YUI_ACTION: 'dev',
ELECTRON_ATTACH_CONSOLE: '1',
YUKIHANA_NATIVE: "D:/GitHub/Yui-native/build/nt_native.node",
YUI_NATIVE: "D:/GitHub/Yui-native/build/nt_native.node",
QQV8BytecodeDebug: '1',
},
cwd: path.resolve(__dirname, '../program')
Expand Down
44 changes: 44 additions & 0 deletions tools/gen-function.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const fs = require('fs')
const path = require('path')
let data = fs.readFileSync(path.resolve(__dirname, '../docs/functions/func.log')).toString()
data = data.split('\n')
console.log(data.length)
const allFuncs = data.filter(e => e && e.length > 0).map(e => {
let a=e.split(' ')
const [service, func] = a[5].split('::')
return {
service,
func: func,
count: parseInt(a[7])
}
})
const _exports = {}
for(const func of allFuncs)
{
if (_exports[func.service])
{
_exports[func.service].push(func)
}
else
{
_exports[func.service] = [func]
}
}

let markdown = ''
// 遍历类
for (const serviceName in _exports) {
console.info('serviceName:', serviceName)
const service = _exports[serviceName]
console.info('service:', service)
const funcs = service
markdown += `## ${serviceName}\n\n`
markdown += '| 方法名 | 参数数量 |\n'
markdown += '|-------|-----|\n'
// 遍历方法
for (const func of funcs) {
markdown += `| ${func.func} | ${func.count} |\n`
}
markdown += '\n'
}
fs.writeFileSync(path.resolve(__dirname, '../docs/function.md'), markdown)
8 changes: 4 additions & 4 deletions tools/prepend.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ global.asyncLocalStorage = asyncLocalStorage;
{
throw new Error('use wrapper: idx error')
}
const targetPath = wrapperPath //.replace('wrapper.node', `wrapper-${idx}.node`)
const targetPath = wrapperPath.replace('wrapper.node', `wrapper-${idx}.node`)
if (!fs.existsSync(targetPath))
{
fs.cpSync(wrapperPath, targetPath)
Expand All @@ -58,9 +58,9 @@ global.asyncLocalStorage = asyncLocalStorage;
'yui-native': (t) => {
/** @type {import('path')} */
const path = orgi_require('path')
let wrapperPath = path.resolve(__dirname, `./native.node`)
if (process.env['YUKIHANA_NATIVE']) {
wrapperPath = process.env['YUKIHANA_NATIVE']
let wrapperPath = path.resolve(__dirname, `./nt_native.node`)
if (process.env['YUI_NATIVE']) {
wrapperPath = process.env['YUI_NATIVE']
}
return orgi_require.apply(t, [wrapperPath])
}
Expand Down
14 changes: 9 additions & 5 deletions yui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ yui:
sqlite3_stmt: 48895C2420564883EC20488BD933F6E8EC
# 获取方法:ida 搜索 DebugGetIPByDomain,所处函数开头
get_ip_by_domain: 40555356574154415541564157488D6C24D84881EC28010000488B05F021
# 9.9.15-26909:
# # ida 搜索 65F883,找有for循环的
# sqlite3_stmt: 4156565755534883EC204889CFE80E01000085C07414B9000300004883C4205B
# # 获取方法:ida 搜索 DebugGetIPByDomain,所处函数开头
# get_ip_by_domain: 5541574156415541545657534881ECF8000000488DAC248000000048C74570
9.9.15-28498:
# ida 搜索 65F883,找有for循环的
# sqlite3_stmt: 4156565755534883EC204889CFE8FE00000085C07414B9000300004883C4205B
# 获取方法:ida 搜索 DebugGetIPByDomain,所处函数开头
# get_ip_by_domain: 5541574156415541545657534881ECF8000000488DAC248000000048C74570FEFFFFFF4C89CF4489456C4889552048894D
# 获取方法:ida 搜索 MSF task pushed seq,所处函数开头
msf_task: 5541574156415541545657534881EC08010000488DAC248000000048C78580000000FEFFFFFF4989CE48895578488B0AE824070000488D4D
# 获取方法:ida 搜索 MSF recv,所处函数开头
msf_resp: 5541574156415541545657534881ECF8000000488DAC248000000048C74570FEFFFFFF4489C748833A0048895560
linux:
3.2.5-21357:
# 获取方法:ida 搜索 DebugGetIPByDomain,所处函数开头
Expand Down

0 comments on commit 4946535

Please sign in to comment.