教程:Nodejs大漠插件开发游戏脚本实战(三)注册大漠插件

一、准备大漠插件

因为大漠插件的特殊性,官网的下载通道也关闭了,我是从某宝买的,发货的时候也会直接发下载链接。解压之后得到完整目录,主要包括了模块.dllAPI说明、还有综合工具(用于抓图、制作字库等)
大漠插件目录
我们程序里面主要是需要这个dm.dll文件,其他工具只会在开发的时候用到。另外说明的是,大漠插件是支持免注册dll到系统的方案,但是这个教程我只讲传统的注册方式。

二、注册大漠插件到系统

1.把dm.dll保存到项目中

上一篇文章中,我们配置了一个library的文件夹,用于存放我们的dll动态库的。我们把dm.dll拉到项目里面去。
library

2.手动注册大漠插件到系统

随后我们编写一个批处理(.bat)文件,reg.bat用于注册dm插件

%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
cd /d "%~dp0"
regsvr32 dm.dll

当我们使用管理员身份运行这个bat,就可以把大漠插件注册到系统
大漠插件注册成功
同理。我们卸载大漠插件的的脚本

# 同上
regsvr32 /u dm.dll

接下来我们只需要用nodejs的child_process去调用这个bat就可以了

三、在Electron中引用大漠插件

0.安装windows构建工具

1.安装chocolatey

Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

2.安装build-tools

choco install python visualcpp-build-tools -y

3.设置msvs_version

npm config set msvs_version 2017
1.安装node-activex

前面已经介绍过这个模块了,这里就再介绍了,值得注意的是COM的变量类型,在之后的课程会用到
COM的变量类型

我们在项目路径下使用npm去装这个库

npm install winax --save

如果在这一步编译失败,检查一下nodejs的版本是不是32位。如果windows-build-tools安装出错,这里也是必然出错的。根据打印的错误堆栈检查一下就好了

2.Electron rebuild
npm install --save-dev electron-rebuild
.\node_modules\.bin\electron-rebuild.cmd
3.编写一个配置文件

因为Electron中,我们打包之后的路径跟开发环境的路径不尽相同。而且我们在编写一个pc应用的时候,应该要考虑到我们一些数据存放的文件夹。参考微信的pc端,微信会在文档里面建一个Wechat Files存放聊天记录的文件以及图片缓存。所以我们的配置文件也应该包含这些内容

// src/main/config.ts
import isDevelop from 'electron-is-dev'
const path = require('path')
const fs = require('fs')
const os = require('os')
// 文档里面建一个存放程序数据的文件夹
const baseDir = os.homedir() + '\\Documents\\Ai_QQSG'
if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir)
// 这个是我们存放dm.dll以及其他依赖的文件夹 判断一下是开发环境还是生产环境
const libDir = path.join(__dirname, isDevelop ? '../../src/main/library' : '../../../library')
export { libDir, baseDir }

这样,我们使用这个library文件的时候,直接按照config里面libDir路径就好了

4.编写大漠类

接下来我们在main目录里面建一个modules文件夹,新建文件dm.ts

// src/main/modules/dm.ts
import cp from 'child_process'
import { libDir } from '../config'
const winax = require('winax')
export default class {
    dll
    variant
    constructor() {
        // 注入dll
        try {
            this.dll = new winax.Object('dm.dmsoft')
            this.variant = winax.Variant
            this.reg()
        } catch (error) {
        	// 这里执行的就是我们编写的注册把大漠插件注册到系统的批处理文件
            cp.execFileSync(libDir + '\\reg.bat')
            setTimeout(() => {
                this.dll = new winax.Object('dm.dmsoft')
                this.variant = winax.Variant
                this.reg()
            }, 3000)
        }
    }
    reg() {
        // 注册大漠插件(主要是大漠插件收费的校验)
        const regResult = this.dll.Reg("大漠插件的注册码", "大漠插件的注册账号")
        console.log('大漠插件注册: ', regResult)
        console.log('大漠插件版本:', this.dll.Ver())
        console.log('大漠插件路径:', this.dll.GetBasePath())
        // 这里是字库的文件,我们后面说到
        // const textPath = `${libDir}\\text\\ocr.txt`
        // console.log('字库设置:', this.dll.SetDict(0, textPath))
    }
}

