|
- local bit32 = (bit32 or require("bit"))
-
-
- -- 一个缓存文件
- local CacheFile = defClass("CacheFile"
- , defVar("origin" , VT_String)
- , defVar("name" , VT_String)
- , defVar("md5" , VT_String)
- , defVar("originSize" , VT_Double)
- , defVar("compileSize" , VT_Double)
- , defVar("encryptSize" , VT_Double)
- , defVar("compressedSize" , VT_Double)
- , defVar("modifyTime" , VT_Double)
- , defVar("compressedFile" , VT_String)
- , defVar("encryptFile" , VT_String)
- );
- -- 一组缓存文件
- local CacheFileList = defClass("CacheFileList"
- , defVar("list" , VT_Map(VT_String , CacheFile))
- );
-
- -- 保存所有缓存的文件
- gCacheFiles = CacheFileList:new();
- -- 所有配置文件的缓存
- gConfigDescCacheFiles = nil
- -- 保存所有的xml文件对应的desc解析文件
- gConfigXmlToDesc = {}
-
- local function getNextPowerOfTwo(value)
- local i = 1;
- while i < value do
- i = i * 2;
- end
-
- return i;
- end
-
- local function isPow2(size)
- return getNextPowerOfTwo(size) == size;
- end
-
- -- 载入文件数据
- function loadfileData(filename)
- local fileData;
- -- 读取整个文件数据
- local file = io.open(filename , "rb");
- fileData = file:read("*a");
- file:close();
- return fileData;
- end
-
-
- --/* These describe the color_type field in png_info. */
- --/* color type masks */
- PNG_COLOR_MASK_PALETTE = 1
- PNG_COLOR_MASK_COLOR = 2
- PNG_COLOR_MASK_ALPHA = 4
-
- --/* color types. Note that not all combinations are legal */
- PNG_COLOR_TYPE_GRAY = 0
- PNG_COLOR_TYPE_PALETTE = (PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_PALETTE)
- PNG_COLOR_TYPE_RGB = (PNG_COLOR_MASK_COLOR)
- PNG_COLOR_TYPE_RGB_ALPHA = (PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA)
- PNG_COLOR_TYPE_GRAY_ALPHA =(PNG_COLOR_MASK_ALPHA)
-
-
- -- 编译png文件成pvr文件,并返回pvr文件名
- local function _compilePngToPvr(sourceFile)
- local pathName , baseName , ext = string.splitFilename(sourceFile);
- -- 只打包这三个目录
- if not (string.startsWith(pathName , "res/effect/")
- or string.startsWith(pathName , "res/animation/")
- or string.startsWith(pathName , "res/scene/")) then
- return sourceFile;
- end
-
- local image = cc.Image:analysisPngFile(sourceFile);
-
- -- PVR转换规则,长宽相等,大小是2次幂。
- if image.image_width ~= image.image_height then
- return sourceFile;
- end
-
- -- 不是2次幂
- if not isPow2(image.image_width) or not isPow2(image.image_height) then
- return sourceFile;
- end
-
- -- 最小8*8
- if image.image_width < 8 or image.image_height < 8 then
- return sourceFile;
- end
-
- local pvrFormat;
- print("image" , table.tostring(image));
-
- -- 根据纹理格式来决定pvr格式
- if image.color_type == PNG_COLOR_TYPE_RGB then
- pvrFormat = "PVRTC1_4_RGB";
- elseif image.color_type == PNG_COLOR_TYPE_RGB_ALPHA then
- pvrFormat = "PVRTC1_4";
- elseif image.color_type == PNG_COLOR_TYPE_GRAY_ALPHA then
- pvrFormat = "PVRTC1_2";
- elseif image.color_type == PNG_COLOR_TYPE_GRAY then
- pvrFormat = "PVRTC1_2_RGB";
- elseif image.color_type == PNG_COLOR_TYPE_PALETTE then
- if image.expand_color_type == PNG_COLOR_TYPE_RGB_ALPHA then
- print("调色板带透明");
- pvrFormat = "PVRTC1_4";
- else
- print("调色板不带透明");
- pvrFormat = "PVRTC1_2_RGB";
- end
- else
- return sourceFile;
- end
- local pvrFile = "cache/" .. baseName .. "." .. pvrFormat .. ".pvr";
-
- local exFlags = "";
- -- 场景光效人物,要用mipmap
- --exFlags = exFlags .. " -m";
-
- local cmdLine = string.format('PVRTexTool -i "%s" -o "%s" -f "%s"%s' , sourceFile , pvrFile , pvrFormat , exFlags);
- local out = io.popen(cmdLine , "r");
- print("正在转换成pvr:" .. cmdLine);
- print(out:read("*a"));
- out:close();
-
- local atts = lfs.attributes(pvrFile , "modification");
- if not atts then
- error("转换pvr失败" .. sourceFile);
- return sourceFile;
- end
- return pvrFile;
- end
- -- 编译png文件成pvr文件,并返回pvr文件数据
- local function compilePngToPvr(sourceFile)
- local fileName = _compilePngToPvr(sourceFile);
- return loadfileData(fileName);
- end
-
- -- 编译png文件成etc文件,并返回etc文件名
- local function _compilePngToEtc(sourceFile)
- local pathName , baseName , ext = string.splitFilename(sourceFile);
- -- 只打包这三个目录
- if not (string.startsWith(pathName , "res/effect/")
- or string.startsWith(pathName , "res/animation/")
- or string.startsWith(pathName , "res/scene/")) then
- return sourceFile;
- end
-
- local image = cc.Image:analysisPngFile(sourceFile);
-
- -- 不是2次幂
- if not isPow2(image.image_width) or not isPow2(image.image_height) then
- return sourceFile;
- end
-
- -- 最小8*8
- if image.image_width < 8 or image.image_height < 8 then
- return sourceFile;
- end
-
-
- local etcFormat;
-
- -- 根据纹理格式来决定etc格式
- if image.expand_color_type == PNG_COLOR_TYPE_RGB or image.expand_color_type == PNG_COLOR_TYPE_GRAY then
- etcFormat = "ETC1";
- else
- return sourceFile;
- end
- local etcFile = "cache/" .. baseName .. "." .. etcFormat .. ".pvr";
-
- local exFlags = "";
- -- 场景光效人物,要用mipmap
- --exFlags = exFlags .. " -m";
-
- local cmdLine = string.format('PVRTexTool -i "%s" -o "%s" -f "%s"%s' , sourceFile , etcFile , etcFormat , exFlags);
- local out = io.popen(cmdLine , "r");
- print("正在转换成etc:" .. cmdLine);
- print(out:read("*a"));
- out:close();
-
- local atts = lfs.attributes(etcFile , "modification");
- if not atts then
- error("转换etc失败" .. sourceFile);
- return sourceFile;
- end
- return etcFile;
- end
- -- 编译png文件成etc文件,并返回etc文件数据
- local function compilePngToEtc(sourceFile)
- local fileName = _compilePngToEtc(sourceFile);
- return loadfileData(fileName);
- end
-
- -- 编译png文件成etc文件,并返回etc文件名
- local function _compilePngToAtc(sourceFile)
- local pathName , baseName , ext = string.splitFilename(sourceFile);
- if string.startsWith(pathName , "res/scene/scene_maoxian_002") then
- print("res/scene/scene_maoxian_002不能压缩纹理,文件名" .. sourceFile);
- return sourceFile;
- end
- -- 只打包这三个目录
- if not (string.startsWith(pathName , "res/effect/")
- or string.startsWith(pathName , "res/animation/")
- or string.startsWith(pathName , "res/ui/")
- or string.startsWith(pathName , "res/scene/"))then
- print("指定目录之外的纹理不需要压缩,文件名" .. sourceFile);
- return sourceFile;
- end
-
- local image = cc.Image:analysisPngFile(sourceFile);
-
- -- 最小8*8
- if image.image_width < 8 or image.image_height < 8 then
- print("长宽小于8不能压缩纹理,文件名" .. sourceFile);
- return sourceFile;
- end
-
-
- local etcFormat;
- -- 根据纹理格式来决定atc格式
- if image.color_type == PNG_COLOR_TYPE_RGB or image.expand_color_type == PNG_COLOR_TYPE_RGB then
- etcFormat = "RGB";
- elseif image.color_type == PNG_COLOR_TYPE_RGB_ALPHA or image.expand_color_type == PNG_COLOR_TYPE_RGB_ALPHA then
- etcFormat = "RGBA"
- else
- print("Texture color type is", image.color_type)
- print("Texture expand color type is", image.expand_color_type)
- print("纹理格式不是RGB或者是RGBA格式,不能转换成压缩纹理,文件名" .. sourceFile);
- return sourceFile;
- end
- --
- local atcFile = "cache/" .. baseName .. "." .. etcFormat .. ".atc";
- local cmdLine = string.format('atc_texture "%s" "%s"' , sourceFile , atcFile);
- local out = io.popen(cmdLine , "r");
- print("正在转换成atc:" .. cmdLine);
- print(out:read("*a"));
- out:close();
-
- local atts = lfs.attributes(atcFile , "modification");
- if not atts then
- error("转换atc失败" .. sourceFile);
- return sourceFile;
- end
- return atcFile;
- end
-
- -- 编译png文件成atc文件,并返回atc文件数据
- local function compilePngToAtc(sourceFile)
- local fileName = _compilePngToAtc(sourceFile);
- return loadfileData(fileName);
- end
-
- -- 编译lua文件,并返回编译后的数据
- function compileLua52(filename)
- -- 编译lua
- print("正在编译Lua52:" , filename);
- local cmdLine = string.format('luac.exe -o "luac_tmp.bin" "%s"' , cc.FileUtils:getInstance():fullPathForFilename(filename));
- local out = io.popen(cmdLine , "r");
- print("正在运行:" .. cmdLine);
- print(out:read("*a"));
- local r , what , code = out:close();
- if code ~= 0 then
- error("编译脚本出错:" .. filename);
- end
- return loadfileData(cc.FileUtils:getInstance():fullPathForFilename("luac_tmp.bin"));
- end
-
- -- 编译lua文件,并返回编译后的数据
- function compileLuajit(filename)
- -- 编译lua
- print("正在编译Luajit:" , filename);
- local cmdLine = string.format('luajit -b -g "%s" "luac_tmp.bin"' , cc.FileUtils:getInstance():fullPathForFilename(filename));
- local out = io.popen(cmdLine , "r");
- print("正在运行:" .. cmdLine);
- print(out:read("*a"));
- local r , what , code = out:close();
- if code ~= 0 then
- error("编译脚本出错:" .. filename);
- end
- return loadfileData(cc.FileUtils:getInstance():fullPathForFilename("luac_tmp.bin"));
- end
-
- function compileLua(filename)
- if hasCmdArg("-lua") then
- return compileLua52(filename);
- else
- return compileLuajit(filename);
- end
- end
-
-
- local ConfigLoaded = false;
- function loadAllXML()
- if ConfigLoaded then return; end
- ConfigLoaded = true;
- local s = app.config.Setting;
- local r = app.config.RomSetting;
- app.config = require("LoadAllConfigs")
- app.config.Setting = s;
- app.config.RomSetting = r;
- for i, v in pairs(app.config) do
- if type(v) == "function" then
- app.config[i] = v()
- end
- end
- end
-
- -- 获取对应版本的lua后缀名
- local function getLuaExtName(baseName)
- local saveBaseName
- if hasCmdArg("-lua") then
- saveBaseName = baseName .. ".lua52";
- else
- saveBaseName = baseName .. ".luajit";
- end
-
- return saveBaseName
- end
-
- -- 判断一个策划配置的xml文件依赖的desc文件是否改变
- local function isConfigXmlDescChanged(xmlFileName)
- local descFileName = gConfigXmlToDesc[xmlFileName]
- if not descFileName then
- print("配置文件:" .. xmlFileName .. "统计不到对应的desc缓存文件,xml文件需要重新打包")
- return true
- end
-
- -- 读取文件
- local atts = lfs.attributes(descFileName);
- if not atts then
- error("找不到文件" .. descFileName);
- return true;
- end
-
- -- 拆分desc文件名
- local pathName, baseName, ext = string.splitFilename(descFileName);
- local saveBaseName = getLuaExtName(baseName)
- local cacheFile = gConfigDescCacheFiles.list[saveBaseName];
- if cacheFile then
- if cacheFile.origin == descFileName and cacheFile.modifyTime == atts.modification and cacheFile.originSize == atts.size then
- -- 文件没有改变则不需要重新生成
- return false
- end
- end
-
- print("配置文件:" .. xmlFileName .. "对应的desc文件:" .. descFileName .. "改变了,xml文件需要重新打包")
- return true
- end
-
- local function optimiseRewardConfig(RewardConfig)
- local deleted = {}
- for i , v in pairs(RewardConfig) do
- --print("删掉空奖励:" , table.tostring(v));
- if not v.epFull
- and not v.apFull
- and #v.gold == 1 and v.gold[1] == ""
- and #v.ticket == 1 and v.ticket[1] == ""
- and #v.redGem == 1 and v.redGem[1] == ""
- and #v.goods == 1 and #v.goods[1] == 1 and v.goods[1][1] == ""
- and #v.treasure == 0
- and #v.awardHero == 0
- and #v.awardHeroSaga == 0
- and #v.awardRune == 0
- and #v.awardRuneChip == 0
- and #v.awardHeroSoul == 0
- and (not v.awardPrivilege or v.awardPrivilege == 0)
- then
- table.insert(deleted , i);
- print("删掉空奖励:" , i);
- end
- end
- print("总共删掉空奖励:" , #deleted);
- for i , v in ipairs(deleted) do
- RewardConfig[v] = nil;
- end
- end
-
- local function optimiseHeroAwardConfig(AwardConfig)
- local deleted = {}
- for i , v in pairs(AwardConfig) do
- if #v.awardValue == 0 or (#v.awardDungeon == 1 and #v.awardDungeon[1] == 0) then
- table.insert(deleted , i);
- print("删掉如何获得的空配置:" , i);
- end
- end
- print("总共删掉如何获得空配置:" , #deleted);
- for i , v in ipairs(deleted) do
- AwardConfig[v] = nil;
- end
- end
-
- local function copyFile(dstFile , srcFile)
- local src = io.open(srcFile , "rb");
- local dst = io.open(dstFile , "wb");
- dst:write(src:read("*a"));
- dst:close();
- src:close();
- end
-
- -- 编译xml文件,并返回编译后的数据
- function compileXml(sourceFile)
- loadAllXML();
- local luaData;
- for i , v in pairs(app.config) do
- if i ~= "Setting" and i ~= "RomSetting" then
- if type(v.LuaFile) == "string" then
- local filename = v.XmlFile;
- if "dataconfig/" .. filename == sourceFile then
- local luaFile = "cache/" .. filename .. ".lua";
- if filename == "pvpRewardConfig.xml"
- or filename == "riftRewardConfig.xml"
- or filename == "castleRewardConfig.xml"
- or filename == "vipRewardConfig.xml"
- or filename == "commonRewardConfig.xml"
- or filename == "appRewardConfig.xml"
- or filename == "rankRewardConfig.xml"
- or filename == "pveRewardConfig.xml"
- or filename == "achieveRewardConfig.xml" then
- optimiseRewardConfig(v);
- end
-
- if filename == "awardHeroSoulConfig.xml"
- or filename == "awardStarUpFoodConfig.xml" then
- optimiseHeroAwardConfig(v);
- end
-
- copyFile(luaFile , v.LuaFile);
- luaData = compileLua(luaFile);
- break;
- end
- else
- local desc = v:getConfigDesc();
- local filename = desc.XMLFile;
-
- if "dataconfig/" .. filename == sourceFile then
- local luaFile = "cache/" .. filename .. ".lua";
- if filename == "pvpRewardConfig.xml"
- or filename == "riftRewardConfig.xml"
- or filename == "castleRewardConfig.xml"
- or filename == "vipRewardConfig.xml"
- or filename == "commonRewardConfig.xml"
- or filename == "appRewardConfig.xml"
- or filename == "rankRewardConfig.xml"
- or filename == "pveRewardConfig.xml"
- or filename == "achieveRewardConfig.xml" then
- optimiseRewardConfig(v);
- end
-
- if filename == "awardHeroSoulConfig.xml"
- or filename == "awardStarUpFoodConfig.xml" then
- optimiseHeroAwardConfig(v);
- end
-
- saveLuaXMLConfig(v , desc, luaFile);
- luaData = compileLua(luaFile);
- break;
- end
- end
- end
- end
- if luaData ~= nil then
- return lzma.compress(luaData);
- end
- end
-
- local keepFiles = {};
-
- -- 编译文件
- function compileFile(sourceFile, targetPath)
- local pathName , baseName , ext = string.splitFilename(sourceFile);
- local lowerExt = string.lower(ext);
- if isIgnoreFile(pathName , baseName , ext) then
- return;
- end
- local atts = lfs.attributes(sourceFile);
- if not atts then
- error("找不到文件" .. sourceFile);
- return;
- end
-
- local keepFile = keepFiles[pathName];
- if not keepFile then
- keepFile = {};
- keepFiles[pathName] = keepFile;
- local f , r = io.open(pathName .. "/keep.txt" , "rb");
- print("open keep" , f , r);
- if f then
- while true do
- local fileName = f:read("*l");
- print("read keep" , fileName);
- if fileName then
- fileName = string.trim(fileName);
- keepFile[fileName] = true;
- print("set keep " , fileName);
- else
- break;
- end
- end
- f:close();
- end
- end
-
- local saveBaseName = baseName;
- if not keepFile[baseName] then
- -- 处理png
- if lowerExt == "png" then
- -- preload要用png格式,有些机子不支持etc
- if pathName ~= "preload" then
- -- 是否支持PVR格式
- if hasCmdArg("-pvr") then
- saveBaseName = saveBaseName .. ".pvr";
- end
- -- 是否支持PVR格式
- if hasCmdArg("-etc") then
- saveBaseName = saveBaseName .. ".etc";
- end
- -- 是否支持PVR格式
- if hasCmdArg("-atc") then
- saveBaseName = saveBaseName .. ".atc";
- end
- end
- end
-
- -- lua文件
- if (isLuaFileExt(lowerExt) or (lowerExt == "xml" and pathName == "dataconfig")) then
- saveBaseName = getLuaExtName(saveBaseName)
- end
- else
- print("file keeped : " , baseName);
- saveBaseName = baseName .. ".keep";
- end
-
- local cacheFile = gCacheFiles.list[saveBaseName];
- if cacheFile then
- if cacheFile.origin == sourceFile and cacheFile.modifyTime == atts.modification and cacheFile.originSize == atts.size then
- -- 如果是dataconfig里面的xml则需要对比下desc文件是否改变了
- if lowerExt == "xml" and pathName == "dataconfig" then
- if isConfigXmlDescChanged(baseName) == false then
- print("配置文件没有改变,不需要重新打包", baseName)
- return cacheFile
- end
- elseif baseName ~= "Setting.lua" then
- return cacheFile;
- end
- end
- end
-
- print("编译文件" .. sourceFile)
-
- local fileData;
-
- if not keepFile[baseName] then
- print("skip keeped : " , baseName);
-
- -- 处理png
- if lowerExt == "png" then
- -- preload要用png格式,有些机子不支持etc
- if pathName ~= "preload" then
- -- 是否支持PVR格式
- if hasCmdArg("-pvr") then
- fileData = compilePngToPvr(sourceFile);
- end
- if hasCmdArg("-etc") then
- fileData = compilePngToEtc(sourceFile);
- end
- if hasCmdArg("-atc") then
- fileData = compilePngToAtc(sourceFile);
- end
- else
- print("preload的文件不用编译png" , sourceFile);
- end
- -- 编译配置文件
- elseif lowerExt == "xml" then
- fileData = compileXml(sourceFile);
- -- 编译lua文件
- elseif isLuaFileExt(lowerExt) then
- fileData = compileLua(sourceFile);
- end
- end
- -- 普通文件加载
- if fileData == nil then
- fileData = loadfileData(sourceFile);
- end
-
- -- 计算文件信息
- local fileInfo = CacheFile:new();
-
- fileInfo.origin = sourceFile;
- fileInfo.name = baseName;
- fileInfo.md5 = md5.sumhexa(fileData);
- fileInfo.compileSize = #fileData;
- fileInfo.originSize = atts.size;
- -- 保存修改时间
- fileInfo.modifyTime = atts.modification;
-
- -- 加密文件
- local encryptData = FilePackage.encrypt(fileData)
- fileInfo.encryptSize = string.len(encryptData);
-
- -- 加密完毕后,计算出加密后大小
- fileInfo.encryptFile = targetPath .. "/cache/" .. saveBaseName .. ".encrypt";
- saveFile(encryptData , fileInfo.encryptFile);
-
- -- 压缩文件
- local compressedData = FilePackage.compress(encryptData)
- fileInfo.compressedSize = string.len(compressedData);
-
- -- 压缩完毕后,计算出压缩后大小
- fileInfo.compressedFile = targetPath .."/cache/" .. saveBaseName .. ".compressed";
- saveFile(compressedData , fileInfo.compressedFile);
-
- gCacheFiles.list[saveBaseName] = fileInfo;
-
- --print("编译文件完毕" .. sourceFile);
- return fileInfo;
- end
-
-
- -- 保存文件列表
- function saveCacheFile(filename)
- local stream = NetStream.new();
- gCacheFiles:write(stream);
- print("保存缓存数据:" , #gCacheFiles.list)
- local cacheData = NetStream.getWriteData(stream);
- saveFile(cacheData , filename);
- NetStream.delete(stream);
- end
-
- -- 载入文件列表
- function loadCacheFile(filename)
- gCacheFiles = CacheFileList:new();
- local cacheData = loadFile(filename);
- if cacheData then
- local stream = NetStream.new(cacheData);
- gCacheFiles = CacheFileList:read(stream);
- print("载入缓存数据:" , #gCacheFiles.list)
- NetStream.delete(stream);
- end
- end
-
- -- 载入配置描述列表
- function loadConfigDescCacheFile(configDescFileName)
- gConfigDescCacheFiles = CacheFileList:new();
- local cacheData = loadFile(configDescFileName);
- if cacheData then
- local stream = NetStream.new(cacheData);
- gConfigDescCacheFiles = CacheFileList:read(stream);
- NetStream.delete(stream);
- end
- end
|