Cocos2d-x 之 lua 代码加密

加密方式

lua 代码加密方式很很多种,这里只讲最简单的一种,就是把代码编译成二进制字节码。lua 是一门脚本语言,不需要经过编译就可以使用 lua 解释器来执行;但我们也可以把 lua 代码事先编译成二进制文件,这样就达到了加密的方式。

使用 lua 编译器

最简单也最直接的方式就是使用 lua 编译器来编译 lua 代码,编译的方式很简单,打开命令行,输入下面的命令

lucac -o dest.lua source.lua

-o 参数指定生成的目标文件名,可以用 .lua 作后缀,也可以用其它后缀,其本质上是一个二进制文件,与文件的后缀并没有什么关系。但是,为了可以使用 require 来加载这个文件,文件的后缀还是必须使用 .lua。一般可以使用原来的文件名,这样使用到这个文件的其它文件就不用修改代码。
下面写一个打印星星的例子,测试编译的过程和编译后能否正确执行

-- test.lua
local str = [=[ hello ]=]
print(str)

local function printStar(n)
    local str
    for i = 1, math.ceil(n / 2), 1 do
        str = " "
        for j = 1, math.ceil(n / 2) - i do
            str = str .. " "
        end
        for j = 1, 2 * (i - 1) + 1 do
            str = str .. "*"
        end
        print(str)
    end

    for i = math.ceil(n / 2) - 1, 1, -1 do
        str = " "
        for j = 1, math.ceil(n / 2) - i do
            str = str .. " "
        end
        for j = 1, 2 * (i - 1) + 1 do
            str = str .. "*"
        end
        print(str)
    end
end

printStar(10)

打开 cmd,输入

luac -o out.lua test.lua

用记事本打开 out.lua,发现是乱码,说明它是个二进制文件。继续在 cmd 中输入 lua,进入到 lua 解释器环境,输入

require("out")

看到运行下面的结果则表示 lua 解释器成功执行了二进制文件

hello
     *
    ***
   *****
  *******
 *********
  *******
   *****
    ***
     *

关于 lua 解释器和编译器可以参考这篇文章
http://blog.csdn.net/xingxinmanong/article/details/76258711

使用 luajit

使用 lua 编译器来编译 lua 代码虽然简单方便,但编译后的字节码却不能在 cocos2d-x 中使用,原因是 cocos2d-x 使用的是 luajit。luajit 是一套合适 c 语言写的 lua 解释器代码,是一种即时编译器(JIT),与原生的 lua 编译器有所区别。也就量说同一个文件使用 luajit.exe 编译后的字节码和使用 luac.exe 编译后字节码是不一样,因此使用 luac.exe 编译后的字节码不能在 cocos2d-x 中正确加载,正确的方式是使用 luajit 来编译 lua 源代码。

获取 luajit

看了网上的教程,都是说在 %COCOS_ROOT%\scripting\lua\luajit\LuaJIT-2.0.1\src 目录下有个 msvcbuild.bat 批处理文件,然后执行这个脚本就可以生成一个 luajit.exe 文件。但这是 cocos2d 2.x 的做法,在 3.x 中并没有找到这个脚本文件。网上的教程抄袭成风,找了好几篇博客,内容全是一模一样的,都是讲 2.x 的做法。最后自己使用 everything 工具搜索资源管理器,发现在 %COCOS_ROOT%\tools\cocos2d-console\plugins\plugin_luacompile\bin 下面就有一个现在的 luajit.exe;从 2.x 到 3.x 总要有些进步的,现在已经不用自己去生成 luajit 了,引擎已经帮我们集成好了。

使用 luajit 来编译源代码

使用 luajit 编译 lua 源代码和使用原生的 lua 编译器差不多,在 luajit 所在目录打开命令行,输入

luajit.exe -b dest.lua source.lua

注意源文件和目标文件要加上路径。

使用脚本批处理

一个项目的源文件有几十个甚至几百个,一个个手动在命令行输入命令编译显然是不现实的,因此需要一个脚本来批量处理。

@echo off 
rem @表示不显示 echo off 这一行,echo off 表示不显示 echo off 这一行之后所有命令

rem 定义标号
:input

rem 定义变量
set luapath=:
rem 提示用户输入并把输入的内容赋给变量
set /p luapath= 拖入要编译的lua文件夹:

rem 如果输入的内容为空则重新输入
if "%luapath%"==":" goto input
rem 如果输入的路径找不到则重新输入
if not exist "%luapath%" goto input

for %%i in ("%luapath%") do if /i "%%~di"==%%i goto input

set out=%luapath%\out
rem 如果存在文件夹 out,则删除
if exist %out% rd /s /q %out%
rem 重新创建目录 out
mkdir %out%

pushd %cd%
cd /d "%luapath%">nul 2>nul || exit
set cur_dir=%cd%
popd

rem 定义变量并赋初值
set /a num = 0

set luajit=D:\engine\cocos\Cocos2d-x\cocos2d-x-3.10\tools\cocos2d-console\plugins\plugin_luacompile\bin\luajit
for /f "delims=" %%i in ('dir /b /a-d /s "%luapath%"') do (set /a num += 1 & %luajit% -b %%~fsi %out%/%%~nxi & echo %%~nxi)

echo 编译脚本数量:%num%

pause

这是一个 bat 脚本示例,这个脚本要求用户输入一个目标文件夹,然后把文件夹下面所有的 lua 文件进行编译,保留在目标文件夹下面的 out 文件夹里面。这个脚本还很不完善,首先它要求目标文件夹下面的所有文件必须是 lua 文件,其次它把生成的所有文件放在一个目录下,如果目标文件夹下面有嵌套目录的话,生成后的文件就无法保持原来的目录结构了。由于我没学过 bat 和 shell 脚本,只能等以后学了再写一个更好的脚本。

2017-08-10 补充

下面是一个 shell 脚本,这个脚本使用 luajit 把 src-raw 下面的所有 lua 源代码编译成字节码,保存在 src 目录下,保持原来的目录结构。

#!/bin/bash
luajit=/d/engine/cocos/Cocos2d-x/cocos2d-x-3.10/tools/cocos2d-console/plugins/plugin_luacompile/bin/luajit.exe

cd ..

if [ ! -d src-raw ]; then
    echo "src-raw 目录不存在!"
    read -p "输入回车键结束..."
    exit 1
fi
if [ ! -d src ]; then
    mkdir src
fi

function compile()
{
    for sub in $1/*
    do
        if [ -f $sub ]; then
            if [[ ${sub##*.} = lua ]]; then
                dest=${sub/src-raw/src}
                if [[ ! -f $dest ]] || [[ $sub -nt $dest ]]; then
                    echo compile $sub
                    `$luajit -b $sub $dest`
                fi
            fi
        elif [ -d $sub ]; then
            dest=${sub/src-raw/src}
            if [ ! -d $dest ]; then
                mkdir $dest
            fi
            compile $sub 
        fi
    done
}

compile ./src-raw
read -p "输入回车键结束..."
exit 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值