From 7f19e3cda209cc2d4acb1c89c849189eab5dbe3f Mon Sep 17 00:00:00 2001 From: bakashigure Date: Wed, 30 Aug 2023 00:23:30 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(skip=20ci):=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=87=B3koffi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- packages/main/coreLoader/api.ts | 50 +++++ packages/main/coreLoader/callback.ts | 13 +- packages/main/coreLoader/index.ts | 297 ++++----------------------- packages/main/coreLoader/types.ts | 29 +++ packages/main/coreLoader/utils.ts | 45 ++++ packages/main/hooks/asst.ts | 11 - packages/main/vite.config.ts | 2 +- pnpm-lock.yaml | 127 ++++++------ scripts/watch.mjs | 12 ++ 10 files changed, 245 insertions(+), 346 deletions(-) create mode 100644 packages/main/coreLoader/api.ts create mode 100644 packages/main/coreLoader/types.ts create mode 100644 packages/main/coreLoader/utils.ts diff --git a/package.json b/package.json index 5ead80df..6ce7767f 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,9 @@ "date-fns": "^2.30.0", "electron": "^26.0.0", "electron-devtools-installer": "^3.2.0", + "electron-rebuild": "^3.2.9", "exponential-backoff": "^3.1.1", + "fs-extra": "^11.1.1", "less": "^4.1.3", "lodash": "^4.17.21", "naive-ui": "^2.34.4", @@ -85,8 +87,6 @@ "arknights" ], "dependencies": { - "@tigerconnect/ffi-napi": "4.0.3-tc3", - "@tigerconnect/ref-napi": "4.0.0-tc8", "axios": "^1.4.0", "chalk": "4", "crypto-js": "^4.1.1", @@ -94,6 +94,7 @@ "electron-store": "^8.1.0", "execa": "^7.1.1", "iconv-lite": "^0.6.3", + "koffi": "^2.5.19", "ps-list": "^8.1.1", "rotating-file-stream": "^3.1.0", "semver": "^7.5.1", diff --git a/packages/main/coreLoader/api.ts b/packages/main/coreLoader/api.ts new file mode 100644 index 00000000..d64a79db --- /dev/null +++ b/packages/main/coreLoader/api.ts @@ -0,0 +1,50 @@ +import koffi from 'koffi' + +import './types' + +const protos = { + AsstSetUserDir: 'AsstBool AsstSetUserDir(str path)', + AsstLoadResource: 'AsstBool AsstLoadResource(str path)', + AsstSetStaticOption: 'AsstBool AsstSetStaticOption(AsstStaticOptionKey key, str value)', + + AsstCreate: 'AsstHandle AsstCreate()', + AsstCreateEx: 'AsstHandle AsstCreateEx(AsstApiCallback* callback, intptr custom_arg)', + AsstDestroy: 'void AsstDestroy(AsstHandle handle)', + + AsstSetInstanceOption: + 'AsstBool AsstSetInstanceOption(AsstHandle handle, AsstInstanceOptionKey key, str value)', + + // AsstConnect + AsstAppendTask: 'AsstTaskId AsstAppendTask(AsstHandle handle, str type, str params)', + AsstSetTaskParams: 'AsstBool AsstSetTaskParams(AsstHandle handle, AsstTaskId id, str params)', + + AsstStart: 'AsstBool AsstStart(AsstHandle handle)', + AsstStop: 'AsstBool AsstStop(AsstHandle handle)', + AsstRunning: 'AsstBool AsstRunning(AsstHandle handle)', + AsstConnected: 'AsstBool AsstConnected(AsstHandle handle)', + + AsstAsyncConnect: + 'AsstAsyncCallId AsstAsyncConnect(AsstHandle handle, str adb_path, str address, str config, AsstBool block)', + AsstAsyncClick: + 'AsstAsyncCallId AsstAsyncClick(AsstHandle handle, int32 x, int32 y, AsstBool block)', + AsstAsyncScreencap: 'AsstAsyncCallId AsstAsyncScreencap(AsstHandle handle, AsstBool block)', + + AsstGetImage: 'AsstSize AsstGetImage(AsstHandle, _Out_ void* buff, AsstSize buff_size)', + AsstGetUUID: 'AsstSize AsstGetUUID(AsstHandle, _Out_ char* buff, AsstSize buff_size)', + AsstGetTasksList: + 'AsstSize AsstGetTasksList(AsstHandle, _Out_ AsstTaskId* buff, AsstSize buff_size)', + AsstGetNullSize: 'AsstSize AsstGetNullSize()', + + AsstGetVersion: 'str AsstGetVersion()', + AsstLog: 'void AsstLog(str level, str message)' +} + +export type MaaCoreExports = Record + +export function load(lib: koffi.IKoffiLib) { + const result: Record = {} + for (const key in protos) { + result[key] = lib.func(protos[key as keyof typeof protos]) + } + return result as MaaCoreExports +} diff --git a/packages/main/coreLoader/callback.ts b/packages/main/coreLoader/callback.ts index 34d20e62..a0a2e06c 100644 --- a/packages/main/coreLoader/callback.ts +++ b/packages/main/coreLoader/callback.ts @@ -1,19 +1,12 @@ -import ffi from '@tigerconnect/ffi-napi' -import ref from '@tigerconnect/ref-napi' import logger from '@main/utils/logger' import type { AsstMsg } from '@type/task/callback' +import type { AsstApiCallback } from './types' -const callbackHandle = ffi.Callback( - 'void', - ['int', 'string', ref.refType(ref.types.void)], - (code: AsstMsg, data: string, customArgs) => { +export const callbackHandle: AsstApiCallback = (code, data, customArgs) => { logger.silly(code) logger.silly(data) globalThis.renderer.CoreLoader.callback({ code, data: JSON.parse(data), }) - } -) - -export default callbackHandle + } \ No newline at end of file diff --git a/packages/main/coreLoader/index.ts b/packages/main/coreLoader/index.ts index ac815782..a41b1211 100644 --- a/packages/main/coreLoader/index.ts +++ b/packages/main/coreLoader/index.ts @@ -4,84 +4,42 @@ import path from 'path' import _ from 'lodash' import logger from '@main/utils/logger' import { existsSync, mkdirSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'fs' -import ffi, { DynamicLibrary } from '@tigerconnect/ffi-napi' -import ref from '@tigerconnect/ref-napi' -import callbackHandle from './callback' +import koffi, { type IKoffiRegisteredCallback, type KoffiFunction, type pointer } from 'koffi' +import { callbackHandle } from './callback' import { getAppBaseDir } from '@main/utils/path' import type { TouchMode } from '@type/misc' import { InstanceOptionKey } from '@type/misc' import { extractFile, unzipFile } from '@main/utils/extract' import type { ResourceType } from '@type/game' +import { loadLibrary } from './utils' +import { type MaaCoreExports, load } from './api' +import { AsstApiCallback } from './types' +import type { AsstMsg } from '@type/task/callback' +export * from './types' + + const storage = new Storage() -/** Some types for core */ -const BoolType = ref.types.bool -const IntType = ref.types.int -const AsstAsyncCallIdType = ref.types.int -// const AsstBoolType = ref.types.uint8 -// const IntArrayType = ArrayType(IntType) -// const DoubleType = ref.types.double -const ULLType = ref.types.ulonglong -const VoidType = ref.types.void -const StringType = ref.types.CString -// const StringPtrType = ref.refType(StringType) -// const StringPtrArrayType = ArrayType(StringType) -const AsstType = ref.types.void -const AsstPtrType = ref.refType(AsstType) -// const TaskPtrType = ref.refType(AsstType) -const CustomArgsType = ref.refType(ref.types.void) -const IntPointerType = ref.refType(IntType) -/** -const CallBackType = ffi.Function(ref.types.void, [ - IntType, - StringType, - ref.refType(ref.types.void) -]) - */ -const Buff = CustomArgsType -type AsstInstancePtr = ref.Pointer -// type TaskInstancePtr = ref.Pointer - -// type CallBackFunc = (msg: number, detail: string, custom?: any) => any - -function createVoidPointer(): ref.Value { - return ref.alloc(ref.types.void) -} @Singleton class CoreLoader { - private readonly dependences: Record = { - win32: ['opencv_world4_maa.dll', 'onnxruntime_maa.dll', 'MaaDerpLearning.dll'], - linux: ['libopencv_world4.so.407', 'libonnxruntime.so.1.14.1', 'libMaaDerpLearning.so'], - darwin: [ - 'libopencv_world4.407.dylib', - 'libonnxruntime.1.14.1.dylib', - 'libMaaDerpLearning.dylib', - ], - } - private readonly libName: Record = { - win32: 'MaaCore.dll', - darwin: 'libMaaCore.dylib', - linux: 'libMaaCore.so', - } - - private DLib!: ffi.DynamicLibrary + private lib!: koffi.IKoffiLib + private func!: MaaCoreExports private static libPath: string private static readonly libPathKey = 'libPath' private static readonly defaultLibPath = path.join(getAppBaseDir(), 'core') private static loadStatus: boolean // core加载状态 - public MeoAsstLib!: any - private readonly DepLibs: DynamicLibrary[] = [] - MeoAsstPtr: Record = {} + MeoAsstPtr: Record = {} screenshotCache: Record = {} + callback: IKoffiRegisteredCallback constructor() { // 在构造函数中创建core存储文件夹 CoreLoader.loadStatus = false CoreLoader.libPath = storage.get(CoreLoader.libPathKey) as string if (!_.isString(CoreLoader.libPath) || !existsSync(CoreLoader.libPath)) { - logger.error(`Update resource folder: ${CoreLoader.libPath} --> ${CoreLoader.defaultLibPath}`) + logger.error(`[CoreLoader] Update resource folder: ${CoreLoader.libPath} --> ${CoreLoader.defaultLibPath}`) CoreLoader.libPath = CoreLoader.defaultLibPath if (!existsSync(CoreLoader.libPath)) mkdirSync(CoreLoader.libPath) } @@ -89,6 +47,7 @@ class CoreLoader { CoreLoader.libPath = path.resolve(CoreLoader.libPath) storage.set(CoreLoader.libPathKey, CoreLoader.libPath) } + this.callback = koffi.register(callbackHandle, AsstApiCallback) } /** @@ -129,12 +88,9 @@ class CoreLoader { this.Destroy(uuid) } try { - this.DLib.close() + this.lib?.unload() } catch (e) { - logger.error('close core error') - } - for (const dep of this.DepLibs) { - dep.close() + logger.error(e) } CoreLoader.loadStatus = false } @@ -149,174 +105,15 @@ class CoreLoader { } try { CoreLoader.loadStatus = true - this.dependences[process.platform].forEach(lib => { - this.DepLibs.push(ffi.DynamicLibrary(path.join(this.libPath, lib))) - }) - this.DLib = ffi.DynamicLibrary( - path.join(this.libPath, this.libName[process.platform]), - ffi.RTLD_NOW - ) - this.MeoAsstLib = { - AsstSetUserDir: ffi.ForeignFunction( - this.DLib.get('AsstSetUserDir'), - BoolType, - [StringType], - ffi.FFI_STDCALL - ), - - AsstLoadResource: ffi.ForeignFunction( - this.DLib.get('AsstLoadResource'), - BoolType, - [StringType], - ffi.FFI_STDCALL - ), - - AsstSetStaticOption: ffi.ForeignFunction( - this.DLib.get('AsstSetStaticOption'), - BoolType, - [IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstCreate: ffi.ForeignFunction( - this.DLib.get('AsstCreate'), - AsstPtrType, - [], - ffi.FFI_STDCALL - ), - - AsstCreateEx: ffi.ForeignFunction( - this.DLib.get('AsstCreateEx'), - AsstPtrType, - ['pointer', CustomArgsType], - ffi.FFI_STDCALL - ), - - AsstDestroy: ffi.ForeignFunction( - this.DLib.get('AsstDestroy'), - VoidType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstSetInstanceOption: ffi.ForeignFunction( - this.DLib.get('AsstSetInstanceOption'), - BoolType, - [AsstPtrType, IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstConnect: ffi.ForeignFunction( - this.DLib.get('AsstConnect'), - BoolType, - [AsstPtrType, StringType, StringType, StringType], - ffi.FFI_STDCALL - ), - - AsstAppendTask: ffi.ForeignFunction( - this.DLib.get('AsstAppendTask'), - IntType, - [AsstPtrType, StringType, StringType], - ffi.FFI_STDCALL - ), - - AsstSetTaskParams: ffi.ForeignFunction( - this.DLib.get('AsstSetTaskParams'), - BoolType, - [AsstPtrType, IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstStart: ffi.ForeignFunction( - this.DLib.get('AsstStart'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstStop: ffi.ForeignFunction( - this.DLib.get('AsstStop'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstRunning: ffi.ForeignFunction( - this.DLib.get('AsstRunning'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstAsyncConnect: ffi.ForeignFunction( - this.DLib.get('AsstAsyncConnect'), - AsstAsyncCallIdType, - [AsstPtrType, StringType, StringType, StringType, BoolType], - ffi.FFI_STDCALL - ), - - AsstAsyncClick: ffi.ForeignFunction( - this.DLib.get('AsstAsyncClick'), - AsstAsyncCallIdType, - [AsstPtrType, IntType, IntType, BoolType], - ffi.FFI_STDCALL - ), - - AsstAsyncScreencap: ffi.ForeignFunction( - this.DLib.get('AsstAsyncScreencap'), - AsstAsyncCallIdType, - [AsstPtrType, BoolType], - ffi.FFI_STDCALL - ), - - AsstGetImage: ffi.ForeignFunction( - this.DLib.get('AsstGetImage'), - ULLType, - [AsstPtrType, Buff, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetUUID: ffi.ForeignFunction( - this.DLib.get('AsstGetUUID'), - ULLType, - [AsstPtrType, StringType, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetTasksList: ffi.ForeignFunction( - this.DLib.get('AsstGetTasksList'), - ULLType, - [AsstPtrType, IntPointerType, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetNullSize: ffi.ForeignFunction( - this.DLib.get('AsstGetNullSize'), - ULLType, - [], - ffi.FFI_STDCALL - ), - - AsstGetVersion: ffi.ForeignFunction( - this.DLib.get('AsstGetVersion'), - StringType, - [], - ffi.FFI_STDCALL - ), - - AsstLog: ffi.ForeignFunction( - this.DLib.get('AsstLog'), - VoidType, - [StringType, StringType], - ffi.FFI_STDCALL - ), - } + this.lib = loadLibrary(path.join(this.libPath, 'MaaCore')) + this.func = load(this.lib) + + const version = this.GetCoreVersion() if (version) { logger.info(`core loaded: version ${version}`) } } catch (error) { - // console.error() logger.error((error as Error).message) this.dispose() } @@ -333,7 +130,7 @@ class CoreLoader { logger.warn(`[LoadResource] path not exists ${path}`) return false } - return this.MeoAsstLib.AsstLoadResource(path ?? this.libPath) + return this.func.AsstLoadResource(path ?? this.libPath) } /** @@ -341,7 +138,7 @@ class CoreLoader { * @returns 实例指针{ref.Pointer} */ public Create(): boolean { - this.MeoAsstPtr.placeholder = this.MeoAsstLib.AsstCreate() + this.MeoAsstPtr.placeholder = this.func.AsstCreate() return !!this.MeoAsstPtr.placeholder } @@ -354,11 +151,11 @@ class CoreLoader { */ public CreateEx( uuid: string, - callback: any = callbackHandle, - customArg: any = createVoidPointer() + // callback: any = this.callBackHandle, + // customArg: any = 0 ): boolean { if (!this.MeoAsstPtr[uuid]) { - this.MeoAsstPtr[uuid] = this.MeoAsstLib.AsstCreateEx(callback, customArg) + this.MeoAsstPtr[uuid] = this.func.AsstCreateEx(this.callback, 0) return true } return false // 重复创建 @@ -370,17 +167,12 @@ class CoreLoader { */ public Destroy(uuid: string): void { if (this.MeoAsstPtr[uuid]) { - this.MeoAsstLib.AsstDestroy(this.MeoAsstPtr[uuid]) + this.func.AsstDestroy(this.MeoAsstPtr[uuid]) // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.MeoAsstPtr[uuid] } } - /** @deprecated 已废弃,将在接下来的版本中移除 */ - public Connect(address: string, uuid: string, adbPath: string, config: string): boolean { - return this.MeoAsstLib.AsstConnect(this.MeoAsstPtr[uuid], `"${adbPath}"`, address, config) - } - /** * @description 连接 * @param address 连接地址 @@ -397,7 +189,7 @@ class CoreLoader { config: string, block: boolean = false ): number { - return this.MeoAsstLib.AsstAsyncConnect( + return this.func.AsstAsyncConnect( this.MeoAsstPtr[uuid], `"${adbPath}"`, address, @@ -414,7 +206,7 @@ class CoreLoader { * @returns */ public AppendTask(uuid: string, type: string, params: string): number { - return this.MeoAsstLib.AsstAppendTask(this.GetCoreInstanceByUUID(uuid), type, params) + return this.func.AsstAppendTask(this.GetCoreInstanceByUUID(uuid), type, params) } /** @@ -425,7 +217,7 @@ class CoreLoader { */ public SetTaskParams(uuid: string, taskId: number, params: string): boolean { - return this.MeoAsstLib.AsstSetTaskParams(this.GetCoreInstanceByUUID(uuid), taskId, params) + return this.func.AsstSetTaskParams(this.GetCoreInstanceByUUID(uuid), taskId, params) } /** @@ -434,7 +226,7 @@ class CoreLoader { * @returns 是否成功 */ public Start(uuid: string): boolean { - return this.MeoAsstLib.AsstStart(this.GetCoreInstanceByUUID(uuid)) + return this.func.AsstStart(this.GetCoreInstanceByUUID(uuid)) } /** @@ -447,20 +239,8 @@ class CoreLoader { logger.warn(`[Stop] uuid not exists ${uuid}`) return true } - return this.MeoAsstLib.AsstStop(this.GetCoreInstanceByUUID(uuid)) + return this.func.AsstStop(this.GetCoreInstanceByUUID(uuid)) } - - /** - * 发送点击 - * @param uuid 设备唯一标识符 - * @param x x坐标 - * @param y y坐标 - * @returns - */ - public Click(uuid: string, x: number, y: number): boolean { - return this.MeoAsstLib.AsstClick(this.GetCoreInstanceByUUID(uuid), x, y) - } - /** * 异步请求截图, 在回调中取得截图完成事件后再使用GetImage获取截图 * @param uuid @@ -469,7 +249,7 @@ class CoreLoader { */ public AsyncScreencap(uuid: string, block: boolean = true): number | boolean { if (!this.MeoAsstPtr[uuid]) return false - return this.MeoAsstLib.AsstAsyncScreencap(this.GetCoreInstanceByUUID(uuid), block) + return this.func.AsstAsyncScreencap(this.GetCoreInstanceByUUID(uuid), block) } public GetImage(uuid: string): string { @@ -477,7 +257,7 @@ class CoreLoader { this.screenshotCache[uuid] = Buffer.alloc(5114514) } const buffer = this.screenshotCache[uuid] - const len = this.MeoAsstLib.AsstGetImage( + const len = this.func.AsstGetImage( this.GetCoreInstanceByUUID(uuid), buffer, buffer.length @@ -493,19 +273,20 @@ class CoreLoader { */ public GetCoreVersion(): string | null { if (!this.loadStatus) return null - return this.MeoAsstLib.AsstGetVersion() + return this.func.AsstGetVersion() } - public GetCoreInstanceByUUID(uuid: string): AsstInstancePtr { + public GetCoreInstanceByUUID(uuid: string): any { + console.log('type of this.MeoAsstPtr[uuid]', typeof this.MeoAsstPtr[uuid]) return this.MeoAsstPtr[uuid] } public Log(level: string, message: string): void { - return this.MeoAsstLib.AsstLog(level, message) + return this.func.AsstLog(level, message) } public SetInstanceOption(uuid: string, key: InstanceOptionKey, value: string): boolean { - return this.MeoAsstLib.AsstSetInstanceOption(this.GetCoreInstanceByUUID(uuid), key, value) + return this.func.AsstSetInstanceOption(this.GetCoreInstanceByUUID(uuid), key, value) } public SetTouchMode(uuid: string, mode: TouchMode): boolean { diff --git a/packages/main/coreLoader/types.ts b/packages/main/coreLoader/types.ts new file mode 100644 index 00000000..146a63af --- /dev/null +++ b/packages/main/coreLoader/types.ts @@ -0,0 +1,29 @@ +import type { AsstMsg } from '@type/task/callback' +import koffi from 'koffi' + +export const AsstExtAPI = koffi.opaque('AsstExtAPI') +export const AsstHandle = koffi.alias('AsstHandle', 'AsstExtAPI*') +export type AsstHandle = unknown + +export const AsstBool = koffi.alias('AsstBool', 'uint8') +export const AsstSize = koffi.alias('AsstSize', 'uint64') + +export const AsstId = koffi.alias('AsstId', 'int32') +export const AsstMsgId = koffi.alias('AsstMsgId', 'AsstId') +export const AsstTaskId = koffi.alias('AsstTaskId', 'AsstId') +export type AsstTaskId = number +export const AsstAsyncCallId = koffi.alias('AsstAsyncCallId', 'AsstId') + +export const AsstOptionKey = koffi.alias('AsstOptionKey', 'int32') +export const AsstStaticOptionKey = koffi.alias('AsstStaticOptionKey', 'AsstOptionKey') +export const AsstInstanceOptionKey = koffi.alias('AsstInstanceOptionKey', 'AsstOptionKey') + +export const AsstApiCallback_Prototype = koffi.proto( + 'void AsstApiCallback_Prototype(AsstMsgId msg, str details_json, intptr custom_arg)' +) + +export const AsstApiCallback = koffi.alias( + 'AsstApiCallback', + koffi.pointer(AsstApiCallback_Prototype) +) +export type AsstApiCallback = (msg: AsstMsg, details_json: string, custom_arg: unknown) => void \ No newline at end of file diff --git a/packages/main/coreLoader/utils.ts b/packages/main/coreLoader/utils.ts new file mode 100644 index 00000000..00fd73e3 --- /dev/null +++ b/packages/main/coreLoader/utils.ts @@ -0,0 +1,45 @@ +import koffi from 'koffi' +import path from 'path' + +type AcceptPlatform = 'win32' | 'linux' | 'darwin' + +const plat = process.platform as AcceptPlatform + +const libName: Record string> = { + win32: (d, l) => path.join(d, `${l}.dll`), + linux: (d, l) => path.join(d, `lib${l}.so`), + darwin: (d, l) => path.join(d, `lib${l}.dylib`) +} + +let win_dll_paths: string[] | null = null + +export function loadLibrary(file: string) { + const dir = path.resolve(path.dirname(file)) + const lib = path.basename(file) + + if (plat === 'win32') { + const kernel = koffi.load('kernel32.dll') + if (!win_dll_paths) { + kernel.stdcall('int32 SetDefaultDllDirectories(uint32)')(0x1000) + win_dll_paths = [] + } + if (!win_dll_paths.includes(dir)) { + kernel.stdcall('int32 AddDllDirectory(str16)')(dir) + win_dll_paths.push(dir) + } + } + + return koffi.load(libName[plat](dir, lib)) +} + +export type PromiseInfo = { + resolve: (state: T) => void + promise: Promise +} +export function getPromise(): PromiseInfo { + const result: Partial> = {} + result.promise = new Promise(resolve => { + result.resolve = resolve + }) + return result as PromiseInfo +} diff --git a/packages/main/hooks/asst.ts b/packages/main/hooks/asst.ts index 707dd14b..1d187159 100644 --- a/packages/main/hooks/asst.ts +++ b/packages/main/hooks/asst.ts @@ -20,17 +20,6 @@ const hooks: IpcMainHandleEventCalleeProxy['CoreLoader'] = { core.Destroy(uuid) return true }, - connect({ address, uuid, adb_path, config }) { - return core.Connect(address, uuid, adb_path, config) - }, - /** @Deprecated */ - initCore(arg) { - const createStatus = core.CreateEx(arg.uuid) ?? false - if (!createStatus) logger.warn(`重复创建 ${JSON.stringify(arg)}`) - if (!core.SetTouchMode(arg.uuid, arg.touch_mode)) - logger.warn('Set touch mode failed', arg.touch_mode) - return core.Connect(arg.address, arg.uuid, arg.adb_path, arg.config) - }, initCoreAsync(arg) { const createStatus = core.CreateEx(arg.uuid) ?? false if (!createStatus) logger.warn(`重复创建 ${JSON.stringify(arg)}`) diff --git a/packages/main/vite.config.ts b/packages/main/vite.config.ts index a5ad2537..c7399d02 100644 --- a/packages/main/vite.config.ts +++ b/packages/main/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ sourcemap: true, emptyOutDir: true, rollupOptions: { - external: ['electron', ...builtinModules, ...Object.keys(pkg.dependencies || {})], + external: ['electron', ...builtinModules, ...Object.keys(pkg.dependencies || {}), 'koffi'], }, }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9eeed089..f694399a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,16 +1,10 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' settings: autoInstallPeers: true excludeLinksFromLockfile: false dependencies: - '@tigerconnect/ffi-napi': - specifier: 4.0.3-tc3 - version: 4.0.3-tc3 - '@tigerconnect/ref-napi': - specifier: 4.0.0-tc8 - version: 4.0.0-tc8 axios: specifier: ^1.4.0 version: 1.4.0 @@ -32,6 +26,9 @@ dependencies: iconv-lite: specifier: ^0.6.3 version: 0.6.3 + koffi: + specifier: ^2.5.19 + version: 2.5.19 ps-list: specifier: ^8.1.1 version: 8.1.1 @@ -148,9 +145,15 @@ devDependencies: electron-devtools-installer: specifier: ^3.2.0 version: 3.2.0 + electron-rebuild: + specifier: ^3.2.9 + version: 3.2.9 exponential-backoff: specifier: ^3.1.1 version: 3.1.1 + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 less: specifier: ^4.1.3 version: 4.1.3 @@ -2178,37 +2181,6 @@ packages: defer-to-connect: 2.0.1 dev: true - /@tigerconnect/ffi-napi@4.0.3-tc3: - resolution: {integrity: sha512-wHzQFyBBmK/9Mf0jIgALtyxQPTWxSG7PUysQO/Qiu0Z/zOTGi8mNi4qmTjlWanmDa3AClt4XsgaUD8TivU/Mlg==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - '@tigerconnect/ref-napi': 4.0.0-tc8 - '@types/node': 18.16.16 - '@types/ref-struct-di': 1.1.9 - debug: 4.3.4 - get-uv-event-loop-napi-h: 1.0.6 - node-addon-api: 3.2.1 - node-gyp-build: 4.6.0 - ref-struct-di: 1.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@tigerconnect/ref-napi@4.0.0-tc8: - resolution: {integrity: sha512-KbdXLRQPHQsZEW0AO5VJ836EGbfat4lNIXYmm8nPQPHJGN14/wWq3a+1E0pRuQ28I6YtX0cTM6lW8e59zjdsEA==} - engines: {node: '>= 10.0'} - requiresBuild: true - dependencies: - '@types/node': 18.16.16 - debug: 4.3.4 - get-symbol-from-current-process-h: 1.0.2 - node-addon-api: 4.3.0 - node-gyp-build: 4.6.0 - transitivePeerDependencies: - - supports-color - dev: false - /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -2301,16 +2273,19 @@ packages: /@types/node@18.16.16: resolution: {integrity: sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==} + dev: true /@types/ref-napi@3.0.7: resolution: {integrity: sha512-CzPwr36VkezSpaJGdQX/UrczMSDsDgsWQQFEfQkS799Ft7n/s183a53lsql7RwVq+Ik4yLEgI84pRnLC0XXRlA==} dependencies: '@types/node': 18.16.16 + dev: true /@types/ref-struct-di@1.1.9: resolution: {integrity: sha512-B1FsB1BhG1VLx0+IqBaAPXEPH0wCOb+Glaaw/i+nRUwDKFtSqWOziGnTRw05RyrBbrDsMiM0tVWmaujrs016Sw==} dependencies: '@types/ref-napi': 3.0.7 + dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} @@ -3267,6 +3242,8 @@ packages: optional: true dependencies: ms: 2.1.3 + dev: true + optional: true /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -3278,6 +3255,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: true /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -3497,6 +3475,31 @@ packages: - supports-color dev: true + /electron-rebuild@3.2.9: + resolution: {integrity: sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==} + engines: {node: '>=12.13.0'} + deprecated: Please use @electron/rebuild moving forward. There is no API change, just a package name change + hasBin: true + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + chalk: 4.1.2 + debug: 4.3.4 + detect-libc: 2.0.1 + fs-extra: 10.1.0 + got: 11.8.6 + lzma-native: 8.0.6 + node-abi: 3.43.0 + node-api-version: 0.1.4 + node-gyp: 9.3.1 + ora: 5.4.1 + semver: 7.5.1 + tar: 6.1.15 + yargs: 17.7.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: true + /electron-squirrel-startup@1.0.0: resolution: {integrity: sha512-Oce8mvgGdFmwr+DsAcXBmFK8jFfN6yaFAP9IvyhTfupM3nFkBku/7VS/mdtJteWumImkC6P+BKGsxScoDDkv9Q==} dependencies: @@ -4140,16 +4143,6 @@ packages: engines: {node: '>=10'} dev: false - /get-symbol-from-current-process-h@1.0.2: - resolution: {integrity: sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==} - dev: false - - /get-uv-event-loop-napi-h@1.0.6: - resolution: {integrity: sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==} - dependencies: - get-symbol-from-current-process-h: 1.0.2 - dev: false - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -4614,6 +4607,11 @@ packages: json-buffer: 3.0.1 dev: true + /koffi@2.5.19: + resolution: {integrity: sha512-x3soag0nEhqUYeaOsj5HV3ogj/XLHWHtui3Z2Fim7pwNgIfYvWL2PxkOFtJRdyjjTM4o2u68e5rvNj96DcWghQ==} + requiresBuild: true + dev: false + /less@4.1.3: resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} engines: {node: '>=6'} @@ -4790,6 +4788,17 @@ packages: engines: {node: '>=12'} dev: true + /lzma-native@8.0.6: + resolution: {integrity: sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==} + engines: {node: '>=10.0.0'} + hasBin: true + requiresBuild: true + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.6.1 + readable-stream: 3.6.2 + dev: true + /magic-string@0.30.0: resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} engines: {node: '>=12'} @@ -5045,9 +5054,11 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true /muggle-string@0.2.2: resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==} @@ -5117,11 +5128,7 @@ packages: /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - dev: false - - /node-addon-api@4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - dev: false + dev: true /node-api-version@0.1.4: resolution: {integrity: sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==} @@ -5141,10 +5148,10 @@ packages: whatwg-url: 5.0.0 dev: true - /node-gyp-build@4.6.0: - resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} hasBin: true - dev: false + dev: true /node-gyp@9.3.1: resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} @@ -5695,14 +5702,6 @@ packages: resolve: 1.22.2 dev: true - /ref-struct-di@1.1.1: - resolution: {integrity: sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==} - dependencies: - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: false - /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} dev: true diff --git a/scripts/watch.mjs b/scripts/watch.mjs index 2627c592..33c9e26f 100644 --- a/scripts/watch.mjs +++ b/scripts/watch.mjs @@ -1,6 +1,10 @@ import { spawn } from 'child_process' import { createServer, build } from 'vite' import electron from 'electron' +import path from 'path' +import fs from 'fs-extra' +import { fileURLToPath } from 'url'; + let aliveInst = 0 let quitTimer = null @@ -52,6 +56,7 @@ function watchMain(server) { startQuit() } }) + }, }, ], @@ -82,6 +87,13 @@ function watchPreload(server) { }) } +function installKoffiBinaries() { + const currentDir = path.dirname(fileURLToPath(import.meta.url)); + console.log(currentDir) + fs.copySync(path.resolve(currentDir, '../node_modules/koffi/build'), path.resolve(currentDir, '../node_modules/electron/dist/resources')); +} + +installKoffiBinaries() // bootstrap const server = await createServer({ configFile: 'packages/renderer/vite.config.ts', From 58c08f66a2f2145a69b8b823b96b1204256d3fc7 Mon Sep 17 00:00:00 2001 From: bakashigure Date: Wed, 30 Aug 2023 00:23:30 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat(skip=20ci):=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=87=B3koffi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- packages/main/coreLoader/api.ts | 50 +++++ packages/main/coreLoader/callback.ts | 13 +- packages/main/coreLoader/index.ts | 319 +++++---------------------- packages/main/coreLoader/types.ts | 29 +++ packages/main/coreLoader/utils.ts | 45 ++++ packages/main/hooks/asst.ts | 11 - packages/main/vite.config.ts | 2 +- pnpm-lock.yaml | 159 +++++++------ scripts/watch.mjs | 12 + 10 files changed, 278 insertions(+), 367 deletions(-) create mode 100644 packages/main/coreLoader/api.ts create mode 100644 packages/main/coreLoader/types.ts create mode 100644 packages/main/coreLoader/utils.ts diff --git a/package.json b/package.json index 3aebc317..bffaba07 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,9 @@ "date-fns": "^2.30.0", "electron": "^26.0.0", "electron-devtools-installer": "^3.2.0", + "electron-rebuild": "^3.2.9", "exponential-backoff": "^3.1.1", + "fs-extra": "^11.1.1", "less": "^4.1.3", "lodash": "^4.17.21", "naive-ui": "^2.34.4", @@ -86,8 +88,6 @@ "arknights" ], "dependencies": { - "@tigerconnect/ffi-napi": "4.0.3-tc3", - "@tigerconnect/ref-napi": "4.0.0-tc8", "axios": "^1.4.0", "chalk": "4", "crypto-js": "^4.1.1", @@ -95,6 +95,7 @@ "electron-store": "^8.1.0", "execa": "^7.1.1", "iconv-lite": "^0.6.3", + "koffi": "^2.6.3", "ps-list": "^8.1.1", "rotating-file-stream": "^3.1.0", "semver": "^7.5.1", diff --git a/packages/main/coreLoader/api.ts b/packages/main/coreLoader/api.ts new file mode 100644 index 00000000..56644e09 --- /dev/null +++ b/packages/main/coreLoader/api.ts @@ -0,0 +1,50 @@ +import koffi from 'koffi' + +import './types' + +const protos = { + AsstSetUserDir: 'AsstBool AsstSetUserDir(str path)', + AsstLoadResource: 'AsstBool AsstLoadResource(str path)', + AsstSetStaticOption: 'AsstBool AsstSetStaticOption(AsstStaticOptionKey key, str value)', + + AsstCreate: 'AsstHandle AsstCreate()', + AsstCreateEx: 'AsstHandle AsstCreateEx(AsstApiCallback callback, intptr custom_arg)', + AsstDestroy: 'void AsstDestroy(AsstHandle handle)', + + AsstSetInstanceOption: + 'AsstBool AsstSetInstanceOption(AsstHandle handle, AsstInstanceOptionKey key, str value)', + + // AsstConnect + AsstAppendTask: 'AsstTaskId AsstAppendTask(AsstHandle handle, str type, str params)', + AsstSetTaskParams: 'AsstBool AsstSetTaskParams(AsstHandle handle, AsstTaskId id, str params)', + + AsstStart: 'AsstBool AsstStart(AsstHandle handle)', + AsstStop: 'AsstBool AsstStop(AsstHandle handle)', + AsstRunning: 'AsstBool AsstRunning(AsstHandle handle)', + AsstConnected: 'AsstBool AsstConnected(AsstHandle handle)', + + AsstAsyncConnect: + 'AsstAsyncCallId AsstAsyncConnect(AsstHandle handle, str adb_path, str address, str config, AsstBool block)', + AsstAsyncClick: + 'AsstAsyncCallId AsstAsyncClick(AsstHandle handle, int32 x, int32 y, AsstBool block)', + AsstAsyncScreencap: 'AsstAsyncCallId AsstAsyncScreencap(AsstHandle handle, AsstBool block)', + + AsstGetImage: 'AsstSize AsstGetImage(AsstHandle, _Out_ void* buff, AsstSize buff_size)', + AsstGetUUID: 'AsstSize AsstGetUUID(AsstHandle, _Out_ char* buff, AsstSize buff_size)', + AsstGetTasksList: + 'AsstSize AsstGetTasksList(AsstHandle, _Out_ AsstTaskId* buff, AsstSize buff_size)', + AsstGetNullSize: 'AsstSize AsstGetNullSize()', + + AsstGetVersion: 'str AsstGetVersion()', + AsstLog: 'void AsstLog(str level, str message)' +} + +export type MaaCoreExports = Record + +export function load(lib: koffi.IKoffiLib) { + const result: Record = {} + for (const key in protos) { + result[key] = lib.func(protos[key as keyof typeof protos]) + } + return result as MaaCoreExports +} diff --git a/packages/main/coreLoader/callback.ts b/packages/main/coreLoader/callback.ts index 6c9a3ab8..a0a2e06c 100644 --- a/packages/main/coreLoader/callback.ts +++ b/packages/main/coreLoader/callback.ts @@ -1,19 +1,12 @@ import logger from '@main/utils/logger' -import ffi from '@tigerconnect/ffi-napi' -import ref from '@tigerconnect/ref-napi' import type { AsstMsg } from '@type/task/callback' +import type { AsstApiCallback } from './types' -const callbackHandle = ffi.Callback( - 'void', - ['int', 'string', ref.refType(ref.types.void)], - (code: AsstMsg, data: string, customArgs) => { +export const callbackHandle: AsstApiCallback = (code, data, customArgs) => { logger.silly(code) logger.silly(data) globalThis.renderer.CoreLoader.callback({ code, data: JSON.parse(data), }) - } -) - -export default callbackHandle + } \ No newline at end of file diff --git a/packages/main/coreLoader/index.ts b/packages/main/coreLoader/index.ts index 9d00938c..2611379e 100644 --- a/packages/main/coreLoader/index.ts +++ b/packages/main/coreLoader/index.ts @@ -1,83 +1,54 @@ import { Singleton } from '@common/function/singletonDecorator' import { getComponentBaseDir } from '@main/componentManager/utils/path' import Storage from '@main/storageManager' -import { extractFile } from '@main/utils/extract' import logger from '@main/utils/logger' +import _ from 'lodash' +import path from 'path' + +import { existsSync, mkdirSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'fs' +import koffi, { type IKoffiRegisteredCallback, type KoffiFunction, type pointer } from 'koffi' +import { callbackHandle } from './callback' import { getAppBaseDir } from '@main/utils/path' -import ffi, { DynamicLibrary } from '@tigerconnect/ffi-napi' -import ref from '@tigerconnect/ref-napi' -import type { ResourceType } from '@type/game' import type { TouchMode } from '@type/misc' import { InstanceOptionKey } from '@type/misc' -import { existsSync, mkdirSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'fs' -import _ from 'lodash' -import path from 'path' +import { extractFile, unzipFile } from '@main/utils/extract' +import type { ResourceType } from '@type/game' +import { loadLibrary } from './utils' +import { type MaaCoreExports, load } from './api' +import { AsstApiCallback } from './types' +import type { AsstMsg } from '@type/task/callback' +export * from './types' -import callbackHandle from './callback' const storage = new Storage() -/** Some types for core */ -const BoolType = ref.types.bool -const IntType = ref.types.int -const AsstAsyncCallIdType = ref.types.int -// const AsstBoolType = ref.types.uint8 -// const IntArrayType = ArrayType(IntType) -// const DoubleType = ref.types.double -const ULLType = ref.types.ulonglong -const VoidType = ref.types.void -const StringType = ref.types.CString -// const StringPtrType = ref.refType(StringType) -// const StringPtrArrayType = ArrayType(StringType) -const AsstType = ref.types.void -const AsstPtrType = ref.refType(AsstType) -// const TaskPtrType = ref.refType(AsstType) -const CustomArgsType = ref.refType(ref.types.void) -const IntPointerType = ref.refType(IntType) -/** -const CallBackType = ffi.Function(ref.types.void, [ - IntType, - StringType, - ref.refType(ref.types.void) -]) - */ -const Buff = CustomArgsType -type AsstInstancePtr = ref.Pointer -// type TaskInstancePtr = ref.Pointer - -// type CallBackFunc = (msg: number, detail: string, custom?: any) => any - -function createVoidPointer(): ref.Value { - return ref.alloc(ref.types.void) -} @Singleton class CoreLoader { - private readonly dependences: Record = { - win32: ['opencv_world4_maa.dll', 'onnxruntime_maa.dll', 'MaaDerpLearning.dll'], - linux: ['libopencv_world4.so.407', 'libonnxruntime.so.1.14.1', 'libMaaDerpLearning.so'], - darwin: [ - 'libopencv_world4.407.dylib', - 'libonnxruntime.1.14.1.dylib', - 'libMaaDerpLearning.dylib', - ], - } - private readonly libName: Record = { - win32: 'MaaCore.dll', - darwin: 'libMaaCore.dylib', - linux: 'libMaaCore.so', - } - - private DLib!: ffi.DynamicLibrary + private lib!: koffi.IKoffiLib + private func!: MaaCoreExports + private static libPath: string + private static readonly libPathKey = 'libPath' + private static readonly defaultLibPath = path.join(getAppBaseDir(), 'core') private static loadStatus: boolean // core加载状态 - public MeoAsstLib!: any - private readonly DepLibs: DynamicLibrary[] = [] - MeoAsstPtr: Record = {} + MeoAsstPtr: Record = {} screenshotCache: Record = {} + callback: IKoffiRegisteredCallback constructor() { // 在构造函数中创建core存储文件夹 CoreLoader.loadStatus = false + CoreLoader.libPath = storage.get(CoreLoader.libPathKey) as string + if (!_.isString(CoreLoader.libPath) || !existsSync(CoreLoader.libPath)) { + logger.error(`[CoreLoader] Update resource folder: ${CoreLoader.libPath} --> ${CoreLoader.defaultLibPath}`) + CoreLoader.libPath = CoreLoader.defaultLibPath + if (!existsSync(CoreLoader.libPath)) mkdirSync(CoreLoader.libPath) + } + if (path.isAbsolute(CoreLoader.libPath)) { + CoreLoader.libPath = path.resolve(CoreLoader.libPath) + storage.set(CoreLoader.libPathKey, CoreLoader.libPath) + } + this.callback = koffi.register(callbackHandle, AsstApiCallback) } /** @@ -111,12 +82,9 @@ class CoreLoader { this.Destroy(uuid) } try { - this.DLib.close() + this.lib?.unload() } catch (e) { - logger.error('close core error') - } - for (const dep of this.DepLibs) { - dep.close() + logger.error(e) } CoreLoader.loadStatus = false } @@ -131,174 +99,15 @@ class CoreLoader { } try { CoreLoader.loadStatus = true - this.dependences[process.platform].forEach(lib => { - this.DepLibs.push(ffi.DynamicLibrary(path.join(getComponentBaseDir(), 'core', lib))) - }) - this.DLib = ffi.DynamicLibrary( - path.join(getComponentBaseDir(), 'core', this.libName[process.platform]), - ffi.RTLD_NOW - ) - this.MeoAsstLib = { - AsstSetUserDir: ffi.ForeignFunction( - this.DLib.get('AsstSetUserDir'), - BoolType, - [StringType], - ffi.FFI_STDCALL - ), - - AsstLoadResource: ffi.ForeignFunction( - this.DLib.get('AsstLoadResource'), - BoolType, - [StringType], - ffi.FFI_STDCALL - ), - - AsstSetStaticOption: ffi.ForeignFunction( - this.DLib.get('AsstSetStaticOption'), - BoolType, - [IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstCreate: ffi.ForeignFunction( - this.DLib.get('AsstCreate'), - AsstPtrType, - [], - ffi.FFI_STDCALL - ), - - AsstCreateEx: ffi.ForeignFunction( - this.DLib.get('AsstCreateEx'), - AsstPtrType, - ['pointer', CustomArgsType], - ffi.FFI_STDCALL - ), - - AsstDestroy: ffi.ForeignFunction( - this.DLib.get('AsstDestroy'), - VoidType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstSetInstanceOption: ffi.ForeignFunction( - this.DLib.get('AsstSetInstanceOption'), - BoolType, - [AsstPtrType, IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstConnect: ffi.ForeignFunction( - this.DLib.get('AsstConnect'), - BoolType, - [AsstPtrType, StringType, StringType, StringType], - ffi.FFI_STDCALL - ), - - AsstAppendTask: ffi.ForeignFunction( - this.DLib.get('AsstAppendTask'), - IntType, - [AsstPtrType, StringType, StringType], - ffi.FFI_STDCALL - ), - - AsstSetTaskParams: ffi.ForeignFunction( - this.DLib.get('AsstSetTaskParams'), - BoolType, - [AsstPtrType, IntType, StringType], - ffi.FFI_STDCALL - ), - - AsstStart: ffi.ForeignFunction( - this.DLib.get('AsstStart'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstStop: ffi.ForeignFunction( - this.DLib.get('AsstStop'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstRunning: ffi.ForeignFunction( - this.DLib.get('AsstRunning'), - BoolType, - [AsstPtrType], - ffi.FFI_STDCALL - ), - - AsstAsyncConnect: ffi.ForeignFunction( - this.DLib.get('AsstAsyncConnect'), - AsstAsyncCallIdType, - [AsstPtrType, StringType, StringType, StringType, BoolType], - ffi.FFI_STDCALL - ), - - AsstAsyncClick: ffi.ForeignFunction( - this.DLib.get('AsstAsyncClick'), - AsstAsyncCallIdType, - [AsstPtrType, IntType, IntType, BoolType], - ffi.FFI_STDCALL - ), - - AsstAsyncScreencap: ffi.ForeignFunction( - this.DLib.get('AsstAsyncScreencap'), - AsstAsyncCallIdType, - [AsstPtrType, BoolType], - ffi.FFI_STDCALL - ), - - AsstGetImage: ffi.ForeignFunction( - this.DLib.get('AsstGetImage'), - ULLType, - [AsstPtrType, Buff, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetUUID: ffi.ForeignFunction( - this.DLib.get('AsstGetUUID'), - ULLType, - [AsstPtrType, StringType, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetTasksList: ffi.ForeignFunction( - this.DLib.get('AsstGetTasksList'), - ULLType, - [AsstPtrType, IntPointerType, ULLType], - ffi.FFI_STDCALL - ), - - AsstGetNullSize: ffi.ForeignFunction( - this.DLib.get('AsstGetNullSize'), - ULLType, - [], - ffi.FFI_STDCALL - ), - - AsstGetVersion: ffi.ForeignFunction( - this.DLib.get('AsstGetVersion'), - StringType, - [], - ffi.FFI_STDCALL - ), - - AsstLog: ffi.ForeignFunction( - this.DLib.get('AsstLog'), - VoidType, - [StringType, StringType], - ffi.FFI_STDCALL - ), - } + this.lib = loadLibrary(path.join(CoreLoader.libPath, 'MaaCore')) + this.func = load(this.lib) + + const version = this.GetCoreVersion() if (version) { logger.info(`core loaded: version ${version}`) } } catch (error) { - // console.error() logger.error((error as Error).message) this.dispose() } @@ -315,7 +124,7 @@ class CoreLoader { logger.warn(`[LoadResource] path not exists ${path}`) return false } - return this.MeoAsstLib.AsstLoadResource(corePath) + return this.func.AsstLoadResource(corePath ?? CoreLoader.libPath) } /** @@ -323,7 +132,7 @@ class CoreLoader { * @returns 实例指针{ref.Pointer} */ public Create(): boolean { - this.MeoAsstPtr.placeholder = this.MeoAsstLib.AsstCreate() + this.MeoAsstPtr.placeholder = this.func.AsstCreate() return !!this.MeoAsstPtr.placeholder } @@ -336,11 +145,11 @@ class CoreLoader { */ public CreateEx( uuid: string, - callback: any = callbackHandle, - customArg: any = createVoidPointer() + // callback: any = this.callBackHandle, + // customArg: any = 0 ): boolean { if (!this.MeoAsstPtr[uuid]) { - this.MeoAsstPtr[uuid] = this.MeoAsstLib.AsstCreateEx(callback, customArg) + this.MeoAsstPtr[uuid] = this.func.AsstCreateEx(this.callback, 0) return true } return false // 重复创建 @@ -352,17 +161,12 @@ class CoreLoader { */ public Destroy(uuid: string): void { if (this.MeoAsstPtr[uuid]) { - this.MeoAsstLib.AsstDestroy(this.MeoAsstPtr[uuid]) + this.func.AsstDestroy(this.MeoAsstPtr[uuid]) // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.MeoAsstPtr[uuid] } } - /** @deprecated 已废弃,将在接下来的版本中移除 */ - public Connect(address: string, uuid: string, adbPath: string, config: string): boolean { - return this.MeoAsstLib.AsstConnect(this.MeoAsstPtr[uuid], `"${adbPath}"`, address, config) - } - /** * @description 连接 * @param address 连接地址 @@ -379,12 +183,12 @@ class CoreLoader { config: string, block: boolean = false ): number { - return this.MeoAsstLib.AsstAsyncConnect( + return this.func.AsstAsyncConnect( this.MeoAsstPtr[uuid], `"${adbPath}"`, address, config, - block + block == true ? 1 : 0 ) } @@ -396,7 +200,7 @@ class CoreLoader { * @returns */ public AppendTask(uuid: string, type: string, params: string): number { - return this.MeoAsstLib.AsstAppendTask(this.GetCoreInstanceByUUID(uuid), type, params) + return this.func.AsstAppendTask(this.GetCoreInstanceByUUID(uuid), type, params) } /** @@ -407,7 +211,7 @@ class CoreLoader { */ public SetTaskParams(uuid: string, taskId: number, params: string): boolean { - return this.MeoAsstLib.AsstSetTaskParams(this.GetCoreInstanceByUUID(uuid), taskId, params) + return this.func.AsstSetTaskParams(this.GetCoreInstanceByUUID(uuid), taskId, params) } /** @@ -416,7 +220,7 @@ class CoreLoader { * @returns 是否成功 */ public Start(uuid: string): boolean { - return this.MeoAsstLib.AsstStart(this.GetCoreInstanceByUUID(uuid)) + return this.func.AsstStart(this.GetCoreInstanceByUUID(uuid)) } /** @@ -429,20 +233,8 @@ class CoreLoader { logger.warn(`[Stop] uuid not exists ${uuid}`) return true } - return this.MeoAsstLib.AsstStop(this.GetCoreInstanceByUUID(uuid)) + return this.func.AsstStop(this.GetCoreInstanceByUUID(uuid)) } - - /** - * 发送点击 - * @param uuid 设备唯一标识符 - * @param x x坐标 - * @param y y坐标 - * @returns - */ - public Click(uuid: string, x: number, y: number): boolean { - return this.MeoAsstLib.AsstClick(this.GetCoreInstanceByUUID(uuid), x, y) - } - /** * 异步请求截图, 在回调中取得截图完成事件后再使用GetImage获取截图 * @param uuid @@ -451,7 +243,7 @@ class CoreLoader { */ public AsyncScreencap(uuid: string, block: boolean = true): number | boolean { if (!this.MeoAsstPtr[uuid]) return false - return this.MeoAsstLib.AsstAsyncScreencap(this.GetCoreInstanceByUUID(uuid), block) + return this.func.AsstAsyncScreencap(this.GetCoreInstanceByUUID(uuid), block) } public GetImage(uuid: string): string { @@ -459,7 +251,7 @@ class CoreLoader { this.screenshotCache[uuid] = Buffer.alloc(5114514) } const buffer = this.screenshotCache[uuid] - const len = this.MeoAsstLib.AsstGetImage( + const len = this.func.AsstGetImage( this.GetCoreInstanceByUUID(uuid), buffer, buffer.length @@ -475,19 +267,20 @@ class CoreLoader { */ public GetCoreVersion(): string | null { if (!this.loadStatus) return null - return this.MeoAsstLib.AsstGetVersion() + return this.func.AsstGetVersion() } - public GetCoreInstanceByUUID(uuid: string): AsstInstancePtr { + public GetCoreInstanceByUUID(uuid: string): any { + console.log('type of this.MeoAsstPtr[uuid]', typeof this.MeoAsstPtr[uuid]) return this.MeoAsstPtr[uuid] } public Log(level: string, message: string): void { - return this.MeoAsstLib.AsstLog(level, message) + return this.func.AsstLog(level, message) } public SetInstanceOption(uuid: string, key: InstanceOptionKey, value: string): boolean { - return this.MeoAsstLib.AsstSetInstanceOption(this.GetCoreInstanceByUUID(uuid), key, value) + return this.func.AsstSetInstanceOption(this.GetCoreInstanceByUUID(uuid), key, value) } public SetTouchMode(uuid: string, mode: TouchMode): boolean { diff --git a/packages/main/coreLoader/types.ts b/packages/main/coreLoader/types.ts new file mode 100644 index 00000000..146a63af --- /dev/null +++ b/packages/main/coreLoader/types.ts @@ -0,0 +1,29 @@ +import type { AsstMsg } from '@type/task/callback' +import koffi from 'koffi' + +export const AsstExtAPI = koffi.opaque('AsstExtAPI') +export const AsstHandle = koffi.alias('AsstHandle', 'AsstExtAPI*') +export type AsstHandle = unknown + +export const AsstBool = koffi.alias('AsstBool', 'uint8') +export const AsstSize = koffi.alias('AsstSize', 'uint64') + +export const AsstId = koffi.alias('AsstId', 'int32') +export const AsstMsgId = koffi.alias('AsstMsgId', 'AsstId') +export const AsstTaskId = koffi.alias('AsstTaskId', 'AsstId') +export type AsstTaskId = number +export const AsstAsyncCallId = koffi.alias('AsstAsyncCallId', 'AsstId') + +export const AsstOptionKey = koffi.alias('AsstOptionKey', 'int32') +export const AsstStaticOptionKey = koffi.alias('AsstStaticOptionKey', 'AsstOptionKey') +export const AsstInstanceOptionKey = koffi.alias('AsstInstanceOptionKey', 'AsstOptionKey') + +export const AsstApiCallback_Prototype = koffi.proto( + 'void AsstApiCallback_Prototype(AsstMsgId msg, str details_json, intptr custom_arg)' +) + +export const AsstApiCallback = koffi.alias( + 'AsstApiCallback', + koffi.pointer(AsstApiCallback_Prototype) +) +export type AsstApiCallback = (msg: AsstMsg, details_json: string, custom_arg: unknown) => void \ No newline at end of file diff --git a/packages/main/coreLoader/utils.ts b/packages/main/coreLoader/utils.ts new file mode 100644 index 00000000..00fd73e3 --- /dev/null +++ b/packages/main/coreLoader/utils.ts @@ -0,0 +1,45 @@ +import koffi from 'koffi' +import path from 'path' + +type AcceptPlatform = 'win32' | 'linux' | 'darwin' + +const plat = process.platform as AcceptPlatform + +const libName: Record string> = { + win32: (d, l) => path.join(d, `${l}.dll`), + linux: (d, l) => path.join(d, `lib${l}.so`), + darwin: (d, l) => path.join(d, `lib${l}.dylib`) +} + +let win_dll_paths: string[] | null = null + +export function loadLibrary(file: string) { + const dir = path.resolve(path.dirname(file)) + const lib = path.basename(file) + + if (plat === 'win32') { + const kernel = koffi.load('kernel32.dll') + if (!win_dll_paths) { + kernel.stdcall('int32 SetDefaultDllDirectories(uint32)')(0x1000) + win_dll_paths = [] + } + if (!win_dll_paths.includes(dir)) { + kernel.stdcall('int32 AddDllDirectory(str16)')(dir) + win_dll_paths.push(dir) + } + } + + return koffi.load(libName[plat](dir, lib)) +} + +export type PromiseInfo = { + resolve: (state: T) => void + promise: Promise +} +export function getPromise(): PromiseInfo { + const result: Partial> = {} + result.promise = new Promise(resolve => { + result.resolve = resolve + }) + return result as PromiseInfo +} diff --git a/packages/main/hooks/asst.ts b/packages/main/hooks/asst.ts index f55d26e6..d020233e 100644 --- a/packages/main/hooks/asst.ts +++ b/packages/main/hooks/asst.ts @@ -20,17 +20,6 @@ const hooks: IpcMainHandleEventCalleeProxy['CoreLoader'] = { core.Destroy(uuid) return true }, - connect({ address, uuid, adb_path, config }) { - return core.Connect(address, uuid, adb_path, config) - }, - /** @Deprecated */ - initCore(arg) { - const createStatus = core.CreateEx(arg.uuid) ?? false - if (!createStatus) logger.warn(`重复创建 ${JSON.stringify(arg)}`) - if (!core.SetTouchMode(arg.uuid, arg.touch_mode)) - logger.warn('Set touch mode failed', arg.touch_mode) - return core.Connect(arg.address, arg.uuid, arg.adb_path, arg.config) - }, initCoreAsync(arg) { const createStatus = core.CreateEx(arg.uuid) ?? false if (!createStatus) logger.warn(`重复创建 ${JSON.stringify(arg)}`) diff --git a/packages/main/vite.config.ts b/packages/main/vite.config.ts index 9bc2bd25..779cb409 100644 --- a/packages/main/vite.config.ts +++ b/packages/main/vite.config.ts @@ -26,7 +26,7 @@ export default defineConfig({ sourcemap: true, emptyOutDir: true, rollupOptions: { - external: ['electron', ...builtinModules, ...Object.keys(pkg.dependencies || {})], + external: ['electron', ...builtinModules, ...Object.keys(pkg.dependencies || {}), 'koffi'], }, }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1bce7757..fece0e72 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,16 +1,10 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' settings: autoInstallPeers: true excludeLinksFromLockfile: false dependencies: - '@tigerconnect/ffi-napi': - specifier: 4.0.3-tc3 - version: 4.0.3-tc3 - '@tigerconnect/ref-napi': - specifier: 4.0.0-tc8 - version: 4.0.0-tc8 axios: specifier: ^1.4.0 version: 1.4.0 @@ -32,6 +26,9 @@ dependencies: iconv-lite: specifier: ^0.6.3 version: 0.6.3 + koffi: + specifier: ^2.6.3 + version: 2.6.3 ps-list: specifier: ^8.1.1 version: 8.1.1 @@ -151,9 +148,15 @@ devDependencies: electron-devtools-installer: specifier: ^3.2.0 version: 3.2.0 + electron-rebuild: + specifier: ^3.2.9 + version: 3.2.9 exponential-backoff: specifier: ^3.1.1 version: 3.1.1 + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 less: specifier: ^4.1.3 version: 4.1.3 @@ -1484,7 +1487,7 @@ packages: '@electron-forge/shared-types': 6.4.0 fs-extra: 10.1.0 optionalDependencies: - electron-winstaller: 5.1.0 + electron-winstaller: 5.1.2 transitivePeerDependencies: - bluebird - enquirer @@ -2296,37 +2299,6 @@ packages: defer-to-connect: 2.0.1 dev: true - /@tigerconnect/ffi-napi@4.0.3-tc3: - resolution: {integrity: sha512-wHzQFyBBmK/9Mf0jIgALtyxQPTWxSG7PUysQO/Qiu0Z/zOTGi8mNi4qmTjlWanmDa3AClt4XsgaUD8TivU/Mlg==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - '@tigerconnect/ref-napi': 4.0.0-tc8 - '@types/node': 18.16.16 - '@types/ref-struct-di': 1.1.9 - debug: 4.3.4 - get-uv-event-loop-napi-h: 1.0.6 - node-addon-api: 3.2.1 - node-gyp-build: 4.6.0 - ref-struct-di: 1.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@tigerconnect/ref-napi@4.0.0-tc8: - resolution: {integrity: sha512-KbdXLRQPHQsZEW0AO5VJ836EGbfat4lNIXYmm8nPQPHJGN14/wWq3a+1E0pRuQ28I6YtX0cTM6lW8e59zjdsEA==} - engines: {node: '>= 10.0'} - requiresBuild: true - dependencies: - '@types/node': 18.16.16 - debug: 4.3.4 - get-symbol-from-current-process-h: 1.0.2 - node-addon-api: 4.3.0 - node-gyp-build: 4.6.0 - transitivePeerDependencies: - - supports-color - dev: false - /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -2439,16 +2411,19 @@ packages: /@types/node@18.16.16: resolution: {integrity: sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==} + dev: true /@types/ref-napi@3.0.7: resolution: {integrity: sha512-CzPwr36VkezSpaJGdQX/UrczMSDsDgsWQQFEfQkS799Ft7n/s183a53lsql7RwVq+Ik4yLEgI84pRnLC0XXRlA==} dependencies: '@types/node': 18.16.16 + dev: true /@types/ref-struct-di@1.1.9: resolution: {integrity: sha512-B1FsB1BhG1VLx0+IqBaAPXEPH0wCOb+Glaaw/i+nRUwDKFtSqWOziGnTRw05RyrBbrDsMiM0tVWmaujrs016Sw==} dependencies: '@types/ref-napi': 3.0.7 + dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} @@ -2494,8 +2469,8 @@ packages: resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} dev: true - /@types/yauzl@2.10.0: - resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} + /@types/yauzl@2.10.2: + resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==} requiresBuild: true dependencies: '@types/node': 18.16.16 @@ -3099,7 +3074,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /chownr@2.0.0: @@ -3431,6 +3406,8 @@ packages: optional: true dependencies: ms: 2.1.3 + dev: true + optional: true /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -3442,6 +3419,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: true /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -3607,7 +3585,7 @@ packages: fs-extra: 9.1.0 get-folder-size: 2.0.1 lodash: 4.17.21 - word-wrap: 1.2.3 + word-wrap: 1.2.5 yargs: 16.2.0 transitivePeerDependencies: - supports-color @@ -3626,7 +3604,7 @@ packages: electron-installer-common: 0.10.3 fs-extra: 9.1.0 lodash: 4.17.21 - word-wrap: 1.2.3 + word-wrap: 1.2.5 yargs: 16.2.0 transitivePeerDependencies: - supports-color @@ -3661,6 +3639,31 @@ packages: - supports-color dev: true + /electron-rebuild@3.2.9: + resolution: {integrity: sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==} + engines: {node: '>=12.13.0'} + deprecated: Please use @electron/rebuild moving forward. There is no API change, just a package name change + hasBin: true + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + chalk: 4.1.2 + debug: 4.3.4 + detect-libc: 2.0.1 + fs-extra: 10.1.0 + got: 11.8.6 + lzma-native: 8.0.6 + node-abi: 3.43.0 + node-api-version: 0.1.4 + node-gyp: 9.3.1 + ora: 5.4.1 + semver: 7.5.1 + tar: 6.1.15 + yargs: 17.7.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: true + /electron-squirrel-startup@1.0.0: resolution: {integrity: sha512-Oce8mvgGdFmwr+DsAcXBmFK8jFfN6yaFAP9IvyhTfupM3nFkBku/7VS/mdtJteWumImkC6P+BKGsxScoDDkv9Q==} dependencies: @@ -3676,8 +3679,8 @@ packages: type-fest: 2.19.0 dev: false - /electron-winstaller@5.1.0: - resolution: {integrity: sha512-4wlZzkUm5cJNiOtp5wL804+QpygdKTKkrZJXA3sSDEI2XnCVPv0kxmxUvVw4KHBwbNS+Yox89agEr+VkR7kxww==} + /electron-winstaller@5.1.2: + resolution: {integrity: sha512-SJ+iTiXcKodXP4hHtvRtLOd0vtV5Z0mWjvf3JULQiGuZOoldDm5RLyl3I45Tyg6lC9S+DPsCx6gd4JILt08VXA==} engines: {node: '>=8.0.0'} requiresBuild: true dependencies: @@ -3982,7 +3985,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.10.0 + '@types/yauzl': 2.10.2 transitivePeerDependencies: - supports-color dev: true @@ -4189,8 +4192,8 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -4304,16 +4307,6 @@ packages: engines: {node: '>=10'} dev: false - /get-symbol-from-current-process-h@1.0.2: - resolution: {integrity: sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==} - dev: false - - /get-uv-event-loop-napi-h@1.0.6: - resolution: {integrity: sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==} - dependencies: - get-symbol-from-current-process-h: 1.0.2 - dev: false - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -4802,6 +4795,11 @@ packages: json-buffer: 3.0.1 dev: true + /koffi@2.6.3: + resolution: {integrity: sha512-UGkH8u91YqHteas8YCwFAW0HKBcBfYJvpbGdf1n4sqeFaDatACuy4TF4hDbbKB8sHrfk95G/Q1wWvPg4pfzxfA==} + requiresBuild: true + dev: false + /less@4.1.3: resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} engines: {node: '>=6'} @@ -4978,6 +4976,17 @@ packages: engines: {node: '>=12'} dev: true + /lzma-native@8.0.6: + resolution: {integrity: sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==} + engines: {node: '>=10.0.0'} + hasBin: true + requiresBuild: true + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.6.1 + readable-stream: 3.6.2 + dev: true + /magic-string@0.30.0: resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} engines: {node: '>=12'} @@ -5233,9 +5242,11 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true /muggle-string@0.2.2: resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==} @@ -5305,11 +5316,7 @@ packages: /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - dev: false - - /node-addon-api@4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - dev: false + dev: true /node-api-version@0.1.4: resolution: {integrity: sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==} @@ -5329,10 +5336,10 @@ packages: whatwg-url: 5.0.0 dev: true - /node-gyp-build@4.6.0: - resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} hasBin: true - dev: false + dev: true /node-gyp@9.3.1: resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} @@ -5456,7 +5463,7 @@ packages: levn: 0.3.0 prelude-ls: 1.1.2 type-check: 0.3.2 - word-wrap: 1.2.3 + word-wrap: 1.2.5 dev: true /ora@5.4.1: @@ -5883,14 +5890,6 @@ packages: resolve: 1.22.2 dev: true - /ref-struct-di@1.1.1: - resolution: {integrity: sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==} - dependencies: - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: false - /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} dev: true @@ -6004,7 +6003,7 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /rotating-file-stream@3.1.0: @@ -6679,7 +6678,7 @@ packages: postcss: 8.4.24 rollup: 3.23.1 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /vooks@0.2.12(vue@3.3.4): @@ -6836,8 +6835,8 @@ packages: string-width: 4.2.3 dev: true - /word-wrap@1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} dev: true diff --git a/scripts/watch.mjs b/scripts/watch.mjs index 9a4a07fd..6686c367 100644 --- a/scripts/watch.mjs +++ b/scripts/watch.mjs @@ -1,6 +1,10 @@ import { spawn } from 'child_process' import electron from 'electron' import { build, createServer } from 'vite' +import path from 'path' +import fs from 'fs-extra' +import { fileURLToPath } from 'url'; + let aliveInst = 0 let quitTimer = null @@ -52,6 +56,7 @@ function watchMain(server) { startQuit() } }) + }, }, ], @@ -82,6 +87,13 @@ function watchPreload(server) { }) } +function installKoffiBinaries() { + const currentDir = path.dirname(fileURLToPath(import.meta.url)); + console.log(currentDir) + fs.copySync(path.resolve(currentDir, '../node_modules/koffi/build'), path.resolve(currentDir, '../node_modules/electron/dist/resources')); +} + +// installKoffiBinaries() // bootstrap const server = await createServer({ configFile: 'packages/renderer/vite.config.ts', From fc86b656837d949749abb75d47d9a5a536708d42 Mon Sep 17 00:00:00 2001 From: bakashigure Date: Fri, 27 Oct 2023 00:12:13 +0800 Subject: [PATCH 3/6] =?UTF-8?q?chore:=20=E5=BC=95=E5=85=A5cross-env?= =?UTF-8?q?=E4=BF=AE=E6=94=B9node=E5=86=85=E5=AD=98=E4=B8=8A=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- forge.config.js | 2 +- package.json | 19 ++++++++++--------- pnpm-lock.yaml | 11 +++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/forge.config.js b/forge.config.js index 7561d4f8..a9eb6478 100644 --- a/forge.config.js +++ b/forge.config.js @@ -20,7 +20,7 @@ module.exports = { } return true }, - // asar: true, + asar: true, }, rebuildConfig: { buildPath: __dirname, diff --git a/package.json b/package.json index bffaba07..571f9dcd 100644 --- a/package.json +++ b/package.json @@ -6,15 +6,15 @@ "templateBy": "草鞋没号 <308487730@qq.com>", "license": "AGPL-3.0-or-later", "scripts": { - "dev": "node scripts/watch.mjs", - "prebuild": "vue-tsc --project packages/renderer/tsconfig.json --noEmit && node --max-old-space-size=4096 scripts/build.mjs", - "debug": "npm run prebuild && vite ./packages/renderer", - "lint": "eslint --ext .js,.ts,.vue --fix packages/main packages/renderer", - "make": "electron-forge make", - "start": "electron-forge start", - "package": "electron-forge package", - "publish": "electron-forge publish", - "format": "npx prettier -w ." + "dev": "cross-env NODE_OPTIONS=--max-old-space-size=8192 node scripts/watch.mjs", + "prebuild": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vue-tsc --project packages/renderer/tsconfig.json --noEmit && node scripts/build.mjs", + "debug": "cross-env NODE_OPTIONS=--max-old-space-size=8192 npm run prebuild && vite ./packages/renderer", + "lint": "cross-env NODE_OPTIONS=--max-old-space-size=8192 eslint --ext .js,.ts,.vue --fix packages/main packages/renderer", + "make": "cross-env NODE_OPTIONS=--max-old-space-size=8192 electron-forge make", + "start": "cross-env NODE_OPTIONS=--max-old-space-size=8192 electron-forge start", + "package": "cross-env NODE_OPTIONS=--max-old-space-size=8192 electron-forge package", + "publish": "cross-env NODE_OPTIONS=--max-old-space-size=8192 electron-forge publish", + "format": "cross-env NODE_OPTIONS=--max-old-space-size=8192 npx prettier -w ." }, "engines": { "node": ">=18.12.0" @@ -49,6 +49,7 @@ "clipboard": "^2.0.11", "color2k": "^2.0.2", "cron-parser": "^4.8.1", + "cross-env": "^7.0.3", "date-fns": "^2.30.0", "electron": "^26.0.0", "electron-devtools-installer": "^3.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fece0e72..6cb22e9d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -139,6 +139,9 @@ devDependencies: cron-parser: specifier: ^4.8.1 version: 4.8.1 + cross-env: + specifier: ^7.0.3 + version: 7.0.3 date-fns: specifier: ^2.30.0 version: 2.30.0 @@ -3271,6 +3274,14 @@ packages: luxon: 3.3.0 dev: true + /cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + dev: true + /cross-spawn-windows-exe@1.2.0: resolution: {integrity: sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==} engines: {node: '>= 10'} From 40790ccb25a1c95a25118ad9af82e1498a62b603 Mon Sep 17 00:00:00 2001 From: bakashigure Date: Fri, 27 Oct 2023 00:12:34 +0800 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20koffi=E6=8E=A5=E5=8F=A3=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/main/coreLoader/index.ts | 3 ++- packages/main/hooks/asst.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/main/coreLoader/index.ts b/packages/main/coreLoader/index.ts index 2611379e..3cf316a2 100644 --- a/packages/main/coreLoader/index.ts +++ b/packages/main/coreLoader/index.ts @@ -25,9 +25,10 @@ const storage = new Storage() @Singleton class CoreLoader { + public static libPath: string + private lib!: koffi.IKoffiLib private func!: MaaCoreExports - private static libPath: string private static readonly libPathKey = 'libPath' private static readonly defaultLibPath = path.join(getAppBaseDir(), 'core') private static loadStatus: boolean // core加载状态 diff --git a/packages/main/hooks/asst.ts b/packages/main/hooks/asst.ts index d020233e..5d42db6f 100644 --- a/packages/main/hooks/asst.ts +++ b/packages/main/hooks/asst.ts @@ -49,7 +49,7 @@ const hooks: IpcMainHandleEventCalleeProxy['CoreLoader'] = { logger.silly('core unloaded, return empty supported stages') return [] } - const jsonPath = path.join(core.libPath, 'resource/tasks.json') + const jsonPath = path.join(CoreLoader.libPath, 'resource/tasks.json') const tasks = JSON.parse(String(fs.readFileSync(jsonPath))) const stages = Object.keys(tasks).filter(s => /[A-Z0-9]+-([A-Z0-9]+-?)?[0-9]/.test(s)) return stages @@ -58,7 +58,7 @@ const hooks: IpcMainHandleEventCalleeProxy['CoreLoader'] = { return core.GetImage(uuid) }, getLibPath() { - return core.libPath + return CoreLoader.libPath }, changeTouchMode({ mode }) { return core.ChangeTouchMode(mode) From 4e5203a1943b88c80800e7dee4fc3185d1426b41 Mon Sep 17 00:00:00 2001 From: bakashigure Date: Fri, 27 Oct 2023 00:15:46 +0800 Subject: [PATCH 5/6] =?UTF-8?q?perf:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/watch.mjs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scripts/watch.mjs b/scripts/watch.mjs index 6686c367..d9a0641d 100644 --- a/scripts/watch.mjs +++ b/scripts/watch.mjs @@ -87,13 +87,6 @@ function watchPreload(server) { }) } -function installKoffiBinaries() { - const currentDir = path.dirname(fileURLToPath(import.meta.url)); - console.log(currentDir) - fs.copySync(path.resolve(currentDir, '../node_modules/koffi/build'), path.resolve(currentDir, '../node_modules/electron/dist/resources')); -} - -// installKoffiBinaries() // bootstrap const server = await createServer({ configFile: 'packages/renderer/vite.config.ts', From f9789bb993317d68d5a113fae935cc1b18c59ce8 Mon Sep 17 00:00:00 2001 From: bakashigure Date: Fri, 27 Oct 2023 03:49:17 +0000 Subject: [PATCH 6/6] =?UTF-8?q?chore:=20=E5=8F=96=E6=B6=88asar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- forge.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge.config.js b/forge.config.js index a9eb6478..7561d4f8 100644 --- a/forge.config.js +++ b/forge.config.js @@ -20,7 +20,7 @@ module.exports = { } return true }, - asar: true, + // asar: true, }, rebuildConfig: { buildPath: __dirname,