【Quick 3.3】資源腳本加密及熱更新(一)腳本加密

【Quick 3.3】資源腳本加密及熱更新(一)腳本加密

注:本文基於Quick-cocos2dx-3.3版本編寫php

1、腳本加密

quick框架已經封裝好加密模塊,與加密有關的文件在引擎目錄/quick/bin下。python

加密腳本:compile_scripts.bat、compile_scripts.sh
參數:android

  • -i 需加密的腳本所在目錄
  • -o 加密後文件輸出目錄
  • -e 加密方式,有xxtea_zip、xxtea_chunk兩種方式,前者是打包一塊兒加密,後者是分文件加密
  • -es 簽名,用來識別代碼、文件是否是加密的,通常填爲"XXTEA"便可
  • -ek 密鑰,簡單來講就是加密和解密的鑰匙,確保只有你本身知道
  • -jit 使用luajit編譯腳本,quick3.3默認是用lua而不是luajit,因此此參數可不加

說明:更多可選參數可在/quick/bin/lib/compile_scripts.php找到說明,這裏就不列舉了ios

例子:(基於跨平臺考慮,本系列的腳本基於python語言)shell

#coding=utf-8
#!/usr/bin/python
import os 
import os.path 
import sys, getopt  
import subprocess
import shutil 
import time,  datetime
import platform
from hashlib import md5
import hashlib  
import binascii

def initEnvironment():
    global APP_ROOT #工程根目錄 
    global APP_ANDROID_ROOT #安卓根目錄
    global QUICK_ROOT #引擎根目錄
    global QUICK_BIN_DIR #引擎bin目錄
    global APP_RESOURCE_ROOT #生成app的資源目錄
    global APP_RESOURCE_RES_DIR #資源目錄

    global APP_BUILD_USE_JIT #是否使用jit

    global SCRIPT_NAME #執行腳本文件名

    global BUILD_PLATFORM #生成app對應的平臺

    SYSTEM_TYPE = platform.system() #當前操做系統

    APP_ROOT = os.getcwd() #當前目錄
    APP_ANDROID_ROOT = APP_ROOT + "/frameworks/runtime-src/proj.android"
    QUICK_ROOT = os.getenv('QUICK_V3_ROOT')

    if QUICK_ROOT == None: #quick引擎目錄未指定,可手動指定路徑或者運行引擎目錄下相應腳本
        print "QUICK_V3_ROOT not set, please run setup_win.bat/setup_mac.sh in engine root or set QUICK_ROOT path"
        return False

    if(SYSTEM_TYPE =="Windows"): 
        BUILD_PLATFORM = "android" #windows dafault build android
        QUICK_BIN_DIR = QUICK_ROOT + "quick/bin"
        SCRIPT_NAME = "/compile_scripts.bat"
    else:
        BUILD_PLATFORM = "ios" #mac default build ios
        QUICK_BIN_DIR = QUICK_ROOT + "/quick/bin" #mac add '/'
        SCRIPT_NAME = "/compile_scripts.sh"


    if(BUILD_PLATFORM =="ios"):
        APP_BUILD_USE_JIT = False
        APP_RESOURCE_ROOT = APP_ROOT + "/Resources" 
        APP_RESOURCE_RES_DIR = APP_RESOURCE_ROOT + "/res"

    else:
        APP_BUILD_USE_JIT = True
        APP_RESOURCE_ROOT = APP_ANDROID_ROOT + "/assets" #default build android
        APP_RESOURCE_RES_DIR = APP_RESOURCE_ROOT + "/res"

    print 'App root: %s' %(APP_ROOT)
    print 'App resource root: %s' %(APP_RESOURCE_ROOT)
    return True

def compileScriptFile(compileFileName, srcName, compileMode):
    scriptDir = APP_RESOURCE_RES_DIR + "/code/"
    if not os.path.exists(scriptDir):
        os.makedirs(scriptDir)
    try:
        scriptsName = QUICK_BIN_DIR + SCRIPT_NAME
        srcName = APP_ROOT + "/" + srcName
        outputName = scriptDir + compileFileName
        args = [scriptsName,'-i',srcName,'-o',outputName,'-e',compileMode,'-es','XXTEA','-ek','ilovecocos2dx']

        if APP_BUILD_USE_JIT:
            args.append('-jit')

        proc = subprocess.Popen(args, shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
        while proc.poll() == None:  
            outputStr = proc.stdout.readline()
            print outputStr,
        print proc.stdout.read(),
    except Exception,e:  
        print Exception,":",e

if __name__ == '__main__': 
    isInit = initEnvironment()

    if isInit == True:
        #將src目錄下的全部腳本加密打包成game.zip
        compileScriptFile("game.zip", "src", "xxtea_zip")

使用方法:windows

  1. 保存爲compileScript.py文件
  2. 放到項目根目錄(res、src同級目錄)
  3. 運行命令行工具,cd到該目錄,執行python compileScript.py
  4. 若屏幕輸出 "create ZIP archive xx/xx/game.zip done". 說明執行成功

2、修改引擎

打開/frameworks/runtime-src/Classes/AppDelegate.cpp文件
在applicationDidFinishLaunching方法的最後改爲以下代碼app

bool AppDelegate::applicationDidFinishLaunching(){
    //..
    //..

    FileUtils *utils = FileUtils::getInstance();

    const char *zipFilename ="code/game.zip";
    
    std::string zipFilePath = utils->fullPathForFilename(zipFilename);

    if (zipFilePath.compare(zipFilename) == 0) //no game zip file use default lua file
    {
        engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str()); 
    }
    else
    {
        stack->loadChunksFromZIP(zipFilename);
        stack->executeString("require 'main'");
    }

    return true
}

這段代碼會判斷res/code/game.zip是否存在,若存在則加載加密代碼壓縮包,不然執行舊的邏輯。這樣改的好處是開發過程當中可直接運行lua代碼,發佈版本則執行加密腳本框架

注意發佈版本時須要移除src目錄中的代碼(教程的最後會給出完整腳本,自動生成app所需資源)工具

相關文章
相關標籤/搜索