Cocos2d-x Lua/Javascript脚本代码加密实现例子【转】

http://www.111cn.net/sj/iOS/75513.htm


下文为各位介绍一个Cocos2d-x Lua/Javascript脚本代码加密实现例子,有需要的朋友可进入参考。

在游戏开发中,脚本作为一种资源文件,就像图片视频一样,被引擎所引用,使用脚本做游戏的好处就在于可以在线patch更新,特别对于苹果App Store审核期很长的情况。

如果不对脚本进行加密,不怀好意的人松松解压出脚本文件,给你瞬间复制一个游戏出来。

1.异或加密解密

最简单的一种加密方式,虽然简单,但是也比较实用。但是防破解方面确实一般,如果你有其他严格的仿破解需求,可以将这部分加密算法换成你自己的复杂算法,不过保证解密效率。下面是采用C++简单实现的对文件进行加密之后保存到原文件中(注意对原始未加密文件进行备份)

 代码如下

复制代码

#include "stdafx.h"

#include<iostream>

#include<ctime>

#include<fstream>

using namespace std;

void Makecode(char *pstr,int *pkey);

void Cutecode(char *pstr,int *pkey);

void encode_file(char *f);

int _tmain(int argc, _TCHAR* argv[])

{

encode_file("e:/src/ResultScene.lua");

/*

encode_file("e:/src/ReadyScene.lua");

encode_file("e:/src/GameScene.lua");

encode_file("e:/src/PutHeadScene.lua");

encode_file("e:/src/TutorialsScene.lua");

encode_file("e:/src/WordsCategoryScene.lua");

encode_file("e:/src/common/DictHelper.lua");

encode_file("e:/src/common/LJ.lua");

encode_file("e:/src/common/DQueue.lua");

encode_file("e:/src/common/UIHelper.lua");

*/

    int c;

    cin>>c;    

    return 0;

}

void encode_file(char *f)

