garbage-maker 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Cosmo Lau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # garbage-maker
2
+
3
+ ![GitHub](https://img.shields.io/github/license/CosmoLau/garbage-maker)
4
+
5
+ 为项目中的所有 `JavaScript` 和 `TypeScript` 脚本添加垃圾代码。
6
+
7
+ ## 背景
8
+
9
+ 部分国内小游戏平台可能会对小游戏进行代码检测,未通过检测可能无法过审。
10
+
11
+ 如果小游戏发布次数不多,可通过简单粗暴往代码里加垃圾代码的形式提交审核,这就是此项目的用途。
12
+
13
+ 如果小游戏被多次发布,使用本项目进行过审的概率会大大降低,可以在本项目的源码中修改部分内容进行多次尝试,或者使用其他方式来完成您的需求,例如 `代码混淆`。
14
+
15
+ ## 快速使用
16
+
17
+ > 本项目需要安装 [Node](https://nodejs.org/) 环境。
18
+
19
+ 使用你喜欢的包管理器全局安装 `garbage-maker`:
20
+
21
+ ```shell
22
+ npm install -g garbage-maker
23
+ ```
24
+
25
+ 添加垃圾代码:
26
+
27
+ ```shell
28
+ garbage-maker add [文件或目录的绝对路径]
29
+ ```
30
+
31
+ 清理垃圾代码:
32
+
33
+ ```shell
34
+ garbage-maker clean [文件或目录的绝对路径]
35
+ ```
36
+
37
+ 查看 `garbage-maker` 所有命令的帮助:
38
+
39
+ ```shell
40
+ garbage-maker --help
41
+ ```
42
+
43
+ 查看指定命令的帮助:
44
+
45
+ ```shell
46
+ garbage-maker add --help
47
+ ```
48
+
49
+ ## 自定义添加垃圾代码
50
+
51
+ 使用 `-c` 或者 `--code` 标志(flag)来添加自定义的垃圾代码:
52
+
53
+ ```shell
54
+ garbage-maker add [绝对路径] -c "console.log();"
55
+ # 或者
56
+ garbage-maker add [绝对路径] --code "console.log();"
57
+ ```
58
+
59
+ > _注意_:自定义添加的垃圾代码最好是未出现在已有代码中的。
60
+ > 在使用 `clean` 命令清理代码时,需要传入与 `add` 命令相同的 `--code` 标志,否则会清理默认的 `(1+1);` 垃圾代码。
61
+
62
+ 使用 `-r` 或者 `--ratio` 标志(flag)控制添加垃圾代码的百分比,即根据文件的字符数量,来添加垃圾代码的字符数量。
63
+
64
+ ```shell
65
+ garbage-maker add [绝对路径] -r 50
66
+ # 或者
67
+ garbage-maker add [绝对路径] --ratio 50
68
+ ```
69
+
70
+ > _注意_:`--ratio` 标志的值为百分比的数字部分,即示例中的 `50` 相当于 `50%`。
71
+
72
+ ## 修改源码
73
+
74
+ 该分支使用 [oclif](https://github.com/oclif/oclif) 作为 CLI 框架进行开发,如需对源码进行修改,按照以下方法进行:
75
+
76
+ 1. 安装依赖:
77
+
78
+ ```shell
79
+ npm install
80
+ ```
81
+
82
+ 2. 调试命令:
83
+
84
+ ```shell
85
+ # Windows
86
+ ./bin/dev.cmd --help
87
+ # MacOS 或 Linux
88
+ ./bin/dev.js --help
89
+ ```
90
+
91
+ 3. 构建 CLI:
92
+
93
+ ```shell
94
+ npm link
95
+ ```
96
+
97
+ ## 分支说明
98
+
99
+ 本项目以 `main` 作为默认分支,老版本的 JavaScript 代码仍包含在本项目中,可以查看 [garbage-maker.js](./garbage-maker.js)。
100
+
101
+ 如需查看老版本文档,可以切换至 `master` 分支查看 `README.md`。
102
+
103
+ ## 赞助
104
+
105
+ 如果该项目对你有帮助,不妨点个 `star` 来支持我。
106
+
107
+ 也可以通过其他方式来赞助我,从零开始将我培养成一个开源工具人。
108
+
109
+ [爱发电主页](https://afdian.net/a/CosmoLau)
110
+
111
+ ## LICENSE
112
+
113
+ [MIT License](./LICENSE)
package/bin/dev.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %*
package/bin/dev.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({development: true, dir: import.meta.url})
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Add extends Command {
3
+ static args: {
4
+ path: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ /** 添加的垃圾代码字符串 */
10
+ code: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ /** 添加垃圾代码的比例 */
12
+ ratio: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,86 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { statSync } from 'fs';
3
+ import { GarbageMaker, defaultProp } from '../garbage-maker.js';
4
+ import { confirm, input } from '@inquirer/prompts';
5
+ export default class Add extends Command {
6
+ static args = {
7
+ path: Args.string({
8
+ name: 'path',
9
+ required: true,
10
+ description: '目标文件或目录的路径'
11
+ }),
12
+ };
13
+ static description = '➕添加垃圾代码';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %>',
16
+ ];
17
+ static flags = {
18
+ /** 添加的垃圾代码字符串 */
19
+ code: Flags.string({
20
+ name: 'code',
21
+ description: '自定义添加的垃圾代码',
22
+ char: 'c',
23
+ required: false,
24
+ }),
25
+ /** 添加垃圾代码的比例 */
26
+ ratio: Flags.string({
27
+ name: 'ratio',
28
+ description: '添加垃圾代码的比例',
29
+ char: 'r',
30
+ required: false,
31
+ })
32
+ };
33
+ async run() {
34
+ const { args, flags } = await this.parse(Add);
35
+ this.log(`输入的路径:${args.path}`);
36
+ this.log(`垃圾代码:${flags.code}\n添加比例:${flags.ratio}`);
37
+ if (!flags.code) {
38
+ // 如果没有在标志中传参,对其进行询问
39
+ flags.code = await input({
40
+ message: '想要添加的垃圾代码:',
41
+ default: defaultProp.codeStr
42
+ });
43
+ }
44
+ // 检查文件中是否包含垃圾代码
45
+ let checkCodeConfirm = true;
46
+ if (GarbageMaker.checkCode(args.path, flags.code)) {
47
+ checkCodeConfirm = await confirm({
48
+ message: '现有代码中已包含垃圾代码,是否继续添加?',
49
+ default: false,
50
+ });
51
+ }
52
+ if (!checkCodeConfirm) {
53
+ console.log("已取消添加代码");
54
+ return;
55
+ }
56
+ // 如果没有在标志中传参,对其进行询问
57
+ if (!flags.ratio) {
58
+ flags.ratio = await input({
59
+ message: '添加垃圾代码的比例:',
60
+ default: defaultProp.ratio?.toString()
61
+ });
62
+ }
63
+ try {
64
+ let stat = statSync(args.path);
65
+ if (stat.isDirectory()) {
66
+ this.log("传入的是一个文件夹路径");
67
+ }
68
+ else if (stat.isFile()) {
69
+ this.log("传入的是一个文件路径");
70
+ }
71
+ else {
72
+ this.warn("请输入正确的路径");
73
+ }
74
+ }
75
+ catch (error) {
76
+ this.error("无法读取路径,请输入正确的路径:" + error);
77
+ }
78
+ let prop = {
79
+ sourcePath: args.path,
80
+ addShit: true,
81
+ codeStr: flags.code,
82
+ ratio: flags.ratio ? Number(flags.ratio) : undefined,
83
+ };
84
+ GarbageMaker.execute(prop);
85
+ }
86
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Clean extends Command {
3
+ static args: {
4
+ path: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ /** 清理的垃圾代码字符串 */
10
+ code: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,58 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { GarbageMaker, defaultProp } from '../garbage-maker.js';
3
+ import { statSync } from 'fs';
4
+ import { input } from '@inquirer/prompts';
5
+ export default class Clean extends Command {
6
+ static args = {
7
+ path: Args.string({
8
+ name: 'path',
9
+ required: true,
10
+ description: '目标文件或目录的路径'
11
+ }),
12
+ };
13
+ static description = '🧹清理垃圾代码';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %>',
16
+ ];
17
+ static flags = {
18
+ /** 清理的垃圾代码字符串 */
19
+ code: Flags.string({
20
+ name: 'code',
21
+ description: '需要清理的垃圾代码',
22
+ char: 'c',
23
+ required: false,
24
+ }),
25
+ };
26
+ async run() {
27
+ const { args, flags } = await this.parse(Clean);
28
+ this.log(`输入的路径:${args.path}`);
29
+ this.log(`垃圾代码:${flags.codeStr}\n添加比例:${flags.ratio}`);
30
+ if (!flags.code) {
31
+ flags.code = await input({
32
+ message: '需要清理的垃圾代码:',
33
+ default: defaultProp.codeStr
34
+ });
35
+ }
36
+ try {
37
+ let stat = statSync(args.path);
38
+ if (stat.isDirectory()) {
39
+ this.log("传入的是一个文件夹路径");
40
+ }
41
+ else if (stat.isFile()) {
42
+ this.log("传入的是一个文件路径");
43
+ }
44
+ else {
45
+ this.warn("请输入正确的路径");
46
+ }
47
+ }
48
+ catch (error) {
49
+ this.error("无法读取路径,请输入正确的路径:" + error);
50
+ }
51
+ let prop = {
52
+ sourcePath: args.path,
53
+ addShit: false,
54
+ codeStr: flags.code,
55
+ };
56
+ GarbageMaker.execute(prop);
57
+ }
58
+ }
@@ -0,0 +1,34 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { PathLike } from "fs";
3
+ /**
4
+ * garbage-maker 类的参数接口
5
+ */
6
+ export interface Prop {
7
+ /** 源文件路径 */
8
+ sourcePath: PathLike;
9
+ /** 是否添加垃圾代码 */
10
+ addShit?: boolean;
11
+ /** 垃圾代码内容 */
12
+ codeStr?: string;
13
+ /** 添加垃圾代码的比例 */
14
+ ratio?: number;
15
+ }
16
+ /** 默认参数 */
17
+ export declare const defaultProp: Prop;
18
+ /**
19
+ * garbage-maker 核心代码类
20
+ */
21
+ export declare class GarbageMaker {
22
+ /**
23
+ * 执行代码
24
+ * @param prop 参数
25
+ */
26
+ static execute(prop: Prop): void;
27
+ /**
28
+ * 检查垃圾代码是否存在
29
+ * @param path 文件或文件夹的绝对路径
30
+ * @param codeStr 代码字符串
31
+ * @returns
32
+ */
33
+ static checkCode(path: PathLike, codeStr: string): boolean;
34
+ }
@@ -0,0 +1,106 @@
1
+ import { readFileSync, readdirSync, statSync, writeFileSync } from "fs";
2
+ import { extname, join } from "path";
3
+ /** 默认参数 */
4
+ export const defaultProp = {
5
+ sourcePath: "",
6
+ addShit: true,
7
+ codeStr: "(1+1);",
8
+ ratio: 35,
9
+ };
10
+ /**
11
+ * garbage-maker 核心代码类
12
+ */
13
+ export class GarbageMaker {
14
+ /**
15
+ * 执行代码
16
+ * @param prop 参数
17
+ */
18
+ static execute(prop) {
19
+ /** 已修改的文件数量 */
20
+ let fileChangeNum = 0;
21
+ // 检查可选参数
22
+ prop.addShit = prop.addShit ?? defaultProp.addShit;
23
+ prop.codeStr = prop.codeStr ?? defaultProp.codeStr;
24
+ prop.ratio = prop.ratio ?? defaultProp.ratio;
25
+ /** 添加垃圾代码 */
26
+ let addCode = (path) => {
27
+ let context = readFileSync(path, 'utf8');
28
+ let num = Math.floor(context.length * prop.ratio / 100 / prop.codeStr?.length);
29
+ for (let i = 0; i < num; i++) {
30
+ context += prop.codeStr;
31
+ }
32
+ writeFileSync(path, context, 'utf8');
33
+ fileChangeNum++;
34
+ };
35
+ /** 清理垃圾代码 */
36
+ let cleanCode = (path) => {
37
+ let context = readFileSync(path, 'utf8');
38
+ let pattern = prop.codeStr?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
39
+ let reg = new RegExp(pattern, 'g');
40
+ context = context.replace(reg, "");
41
+ writeFileSync(path, context, 'utf8');
42
+ fileChangeNum++;
43
+ };
44
+ /** 遍历文件夹 */
45
+ let traverseFile = (path) => {
46
+ let files = readdirSync(path);
47
+ files.forEach(val => {
48
+ let subPath = join(path.toString(), val);
49
+ let stat = statSync(subPath);
50
+ if (stat.isFile() && (extname(subPath) == ".ts" || extname(subPath) == ".js")) {
51
+ prop.addShit ? addCode(subPath) : cleanCode(subPath);
52
+ }
53
+ if (stat.isDirectory()) {
54
+ traverseFile(subPath);
55
+ }
56
+ });
57
+ };
58
+ let stat = statSync(prop.sourcePath);
59
+ if (stat.isFile() && (extname(prop.sourcePath.toString()) == ".ts" || extname(prop.sourcePath.toString()) == ".js")) {
60
+ prop.addShit ? addCode(prop.sourcePath) : cleanCode(prop.sourcePath);
61
+ }
62
+ if (stat.isDirectory()) {
63
+ traverseFile(prop.sourcePath);
64
+ }
65
+ console.log(`已修改 ${fileChangeNum} 个文件`);
66
+ }
67
+ /**
68
+ * 检查垃圾代码是否存在
69
+ * @param path 文件或文件夹的绝对路径
70
+ * @param codeStr 代码字符串
71
+ * @returns
72
+ */
73
+ static checkCode(path, codeStr) {
74
+ /** 是否存在代码 */
75
+ let haveCode = false;
76
+ /** 清理垃圾代码 */
77
+ let check = (path) => {
78
+ let context = readFileSync(path, 'utf8');
79
+ let pattern = codeStr?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
80
+ let reg = new RegExp(pattern, 'g');
81
+ haveCode = reg.test(context) ? true : haveCode;
82
+ };
83
+ /** 遍历文件夹 */
84
+ let traverseFile = (path) => {
85
+ let files = readdirSync(path);
86
+ files.forEach(val => {
87
+ let subPath = join(path.toString(), val);
88
+ let stat = statSync(subPath);
89
+ if (stat.isFile() && (extname(subPath) == ".ts" || extname(subPath) == ".js")) {
90
+ check(subPath);
91
+ }
92
+ if (stat.isDirectory()) {
93
+ traverseFile(subPath);
94
+ }
95
+ });
96
+ };
97
+ let stat = statSync(path);
98
+ if (stat.isFile() && (extname(path.toString()) == ".ts" || extname(path.toString()) == ".js")) {
99
+ check(path);
100
+ }
101
+ if (stat.isDirectory()) {
102
+ traverseFile(path);
103
+ }
104
+ return haveCode;
105
+ }
106
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "commands": {
3
+ "add": {
4
+ "aliases": [],
5
+ "args": {
6
+ "path": {
7
+ "description": "目标文件或目录的路径",
8
+ "name": "path",
9
+ "required": true
10
+ }
11
+ },
12
+ "description": "➕添加垃圾代码",
13
+ "examples": [
14
+ "<%= config.bin %> <%= command.id %>"
15
+ ],
16
+ "flags": {
17
+ "code": {
18
+ "char": "c",
19
+ "description": "自定义添加的垃圾代码",
20
+ "name": "code",
21
+ "required": false,
22
+ "hasDynamicHelp": false,
23
+ "multiple": false,
24
+ "type": "option"
25
+ },
26
+ "ratio": {
27
+ "char": "r",
28
+ "description": "添加垃圾代码的比例",
29
+ "name": "ratio",
30
+ "required": false,
31
+ "hasDynamicHelp": false,
32
+ "multiple": false,
33
+ "type": "option"
34
+ }
35
+ },
36
+ "hasDynamicHelp": false,
37
+ "hiddenAliases": [],
38
+ "id": "add",
39
+ "pluginAlias": "garbage-maker",
40
+ "pluginName": "garbage-maker",
41
+ "pluginType": "core",
42
+ "strict": true,
43
+ "enableJsonFlag": false,
44
+ "isESM": true,
45
+ "relativePath": [
46
+ "dist",
47
+ "commands",
48
+ "add.js"
49
+ ]
50
+ },
51
+ "clean": {
52
+ "aliases": [],
53
+ "args": {
54
+ "path": {
55
+ "description": "目标文件或目录的路径",
56
+ "name": "path",
57
+ "required": true
58
+ }
59
+ },
60
+ "description": "🧹清理垃圾代码",
61
+ "examples": [
62
+ "<%= config.bin %> <%= command.id %>"
63
+ ],
64
+ "flags": {
65
+ "code": {
66
+ "char": "c",
67
+ "description": "需要清理的垃圾代码",
68
+ "name": "code",
69
+ "required": false,
70
+ "hasDynamicHelp": false,
71
+ "multiple": false,
72
+ "type": "option"
73
+ }
74
+ },
75
+ "hasDynamicHelp": false,
76
+ "hiddenAliases": [],
77
+ "id": "clean",
78
+ "pluginAlias": "garbage-maker",
79
+ "pluginName": "garbage-maker",
80
+ "pluginType": "core",
81
+ "strict": true,
82
+ "enableJsonFlag": false,
83
+ "isESM": true,
84
+ "relativePath": [
85
+ "dist",
86
+ "commands",
87
+ "clean.js"
88
+ ]
89
+ }
90
+ },
91
+ "version": "0.2.0"
92
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "garbage-maker",
3
+ "version": "0.2.0",
4
+ "description": "garbage-maker,向 JS 和 TS 文件中添加垃圾代码",
5
+ "keywords": [
6
+ "oclif",
7
+ "garbage-maker"
8
+ ],
9
+ "homepage": "https://github.com/CosmoLau/garbage-maker",
10
+ "bugs": "https://github.com/CosmoLau/garbage-maker/issues",
11
+ "repository": "CosmoLau/garbage-maker",
12
+ "license": "MIT",
13
+ "author": "CosmoLau",
14
+ "type": "module",
15
+ "exports": "./lib/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "bin": {
18
+ "garbage-maker": "./bin/run.js"
19
+ },
20
+ "files": [
21
+ "/bin",
22
+ "/dist",
23
+ "/oclif.manifest.json"
24
+ ],
25
+ "scripts": {
26
+ "build": "shx rm -rf dist && tsc -b",
27
+ "prepack": "npm run build && oclif manifest && oclif readme",
28
+ "postpack": "shx rm -f oclif.manifest.json",
29
+ "prepare": "npm run build",
30
+ "test": "mocha --forbid-only \"test/**/*.test.ts\"",
31
+ "version": "oclif readme && git add README.md"
32
+ },
33
+ "oclif": {
34
+ "bin": "garbage-maker",
35
+ "commands": "./dist/commands",
36
+ "dirname": "garbage-maker",
37
+ "plugins": [
38
+ "@oclif/plugin-help",
39
+ "@oclif/plugin-plugins"
40
+ ],
41
+ "topicSeparator": " "
42
+ },
43
+ "dependencies": {
44
+ "@inquirer/prompts": "^5.0.1",
45
+ "@oclif/core": "^3",
46
+ "@oclif/plugin-help": "^6",
47
+ "@oclif/plugin-plugins": "^5",
48
+ "@types/inquirer": "^9.0.7"
49
+ },
50
+ "devDependencies": {
51
+ "@oclif/prettier-config": "^0.2.1",
52
+ "@oclif/test": "^3",
53
+ "@types/chai": "^4",
54
+ "@types/mocha": "^10",
55
+ "@types/node": "^18",
56
+ "chai": "^4",
57
+ "mocha": "^10",
58
+ "oclif": "^4.8.2",
59
+ "shx": "^0.3.4",
60
+ "ts-node": "^10.9.2",
61
+ "typescript": "^5"
62
+ },
63
+ "engines": {
64
+ "node": ">=18.0.0"
65
+ }
66
+ }