assets-crypto.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. const fs = require('fire-fs');
  2. const path = require('fire-path');
  3. const crypto = require('./libs/crypto');
  4. const setting = require('./build-setting');
  5. const utils = require('./libs/utils');
  6. module.exports = (function (){
  7. var _instance;
  8. function AssetsCrypto (params) {
  9. return {
  10. _ready: false,
  11. _files: [],
  12. _paths: [],
  13. _cipherKey: null,
  14. _cipherSign: null,
  15. init (actualPlatform) {
  16. this._ready = false;
  17. let assetsCrypto = `assetsCrypto`;
  18. let crypto = setting.getInstance().getItem(assetsCrypto);
  19. if (!crypto) { Editor.warn('缺少配置,跳过资源加密!'); return false; }
  20. if (!crypto.enable) { Editor.warn('未开启资源加密!'); return false; }
  21. let platform = crypto.platform || ''; // 平台配置
  22. let supportList = platform.split(',');
  23. if (!supportList.includes(actualPlatform)) {
  24. Editor.warn(actualPlatform, '平台不支持资源加密');
  25. return false;
  26. }
  27. let dir = crypto.dir;
  28. let key = crypto.key;
  29. let sign = crypto.sign;
  30. let exts = crypto.exts;
  31. let list = crypto.list;
  32. if (!dir || !key || !sign || !exts) {
  33. Editor.error('资源加密配置不满足');
  34. return false;
  35. }
  36. this._dir = dir;
  37. this._cipherKey = key; // 用来加密的密钥key
  38. this._cipherSign = sign; // 签名用来标识加密图片
  39. this._extList = exts.split(',');
  40. this._list = list || [];
  41. this._importUuids = [];
  42. for (const aPath of this._list) {
  43. let fullpath = path.join(Editor.Project.path, aPath);
  44. let stat = fs.statSync(fullpath);
  45. if (stat.isDirectory()) {
  46. utils.findFileSync(fullpath, (filePath)=> {
  47. this.addImportFile(filePath);
  48. });
  49. } else {
  50. this.addImportFile(fullpath);
  51. }
  52. }
  53. this._ready = true;
  54. return true;
  55. },
  56. addImportFile (filePath) {
  57. let index = filePath.lastIndexOf('.');
  58. let ext = filePath.substr(index + 1);
  59. if (ext === 'DS_Store' || ext === 'meta') {
  60. return;
  61. }
  62. let uuid = Editor.assetdb._path2uuid[filePath];
  63. this._importUuids.push(uuid);
  64. },
  65. isReady () {
  66. return this._ready;
  67. },
  68. getImportBuildUrl (root, uuid) {
  69. if (!root || !uuid) {
  70. return;
  71. }
  72. let dirname = uuid.substr(0, 2);
  73. let dirPath = path.join(root, 'res/import', dirname);
  74. let url = path.join(dirPath, uuid + '.json');
  75. if (!fs.existsSync(url)) {
  76. if (!fs.existsSync(dirPath)) {
  77. return;
  78. }
  79. let dirs = fs.readdirSync(dirPath);
  80. for (const ele of dirs) {
  81. let fullpath = path.join(dirPath, ele);
  82. let stat = fs.statSync(fullpath);
  83. if (stat.isFile() && ele.includes(uuid)) {
  84. url = fullpath;
  85. break;
  86. }
  87. }
  88. }
  89. return url;
  90. },
  91. addCryptoFile (filePath, isImport) {
  92. if (isImport) {
  93. this._files.push(filePath);
  94. return;
  95. }
  96. let index = filePath.lastIndexOf('.');
  97. let ext = filePath.substr(index + 1);
  98. if (this._extList.includes(ext)) {
  99. this._files.push(filePath);
  100. }
  101. },
  102. genFiles (buildDest) {
  103. this._files = [];
  104. for (const uuid of this._importUuids) {
  105. let fullpath = this.getImportBuildUrl(buildDest, uuid);
  106. if (fullpath) {
  107. this.addCryptoFile(fullpath);
  108. }
  109. }
  110. let rootPath = path.join(Editor.Project.path, this._dir);
  111. let stat = fs.statSync(rootPath);
  112. if (stat.isDirectory()) {
  113. utils.findFileSync(rootPath, (filePath)=> {
  114. this.addCryptoFile(filePath);
  115. });
  116. }
  117. },
  118. getFilesCount () {
  119. return this._files.length;
  120. },
  121. encrypt (callback) {
  122. this._files.forEach((filePath, index) => {
  123. let data = fs.readFileSync(filePath);
  124. if (data) {
  125. let buffer = crypto.xor(data, this._cipherKey, this._cipherSign);
  126. if (buffer) {
  127. fs.writeFileSync(filePath, buffer);
  128. callback (filePath);
  129. }
  130. } else {
  131. Editor.error('读取' + filePath + '失败');
  132. }
  133. });
  134. },
  135. decrypt (callback) {
  136. this._files.forEach((filePath, index) => {
  137. let data = fs.readFileSync(filePath);
  138. if (data) {
  139. let buffer = crypto.rox(data, this._cipherKey, this._cipherSign);
  140. if (buffer) {
  141. fs.writeFileSync(filePath, buffer);
  142. callback (filePath);
  143. }
  144. } else {
  145. Editor.error('读取' + filePath + '失败');
  146. }
  147. });
  148. },
  149. modifyFileUtilsFile (buildDest) {
  150. // 需要被替换的值
  151. let defSign = '{0x6a, 0x69, 0x61, 0x6d, 0x69}; // jiami';
  152. let defKey = '7911ea3ff0ba6ea6d475da6418f254017911ea3ff0ba6ea6d475da6418f25401';
  153. function strToHexCharCode (str) {
  154. var hexCharCode = '{';
  155. for (var i = 0; i < str.length; i++) {
  156. hexCharCode += '0x' + (str.charCodeAt(i)).toString(16);
  157. if (i < (str.length - 1)) {
  158. hexCharCode += ', ';
  159. }
  160. }
  161. return hexCharCode + '}; // ' + str;
  162. }
  163. let cipherSign = strToHexCharCode(this._cipherSign);
  164. let filePath = buildDest + '/frameworks/cocos2d-x/cocos/platform/CCFileUtils.cpp';
  165. if (fs.existsSync(filePath)) {
  166. let data = fs.readFileSync(filePath, 'utf-8');
  167. if (data) {
  168. data = data.replace(defSign, cipherSign);
  169. data = data.replace(defKey, this._cipherKey);
  170. fs.writeFileSync(filePath, data, 'utf-8');
  171. // 批量打包时时不存在这个路径的,也不需要处理
  172. let packagePath = path.join(Editor.Project.path, '../mj-package-android/package/frameworks/cocos2d-x/cocos/platform/CCFileUtils.cpp');
  173. if (fs.existsSync(packagePath)) {
  174. Editor.warn('修改UtilsFile.cpp中的签名:' + this._cipherSign + '密钥:' + this._cipherKey);
  175. fs.copyFileSync(filePath, packagePath);
  176. // 如果打包工程有temp_demo
  177. let packageTempPath = path.join(Editor.Project.path, '../mj-package-android/temp_demo/cocos2d-x/cocos/platform/CCFileUtils.cpp');
  178. if (fs.existsSync(packageTempPath)) {
  179. fs.copyFileSync(filePath, packageTempPath);
  180. }
  181. }
  182. } else {
  183. Editor.error('读取' + filePath + '失败');
  184. }
  185. } else {
  186. Editor.log('没有找到' + filePath + '文件');
  187. }
  188. }
  189. };
  190. }
  191. return {
  192. getInstance (params) {
  193. if (!_instance){
  194. _instance = AssetsCrypto(params);
  195. }
  196. return _instance;
  197. }
  198. };
  199. })();