{

FILE *fp = NULL;

fopen_s(&fp, f,"rb");

fseek(fp,0,SEEK_END); //定位到文件末 

int nFileLen = ftell(fp); //文件长度

cout << "file len = " << nFileLen << endl;

fseek(fp, 0, SEEK_SET);

char *fileContent = NULL;

fileContent = (char *) malloc ((nFileLen + 1) * sizeof(char));//增加一位

memset(fileContent, 0, nFileLen + 1);

fileContent[nFileLen] = '';//最后一位置为结束位

fread_s(fileContent,nFileLen, 1, nFileLen, fp);

//fread(buf,nFileLen, 1, fp);

//cout<<"解密前:"<<fileContent<<endl;

fclose(fp);

cout<<"文件:"<<f<<endl;

cout<<"解密前文件大小:"<<strlen(fileContent)<<endl;

    int key[]={1, 2, 6, 1, 2, 6};//加密字符

    char *p=fileContent;

cout<<"====="<<endl;

    Makecode(fileContent,key);//加密

    //cout<<"加密后:"<<p<<endl; 

cout<<"加密后文件大小:"<<strlen(fileContent)<<endl;

FILE *stream = NULL;

fopen_s(&stream, f,"wb");

if (stream == NULL) /* open file TEST.$$$ */

    {

        fprintf(stderr, "Cannot open output file.

");

    }

else {

fwrite(p, nFileLen, 1, stream); /* 写的struct文件*/

fclose(stream); /*关闭文件*/

}

cout<<"====="<<endl;

    Cutecode(fileContent,key);//解密

    //cout<<"解密后:"<<fileContent<<endl;

}

//单个字符异或运算

char MakecodeChar(char c,int key){

    return c=c^key;

}

//单个字符解密

char CutcodeChar(char c,int key){

    return c^key;

}

//加密

void Makecode(char *pstr,int *pkey){

    int len=strlen(pstr);//获取长度

    for(int i=0;i<len;i++)

        *(pstr+i)=MakecodeChar(*(pstr+i),pkey[i%5]);

}

//解密

void Cutecode(char *pstr,int *pkey){

    int len=strlen(pstr);

    for(int i=0;i<len;i++)

        *(pstr+i)=CutcodeChar(*(pstr+i),pkey[i%5]);

}

2.修改Cocos2d-x引擎中加载lua脚本文件(或者js文件)的入口,在加载的时候对其进行解密。可能不同版本引擎有不同的入口文件,在Cocos2d-x3.0中,对应的是文件Cocos2dxLuaLoader.cpp文件中的int cocos2dx_lua_loader(lua_State *L)方法,对其进行修改成如下:

 代码如下

复制代码

#include "Cocos2dxLuaLoader.h"

#include <string>

#include <algorithm>

#include<iostream>

using namespace cocos2d;

extern "C"

{

    //单个字符异或运算

    char MakecodeChar(char c,int key){

        return c=c^key;

    }

    //单个字符解密

    char CutcodeChar(char c,int key){

        return c^key;

    }

    //加密

    void Makecode(char *pstr,int *pkey){

        int len=strlen(pstr);//获取长度

        for(int i=0;i<len;i++)

            *(pstr+i)=MakecodeChar(*(pstr+i),pkey[i%5]);

    }

    //解密

    void Cutecode(char *pstr,int *pkey){

        int len=strlen(pstr);

        for(int i=0;i<len;i++)

            *(pstr+i)=CutcodeChar(*(pstr+i),pkey[i%5]);

    }

    int cocos2dx_lua_loader(lua_State *L)

    {

        std::string filename(luaL_checkstring(L, 1));

        size_t pos = filename.rfind(".lua");

        if (pos != std::string::npos)

        {

            filename = filename.substr(0, pos);

        }

         

        pos = filename.find_first_of(".");

        while (pos != std::string::npos)

        {

            filename.replace(pos, 1, "/");

            pos = filename.find_first_of(".");

        }

        filename.append(".lua");

         

        Data data = FileUtils::getInstance()->getDataFromFile(filename);

         

        if (!data.isNull())

        {

         

            //====code decode start==================================

            log("===encode filename:%s===", filename.c_str());

            //如果filename == 'main.lua',则解密

            char *fileContent = (char*)data.getBytes();

            int key[]={1, 2, 6, 1, 2, 6};//加密字符

            char *fileContentDecoded = NULL; 

            if (strcmp(filename.c_str(),"ReadyScene.lua")==0 || 

            strcmp(filename.c_str(),"GameScene.lua")==0 || 

            strcmp(filename.c_str(),"PutHeadScene.lua")==0 || 

            strcmp(filename.c_str(),"TutorialsScene.lua")==0 || 

            strcmp(filename.c_str(),"WordsCategoryScene.lua")==0 || 

            strcmp(filename.c_str(),"DictHelper.lua")==0 || 

            strcmp(filename.c_str(),"LJ.lua")==0 || 

            strcmp(filename.c_str(),"ResultScene.lua")==0 || 

            strcmp(filename.c_str(),"DQueue.lua")==0 || 

            strcmp(filename.c_str(),"UIHelper.lua")==0 ) {

            if (data.getSize() < strlen(fileContent)) {

            fileContentDecoded = (char *) malloc ((data.getSize() + 1) * sizeof(char));//增加一位

            memset(fileContentDecoded, 0, data.getSize() + 1);

            fileContentDecoded[data.getSize()] = '';//最后一位置为结束位

            strncpy(fileContentDecoded,fileContent,data.getSize());

            fileContent = NULL;

            }

            else {

            fileContentDecoded = fileContent;

            }

            Cutecode(fileContentDecoded,key);//解密

            }

            else {

            fileContentDecoded = fileContent;

            }

            //====code decode end==================================

 

            if (luaL_loadbuffer(L, fileContentDecoded, data.getSize(), filename.c_str()) != 0)

            {

                luaL_error(L, "error loading module %s from file %s :

    %s",

                    lua_tostring(L, 1), filename.c_str(), lua_tostring(L, -1));

            }

        }

        else

        {

            log("can not get file data of %s", filename.c_str());

        }

        return 1;

    }

}


注意加密解密的key保证一致。

代码注释应该挺完善的,不进行解释了,Enjoy~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值