Skip to content

Auto.js 快速接入

本文提供完整的 Auto.js 接入示例,包含签名计算、卡密登录和心跳保活。

环境要求

  • Auto.js 4.x / Auto.js Pro
  • 需要网络权限

完整示例

javascript
// ========== 配置 ==========
var APP_KEY = "your_app_key";
var APP_SECRET = "your_app_secret";
var API_BASE = "http://api.nullverify.com/api/client/v1";

/**
 * 计算 MD5 签名
 */
function md5(str) {
    var digest = java.security.MessageDigest.getInstance("MD5");
    digest.update(new java.lang.String(str).getBytes("UTF-8"));
    var bytes = digest.digest();
    var hex = "";
    for (var i = 0; i < bytes.length; i++) {
        var b = bytes[i] & 0xff;
        hex += ("0" + b.toString(16)).slice(-2);
    }
    return hex;
}

/**
 * 计算请求签名
 */
function makeSign(params) {
    var keys = Object.keys(params).filter(function(k) { return k !== "sign"; }).sort();
    var sortedParams = keys.map(function(k) { return k + "=" + params[k]; }).join("&");
    var raw = sortedParams + APP_SECRET;
    return md5(raw);
}

/**
 * 生成公共参数
 */
function makeCommonParams() {
    return {
        app_key: APP_KEY,
        timestamp: Math.floor(Date.now() / 1000).toString(),
        nonce: java.util.UUID.randomUUID().toString()
    };
}

/**
 * 解析响应(自动处理加密)
 */
function parseResponse(resp) {
    var body = resp.body.string();
    // 尝试 JSON 解析,如果失败则为密文
    try {
        return JSON.parse(body);
    } catch (e) {
        // 加密响应:需先解密再解析
        // 请根据应用配置的加密算法实现解密逻辑
        throw new Error("加密响应需要解密,参考 /guide/response-encryption");
    }
}

/**
 * 卡密登录
 */
function cardLogin(card, deviceId) {
    var params = makeCommonParams();
    params.card = card;
    params.device_id = deviceId;
    params.sign = makeSign(params);

    var resp = http.post(API_BASE + "/card/login", params);
    return parseResponse(resp);
}

/**
 * 卡密心跳
 */
function cardHeartbeat(card, token) {
    var params = makeCommonParams();
    params.card = card;
    params.token = token;
    params.sign = makeSign(params);

    var resp = http.post(API_BASE + "/card/heartbeat", params);
    return parseResponse(resp);
}

/**
 * 卡密退出
 */
function cardLogout(card, token) {
    var params = makeCommonParams();
    params.card = card;
    params.token = token;
    params.sign = makeSign(params);

    var resp = http.post(API_BASE + "/card/logout", params);
    return parseResponse(resp);
}

// ========== 主流程 ==========
var CARD = "your_card_no";
var DEVICE_ID = device.getAndroidId();

// 1. 登录
var result = cardLogin(CARD, DEVICE_ID);
if (result.code !== 0) {
    toast("登录失败: " + result.message);
    exit();
}

var token = result.result.token;
var hg = result.result.hg || 30;
toast("登录成功,到期: " + result.result.expires);

// 2. 心跳保活
var heartbeatTimer = setInterval(function() {
    var hb = cardHeartbeat(CARD, token);
    if (hb.code !== 0) {
        toast("心跳失败: " + hb.message);
        clearInterval(heartbeatTimer);
        exit();
    }
    log("心跳正常,到期: " + hb.result.expires);
}, hg * 1000);

// 3. 脚本退出时清理
events.on("exit", function() {
    clearInterval(heartbeatTimer);
    cardLogout(CARD, token);
    log("已退出登录");
});

// ========== 你的业务逻辑 ==========
// 在此处编写你的自动化脚本...

关键说明

设备标识

Auto.js 中推荐使用 device.getAndroidId() 作为设备唯一标识:

javascript
var deviceId = device.getAndroidId();

MD5 签名

Auto.js 运行在 Android 环境,使用 Java 的 MessageDigest 计算 MD5:

javascript
function md5(str) {
    var digest = java.security.MessageDigest.getInstance("MD5");
    digest.update(new java.lang.String(str).getBytes("UTF-8"));
    var bytes = digest.digest();
    var hex = "";
    for (var i = 0; i < bytes.length; i++) {
        hex += ("0" + (bytes[i] & 0xff).toString(16)).slice(-2);
    }
    return hex;
}

响应处理

启用响应加密后,HTTP 响应体为纯密文字符串,不再是 JSON。客户端需先解密再解析:

javascript
var body = resp.body.string();
try {
    // 尝试直接解析 JSON(明文响应)
    var result = JSON.parse(body);
} catch (e) {
    // 密文响应:先解密再解析
    var plaintext = decrypt(body, encryptKey);
    var result = JSON.parse(plaintext);
}

详细解密实现请参考 响应加密

错误处理

javascript
var result = cardLogin(card, deviceId);
switch (result.code) {
    case 0:
        toast("登录成功");
        break;
    case 10210:
        toast("卡密已过期,请续费");
        exit();
    case 10213:
        toast("超过多开上限");
        exit();
    case 10218:
        toast("卡密不存在");
        exit();
    default:
        toast("错误: " + result.message);
        exit();
}

完整错误码列表请参考 错误码对照表

提示

建议将 APP_KEYAPP_SECRET 进行混淆处理,避免被直接提取。

面向脚本与插件开发者的网络验证系统