mirror of
https://gitee.com/bimuziyan/ccc-obfuscated-code.git
synced 2026-09-03 05:24:00 +08:00
update
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,4 +1,12 @@
|
||||
### 1.0.2.20200530 (当前版本)
|
||||
### 1.0.3.20200802 (当前版本)
|
||||
|
||||
1. 支持 Cocos Creator 2.4.x
|
||||
2. 去除【需要混淆的文件】选项
|
||||
3. 代码优化
|
||||
|
||||
|
||||
|
||||
### 1.0.2.20200530
|
||||
|
||||
1. 调整混淆时机(支持 MD5 Cache)
|
||||
2. 配置面板参数添加中文名称
|
||||
|
||||
72
README.md
72
README.md
@@ -1,35 +1,49 @@
|
||||
# 代码混淆工具
|
||||
|
||||
### 介绍
|
||||
## 介绍
|
||||
|
||||
[Cocos Creator 编辑器插件] 混淆代码工具,支持项目构建后自动混淆代码以及主动混淆目标文件(TODO)。
|
||||
|
||||
- 混淆引擎:[javascript-obfuscator@0.28.0](https://github.com/javascript-obfuscator/javascript-obfuscator)
|
||||
|
||||
### 截图
|
||||
如果此项目对你有帮助,请不要忘记 [](https://gitee.com/ifaswind/ccc-obfuscated-code/stargazers)
|
||||
|
||||

|
||||
如有使用上的问题,可以在 gitee 上提 issue 或者添加我的微信 `im_chenpipi` 并留言。
|
||||
|
||||
### 运行环境
|
||||
|
||||
|
||||
## 截图
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 环境
|
||||
|
||||
平台:Windows、Mac
|
||||
|
||||
编辑器:Cocos Creator 2.x.x(理论上通用)
|
||||
引擎:Cocos Creator 2.x.x(理论上通用)
|
||||
|
||||
### 插件说明
|
||||
|
||||
1. 插件默认禁用
|
||||
|
||||
2. 点击 **[ 扩展 --> 代码混淆工具 --> 构建后自动混淆 ]** 启用自动混淆并设置参数
|
||||
## 说明
|
||||
|
||||
3. 配置文件保存路径为 **[ {项目根目录}/local/ccc-obfuscated-code.json ]**
|
||||
1. 将插件文件夹 `ccc-obfuscated-code` 放置在 `${用户目录}/.CocosCreator/packages` 目录下即可
|
||||
|
||||
### 参数说明
|
||||
3. 本插件默认禁用,需自行启用
|
||||
|
||||
2. 点击顶部菜单栏的 **[ 扩展 --> 代码混淆工具 ]** 打开插件配置面板
|
||||
|
||||
4. 配置文件存放路径:`${项目目录}/local/ccc-obfuscated-code.json`
|
||||
|
||||
|
||||
|
||||
## 参数说明
|
||||
|
||||
- Javascript Obfuscator 文档:[传送门](https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/README.md)
|
||||
|
||||
- 以下均为我人工翻译的内容,尽我所能翻译得通俗易懂了。
|
||||
|
||||
- 原英文文档:[传送门](https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/README.md)
|
||||
|
||||
|
||||
|
||||
**compact**
|
||||
@@ -476,15 +490,9 @@
|
||||
}
|
||||
```
|
||||
|
||||
### 关于
|
||||
|
||||
作者:陈皮皮(ifaswind)
|
||||
|
||||
公众号:文弱书生陈皮皮
|
||||
|
||||

|
||||
|
||||
### *License*
|
||||
## *License*
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -504,4 +512,28 @@ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
# 菜鸟小栈
|
||||
|
||||
我是陈皮皮,这是我的个人公众号,专注但不仅限于游戏开发、前端和后端技术记录与分享。
|
||||
|
||||
每一篇原创都非常用心,你的关注就是我原创的动力!
|
||||
|
||||
> Input and output.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 交流群
|
||||
|
||||
皮皮创建了一个游戏开发交流群,供大家交流经验、问题求助等。
|
||||
|
||||
感兴趣的小伙伴可以添加我微信 `im_chenpipi` 并留言 `加群`。
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
194
main.js
194
main.js
@@ -6,8 +6,8 @@ const configFileDir = 'local/';
|
||||
const configFileName = 'ccc-obfuscated-code.json';
|
||||
const defaultConfig = {
|
||||
auto: false,
|
||||
files: ['/src/project.js'],
|
||||
useAbsPath: false,
|
||||
// extraFiles: [],
|
||||
// useAbsPath: false,
|
||||
preset: 'lower',
|
||||
options: {}
|
||||
};
|
||||
@@ -15,78 +15,6 @@ const defaultConfig = {
|
||||
const presetFileUrl = 'packages://ccc-obfuscated-code/preset.json';
|
||||
let presets = null;
|
||||
|
||||
/**
|
||||
* 保存配置
|
||||
* @param {object} config
|
||||
*/
|
||||
function saveConfig(config) {
|
||||
let projectPath = Editor.Project.path || Editor.projectPath;
|
||||
let configDirPath = Path.join(projectPath, configFileDir);
|
||||
if (!Fs.existsSync(configDirPath)) Fs.mkdirSync(configDirPath);
|
||||
let configFilePath = Path.join(configDirPath, configFileName);
|
||||
// 读取本地配置
|
||||
let object = {};
|
||||
if (Fs.existsSync(configFilePath)) {
|
||||
object = JSON.parse(Fs.readFileSync(configFilePath, 'utf8'));
|
||||
}
|
||||
// 写入配置
|
||||
for (let key in config) object[key] = config[key];
|
||||
let string = JSON.stringify(object, null, 2);
|
||||
Fs.writeFileSync(configFilePath, string);
|
||||
Editor.log('[CC]', '配置文件路径', configFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置
|
||||
*/
|
||||
function getConfig() {
|
||||
let projectPath = Editor.Project.path || Editor.projectPath;
|
||||
let configFilePath = Path.join(projectPath, configFileDir, configFileName);
|
||||
let config = null;
|
||||
if (Fs.existsSync(configFilePath)) {
|
||||
config = JSON.parse(Fs.readFileSync(configFilePath, 'utf8'));
|
||||
}
|
||||
if (!config) {
|
||||
config = JSON.parse(JSON.stringify(defaultConfig));
|
||||
config.options = getPreset('off');
|
||||
if (config.preset !== 'off') {
|
||||
let preset = getPreset(config.preset);
|
||||
for (let key in preset) {
|
||||
config.options[key] = preset[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取预设参数
|
||||
* @param {string} type 预设名
|
||||
*/
|
||||
function getPreset(type) {
|
||||
if (presets) return presets[type];
|
||||
|
||||
let presetFilePath = Editor.url(presetFileUrl);
|
||||
if (Fs.existsSync(presetFilePath)) {
|
||||
presets = JSON.parse(Fs.readFileSync(presetFilePath, 'utf8'));
|
||||
return presets[type];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 混淆
|
||||
* @param {string} path 文件路径
|
||||
* @param {ObfuscatorOptions} options 混淆参数
|
||||
*/
|
||||
function obfuscate(path, options) {
|
||||
let sourceCode = Fs.readFileSync(path, 'utf8');
|
||||
let obfuscationResult = JavascriptObfuscator.obfuscate(sourceCode, options);
|
||||
let obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
Fs.writeFileSync(path, obfuscatedCode);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
load() {
|
||||
@@ -102,25 +30,24 @@ module.exports = {
|
||||
messages: {
|
||||
|
||||
'open-panel'() {
|
||||
Editor.log('[CC]', '代码混淆工具/构建后自动混淆');
|
||||
Editor.Panel.open('ccc-obfuscated-code');
|
||||
},
|
||||
|
||||
// TODO
|
||||
// 'open-panel-do'() {
|
||||
// Editor.log('[CC] 代码混淆工具/主动混淆');
|
||||
// Editor.Panel.open('ccc-obfuscated-code-do');
|
||||
// },
|
||||
|
||||
'save-config'(event, config) {
|
||||
Editor.log('[CC]', '保存配置');
|
||||
saveConfig(config);
|
||||
const configFilePath = saveConfig(config);
|
||||
Editor.log('[CC]', '保存配置', configFilePath);
|
||||
event.reply(null, true);
|
||||
},
|
||||
|
||||
'read-config'(event) {
|
||||
Editor.log('[CC]', '读取配置');
|
||||
let config = getConfig();
|
||||
const config = getConfig();
|
||||
if (config) Editor.log('[CC]', '读取本地配置');
|
||||
else Editor.log('[CC]', '未找到本地配置文件');
|
||||
event.reply(null, config);
|
||||
},
|
||||
|
||||
@@ -158,21 +85,104 @@ module.exports = {
|
||||
onBeforeChangeFiles(options, callback) {
|
||||
const config = getConfig();
|
||||
if (config.auto) {
|
||||
Editor.log('[CC]', '正在混淆代码...');
|
||||
for (let i = 0; i < config.files.length; i++) {
|
||||
if (config.files[i] === '') continue;
|
||||
let path = config.useAbsPath ? config.files[i] : Path.join(options.dest, config.files[i]);
|
||||
if (Fs.existsSync(path)) {
|
||||
obfuscate(path, config.options);
|
||||
Editor.log('[CC]', '已混淆文件', path);
|
||||
} else {
|
||||
Editor.warn('[CC]', '文件不存在', path);
|
||||
}
|
||||
Editor.log('[CC]', '正在混淆代码');
|
||||
// Cocos Creator 2.4 以下
|
||||
const srcPath = Path.join(options.dest, 'src', 'project.js');
|
||||
if (Fs.existsSync(srcPath)) {
|
||||
obfuscate(srcPath, config.options);
|
||||
Editor.log('[CC]', '已混淆项目代码文件', srcPath);
|
||||
}
|
||||
Editor.log('[CC]', '混淆已结束');
|
||||
// Cocos Creator 2.4 以上
|
||||
const assetsPath = Path.join(options.dest, 'assets', 'main', 'index.js');
|
||||
if (Fs.existsSync(assetsPath)) {
|
||||
obfuscate(assetsPath, config.options);
|
||||
Editor.log('[CC]', '已混淆项目代码文件', assetsPath);
|
||||
}
|
||||
// 额外需要混淆的文件
|
||||
// for (let i = 0; i < config.extraFiles.length; i++) {
|
||||
// if (config.extraFiles[i] === '') continue;
|
||||
// const path = config.useAbsPath ? config.extraFiles[i] : Path.join(options.dest, config.extraFiles[i]);
|
||||
// if (Fs.existsSync(path)) {
|
||||
// obfuscate(path, config.options);
|
||||
// Editor.log('[CC]', '已额外混淆文件', path);
|
||||
// } else {
|
||||
// Editor.warn('[CC]', '需额外混淆文件不存在', path);
|
||||
// }
|
||||
// }
|
||||
Editor.log('[CC]', '混淆已完成');
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存配置
|
||||
* @param {object} config
|
||||
*/
|
||||
function saveConfig(config) {
|
||||
// 查找目录
|
||||
const projectPath = Editor.Project.path || Editor.projectPath;
|
||||
const configDirPath = Path.join(projectPath, configFileDir);
|
||||
if (!Fs.existsSync(configDirPath)) Fs.mkdirSync(configDirPath);
|
||||
const configFilePath = Path.join(projectPath, configFileDir, configFileName);
|
||||
// 读取本地配置
|
||||
let object = {};
|
||||
if (Fs.existsSync(configFilePath)) {
|
||||
object = JSON.parse(Fs.readFileSync(configFilePath, 'utf8'));
|
||||
}
|
||||
// 写入配置
|
||||
for (const key in config) { object[key] = config[key]; }
|
||||
Fs.writeFileSync(configFilePath, JSON.stringify(object, null, 2));
|
||||
return configFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置
|
||||
*/
|
||||
function getConfig() {
|
||||
const projectPath = Editor.Project.path || Editor.projectPath;
|
||||
const configFilePath = Path.join(projectPath, configFileDir, configFileName);
|
||||
let config = null;
|
||||
if (Fs.existsSync(configFilePath)) {
|
||||
config = JSON.parse(Fs.readFileSync(configFilePath, 'utf8'));
|
||||
}
|
||||
if (!config) {
|
||||
config = JSON.parse(JSON.stringify(defaultConfig));
|
||||
config.options = getPreset('off');
|
||||
if (config.preset !== 'off') {
|
||||
const preset = getPreset(config.preset);
|
||||
for (const key in preset) { config.options[key] = preset[key]; }
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取预设参数
|
||||
* @param {string} type 预设名
|
||||
*/
|
||||
function getPreset(type) {
|
||||
if (presets) return presets[type];
|
||||
|
||||
const presetFilePath = Editor.url(presetFileUrl);
|
||||
if (Fs.existsSync(presetFilePath)) {
|
||||
presets = JSON.parse(Fs.readFileSync(presetFilePath, 'utf8'));
|
||||
return presets[type];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 混淆
|
||||
* @param {string} filePath 文件路径
|
||||
* @param {ObfuscatorOptions} options 混淆参数
|
||||
*/
|
||||
function obfuscate(filePath, options) {
|
||||
const sourceCode = Fs.readFileSync(filePath, 'utf8');
|
||||
const obfuscationResult = JavascriptObfuscator.obfuscate(sourceCode, options);
|
||||
const obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
Fs.writeFileSync(filePath, obfuscatedCode);
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "ccc-obfuscated-code",
|
||||
"version": "1.0.2.20200530",
|
||||
"version": "1.0.3.20200802",
|
||||
"description": "代码混淆工具,支持项目构建后自动混淆代码。",
|
||||
"author": "文弱书生陈皮皮",
|
||||
"main": "main.js",
|
||||
"main-menu": {
|
||||
"扩展/代码混淆工具/构建后自动混淆": {
|
||||
"i18n:MAIN_MENU.package.title/代码混淆工具/构建后自动混淆": {
|
||||
"message": "ccc-obfuscated-code:open-panel"
|
||||
}
|
||||
},
|
||||
@@ -13,10 +13,10 @@
|
||||
"main": "panel/index.js",
|
||||
"type": "dockable",
|
||||
"title": "代码混淆工具/构建后自动混淆",
|
||||
"width": 600,
|
||||
"height": 900
|
||||
"width": 620,
|
||||
"height": 910
|
||||
},
|
||||
"dependencies": {
|
||||
"javascript-obfuscator": "^0.28.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@
|
||||
<div>
|
||||
<ui-prop name="构建后自动混淆" type="boolean" v-value="auto" tooltip="· 项目构建完成后根据已保存配置自动混淆代码。"></ui-prop>
|
||||
<hr />
|
||||
<ui-prop name="需要混淆的文件" style='height: 50;'
|
||||
<!-- <ui-prop name="额外需要混淆的文件(非项目代码文件)" style='height: 50;'
|
||||
tooltip="· 默认根目录为项目导出目录 build/{dest}/ · 绝对路径如:E:\hahaha\build\web-mobile\src\project.js * 多个值之间用 ',' 隔开">
|
||||
<ui-checkbox v-value="useAbsPath">绝对路径?</ui-checkbox>
|
||||
<ui-text-area class="flex-1" type="string" v-value="files"></ui-text-area>
|
||||
<ui-text-area v-show="extraFiles != ''" class="flex-1" type="string" v-value="extraFiles"></ui-text-area>
|
||||
<ui-input v-show="extraFiles == ''" class="flex-1" type="string" v-value="extraFiles"></ui-input>
|
||||
</ui-prop>
|
||||
<hr />
|
||||
<hr /> -->
|
||||
<ui-prop name="预设"
|
||||
tooltip="· 可用值: - 高度混淆,性能较低:性能比不混淆慢 50 - 100% - 中度混淆,性能均衡:性能比不混淆慢 30 - 50% - 轻度混淆,性能较高:性能只会比不混淆稍微慢一点点">
|
||||
<ui-select class="flex-1" v-value="preset">
|
||||
@@ -37,8 +38,9 @@
|
||||
<ui-prop name="controlFlowFlattening(逻辑扁平化)" type="boolean" v-value="options.controlFlowFlattening"
|
||||
tooltip="· 皮皮:就是将代码逻辑扁平化了。 · 注意:该选项将严重影响性能,影响高达 1.5 倍。使用 controlFlowFlatteningThreshold 选项来控制转换概率。 · 开启代码控制流扁平化。控制流扁平化会转换源代码的结构,阻碍程序的阅读理解。">
|
||||
</ui-prop>
|
||||
<ui-prop name="controlFlowFlatteningThreshold(扁平化比例)" v-if="options.controlFlowFlattening" indent="1" type="number"
|
||||
v-value="options.controlFlowFlatteningThreshold" step="0.01" min="0" max="1" tooltip="· 应用控制流扁平化的概率。"></ui-prop>
|
||||
<ui-prop name="controlFlowFlatteningThreshold(扁平化比例)" v-if="options.controlFlowFlattening" indent="1"
|
||||
type="number" v-value="options.controlFlowFlatteningThreshold" step="0.01" min="0" max="1"
|
||||
tooltip="· 应用控制流扁平化的概率。"></ui-prop>
|
||||
<ui-prop name="deadCodeInjection(注入废代码)" type="boolean" v-value="options.deadCodeInjection"
|
||||
tooltip="· 皮皮:就是往代码里面随机加一些没有用的代码,迷惑敌人~ · 注意:该选项会大大增加代码的体积(甚至高达 200%)。可以使用 deadCodeInjectionThreshold 来设置添加的比例。 · 注意:开启这个选项会强制使用 stringArray 。">
|
||||
</ui-prop>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
let Fs = require('fs');
|
||||
const Fs = require('fs');
|
||||
|
||||
Editor.Panel.extend({
|
||||
|
||||
@@ -7,7 +7,7 @@ Editor.Panel.extend({
|
||||
template: Fs.readFileSync(Editor.url('packages://ccc-obfuscated-code/panel/index.html'), 'utf8'),
|
||||
|
||||
ready() {
|
||||
let vue = new window.Vue({
|
||||
const app = new window.Vue({
|
||||
el: this.shadowRoot,
|
||||
|
||||
data() {
|
||||
@@ -15,8 +15,8 @@ Editor.Panel.extend({
|
||||
isSaving: false,
|
||||
|
||||
auto: false,
|
||||
files: '/src/project.js',
|
||||
useAbsPath: false,
|
||||
// extraFiles: '',
|
||||
// useAbsPath: false,
|
||||
preset: 'low',
|
||||
options: {
|
||||
compact: true,
|
||||
@@ -59,7 +59,7 @@ Editor.Panel.extend({
|
||||
watch: {
|
||||
options: {
|
||||
handler(value) {
|
||||
if (value.deadCodeInjection) vue.options.stringArray = true;
|
||||
if (value.deadCodeInjection) app.options.stringArray = true;
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
@@ -75,13 +75,13 @@ Editor.Panel.extend({
|
||||
|
||||
let config = {
|
||||
auto: this.auto,
|
||||
files: this.files.split(','),
|
||||
useAbsPath: this.useAbsPath,
|
||||
// useAbsPath: this.useAbsPath,
|
||||
preset: this.preset,
|
||||
options: {}
|
||||
};
|
||||
for (let key in this.options) {
|
||||
switch (key) {
|
||||
// case 'extraFiles':
|
||||
case 'domainLock': case 'identifiersDictionary': case 'reservedNames': case 'reservedStrings':
|
||||
config.options[key] = this.options[key] == '' ? [] : this.options[key].split(',');
|
||||
break;
|
||||
@@ -109,8 +109,8 @@ Editor.Panel.extend({
|
||||
Editor.Ipc.sendToMain('ccc-obfuscated-code:read-config', (err, config) => {
|
||||
if (err) return;
|
||||
this.auto = config.auto;
|
||||
this.files = config.files.join(',');
|
||||
this.useAbsPath = config.useAbsPath;
|
||||
// this.extraFiles = config.extraFiles.join(',');
|
||||
// this.useAbsPath = config.useAbsPath;
|
||||
this.preset = config.preset;
|
||||
for (let key in config.options) {
|
||||
this.options[key] = Array.isArray(config.options[key]) ? config.options[key].join(',') : config.options[key];
|
||||
@@ -132,7 +132,8 @@ Editor.Panel.extend({
|
||||
}
|
||||
});
|
||||
|
||||
vue.readConfig();
|
||||
app.readConfig();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Cocos Creator 编辑器命名空间
|
||||
* @author 陈皮皮(ifaswind)
|
||||
* @see https://gitee.com/ifaswind/eazax-ccc/blob/master/declaration/editor.d.ts
|
||||
* @version 20200727
|
||||
* @see https://gitee.com/ifaswind/eazax-ccc/blob/master/declarations/editor.d.ts
|
||||
*/
|
||||
declare namespace Editor {
|
||||
|
||||
@@ -1102,4 +1103,4 @@ declare module Editor.Utils {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user