cocos2dx luajit相关

545 阅读3分钟

安装cocos studio后,当我们在命令行输入cocos

E:\cocosstudio\Cocos2d-x\cocos2d-x-3.10\tools\cocos2d-console\bin\/cocos.py 2.1 - cocos console: cocos2d-x 的命令行工具 集。

可用的命令:
        run              在设备或者模拟器上编译,部署和运行工程。
        gen-libs         生成引擎的预编译库。生成的库文件会保存在引擎根目录的 'prebuilt' 文件夹。
        luacompile       对 lua 文件进行加密和编译为字节码的处理。
        gui              shows the GUI
        deploy           编译并在设备或模拟器上部署工程。
        package          管理 cocos 中的 package。
        compile          编译并打包工程。
        framework        管理工程使用的 frameworks。
        gen-simulator    生成 Cocos 模拟器。
        new              创建一个新的工程。
        jscompile        对 js 文件进行加密和压缩处理。
        gen-templates    生成用于 Cocos Framework 环境的模板。

可用的参数:
        -h, --help                      显示帮助信息。
        -v, --version                   显示命令行工具的版本号。
        --ol ['en', 'zh', 'zh_tr']      指定输出信息的语言。

示例:
        cocos new --help
        cocos run --help
>cocos luacompile -h
usage: cocos luacompile [-h] [-v] [-s SRC_DIR_ARR] [-d DST_DIR] [-e]
                        [-k ENCRYPTKEY] [-b ENCRYPTSIGN] [--disable-compile]

对 lua 文件进行加密和编译为字节码的处理。

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         更多输出信息。
  -s SRC_DIR_ARR, --src SRC_DIR_ARR
                        指定需要编译的 lua 文件路径,支持指定多个路径。
  -d DST_DIR, --dst DST_DIR
                        指定输出文件的路径。
  -e, --encrypt         开启 XXTEA 加密功能。
  -k ENCRYPTKEY, --encryptkey ENCRYPTKEY
                        指定 XXTEA 加密功能的 key 字段。
  -b ENCRYPTSIGN, --encryptsign ENCRYPTSIGN
                        指定 XXTEA 加密功能的 sign 字段,其实就是:sign字段+加密后的数据
  --disable-compile     关闭编译为字节码的功能。

luajit的使用

>luajit.exe -h
usage: luajit.exe [options]... [script [args]...].
Available options are:
  -e chunk  Execute string 'chunk'.
  -l name   Require library 'name'.
  -b ...    Save or list bytecode.
  -j cmd    Perform LuaJIT control command.
  -O[opt]   Control LuaJIT optimizations.
  -i        Enter interactive mode after executing 'script'.
  -v        Show version information.
  -E        Ignore environment variables.
  --        Stop handling options.
  -         Execute stdin and stop handling options.

cocos console源码

  • cocos2d-console
    • bin
      • cocos.py: 命令行的源码,各个功能是通过插件注册到里面
    • plugins
      • plugin_luacompile: 对应的插件源码
        • __init__.py:插件入口
        • bin:存储luajit的加密工具
          • luajit.exe
          • lua51.dll
          • lua
            • luajit-linux
            • luajit-mac

调用luajit的相关代码

with cocos.pushd(self._luajit_dir):
    cmd_str = "\"%s\" -b \"%s\" \"%s\"" % (self._luajit_exe_path, lua_file, output_file)
    self._run_cmd(cmd_str)

简单说就是:

luajit.exe -b src/1.lua out/1.luac

项目中的用法

  • 外部脚本加密
call cocos luacompile 
    -s "%DIR%\src" 
    -d "%DIR%\1\src" 
    -e 
    -k mTWZh9lg8K8hRmi 
    -b xogame 
    --disable-compile
  • Android 项目中加密
#PROP_LUA_ENCRYPT=1
#PROP_LUA_ENCRYPT_KEY=mTWZh9lg8K8hRmi
#PROP_LUA_ENCRYPT_KEY_RES=TuwW9yCKTn7bQzK  
#PROP_LUA_ENCRYPT_SIGN=xogame
 def compileArgs = ['luacompile', '-s', srcDir, '-d', dstDir]
    if (!doCompile) {
        compileArgs << '--disable-compile'
    }
    else if (is64bit) {
        compileArgs << '--bytecode-64bit'
    }

    if (doEncrypt) {
        compileArgs << '-e'
        compileArgs << '-k'
        compileArgs << project.property('PROP_LUA_ENCRYPT_KEY')
        compileArgs << '-b'
        compileArgs << project.property('PROP_LUA_ENCRYPT_SIGN')
    }

PROP_LUA_ENCRYPT_KEY_RES在这里使用,

def compileRes(srcDir) {
    def compileArgs = ['-i', srcDir, '-o', srcDir]

    compileArgs << '-m'
    compileArgs << 'files'
    compileArgs << '-ek'
    compileArgs << project.property('PROP_LUA_ENCRYPT_KEY_RES')
    compileArgs << '-es'
    compileArgs << project.property('PROP_LUA_ENCRYPT_SIGN')

    exec {
        executable = project.file('../../../../pack_files.bat')
        args compileArgs
    }
}

而pack_files.bat最终调用到了一个php文件,技术栈是真砸啊

image.png

AppDelegate.cpp

   LuaStack* stack = engine->getLuaStack();
	stack->setXXTEAKeyAndSign("YRokP3hO", strlen("YRokP3hO"), "hggame", strlen("hggame"));

Android中使用luajit库

external\lua\luajit\prebuilt\android\Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := luajit_static
LOCAL_MODULE_FILENAME := libluajit
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libluajit.a # 使用的是luajit的预编译库
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
include $(PREBUILT_STATIC_LIBRARY)

项目中默认就使用了luajit

image.png

运行报错

设置了错误的PROP_LUA_ENCRYPT_KEY也会导致崩溃

错误1

[LUA ERROR] load "assets/src/main.luac", error: syntax error during pre-compilation.

一般是ENCRYPT_KEYENCRYPT_SIGN和C++中Appdelegate中的不匹配导致

E:\proj\tank5_android\tank5_buildAPK\xxtea\win32>luajit.exe -v
LuaJIT 2.0.1 -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/

代码中使用的

#define LUAJIT_VERSION		"LuaJIT 2.1.0-beta2"

解码luac

image.png

hggame就是cocos luacompile的-b参数,也就是sign数据,因为底层代码里面,最终的文件数据就是sign数据+加密的数据,这也解释了开头就是-b参数的原因。

搜索main.lua就能上上下文找到私钥