这样,每当我们new一个dm类的时候,就会自动注册大漠插件,并且得到一个大漠插件的实例

四、使用大漠插件后台绑定窗体

通过上面的准备,现在万事俱备,只欠东风

1.使用nodejs获取QQ三国进程

大漠插件也支持通过窗口名称找到窗口句柄,但是这里我用nodejs去遍历进程。
我们打开index.ts,找到Electron的appReady生命周期钩子, 在app.whenReady()的回调方法中加入以下代码,这里用到了Electron的系统通知(Notification )功能,有兴趣的可以阅读Electron的官方文档,基础使用参考下面代码就可以

import { app, BrowserWindow, ipcMain, Notification } from 'electron'
declare global {
  namespace NodeJS {
    interface Global {
      clients: any; // 所有的大漠插件客户端
    }
  }
}

...忽略其他代码...
app.whenReady().then(async () => {
  // electron创建窗口
  new createWin()
  // 通过tasklist遍历返回的进程信息
  cp.exec('tasklist', async function (error, stdout) {
    if (error) {
      console.log(error)
      return
    }
    if (!stdout) return
    const list = stdout.split('\n')
    for (const line of list) {
      const processMessage = line.trim().split(/\s+/)
      const processName = processMessage[0] // processMessage[0]进程名称 , processMessage[1]进程id
      if (processName === 'QQSG.exe') {
      	// 判断进程位QQSG.exe 拿到进程id
        const pid = parseInt(processMessage[1])
        // Electron的系统通知功能
        new Notification({ title: '注入QQ三国进程', body: pid.toString() }).show()
        // 一个进程新建一个大漠对象
        const clientDm = new Dm()
        // 通过大漠的api:根据pid获取窗口句柄
        const handle = clientDm.dll.FindWindowByProcessId(pid, '', '')
        console.log('句柄: ', handle)
        if (!handle) {
          console.log('pid: ', pid, ' 找不到窗口句柄')
          continue
        }
        // 大漠插件后台绑定窗口 参数详情可以看大漠插件文档 如果是模拟器或者其他游戏,所需的参数不尽相同
        const bindResult = clientDm.dll.BindWindowEx(handle, 'gdi', 'windows', 'windows', 'dx.public.active.api', 0)
        console.log('后台绑定:', bindResult)
        if (!bindResult) {
          console.log('句柄', handle, ' 后台绑定失败')
          continue
        }
        // 绑定成功之后,我们可以利用global对象,把所有的客户端保存到一个map方便调用,用句柄作为key
        global.clients[handle] = { pid, dm: clientDm }
        // 测试移动窗口
        // clientDm.dll.MoveWindow(handle, 0, 0)
      }
    }
  })
})

之后我们就根据窗口句柄作为标识,去调用一些大漠插件的api操作窗口了,用不用的大漠对象方便对窗口同时操作

例如编写一个移动鼠标点击function:

function leftClick(handle: Number, x: Number, y: Number) {
	const { dm: { dll, variant }} = global.clients[handle.toString()]
	dll.MoveTo(x, y)
	dll.LeftClick()
	return { success: true, message: `Click :(${x},${y})` }
}

最后,我们使用大漠插件是需要将程序使用管理员运行的,我们打开package.json
在win下面,添加

"build": {
	...其他配置省略...
    "win": {
      "requestedExecutionLevel": "highestAvailable", // 程序使用管理员运行
      ...其他配置省略...
    },
  }

编写完成之后,npm run dev运行Electron程序,测试一下自己的操作
好了。下课

教程:Nodejs大漠插件开发游戏脚本实战(三)注册大漠插件


版权声明:本文为qq_39649991原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。