atm-droid 1.0.7 → 1.0.8
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/package.json +1 -1
- package/src/autostart.js +163 -0
- package/src/commands.js +8 -0
- package/src/menu.js +29 -0
package/package.json
CHANGED
package/src/autostart.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
const APP_NAME = 'ATM-Droid';
|
|
7
|
+
|
|
8
|
+
// 获取启动命令
|
|
9
|
+
function getStartCommand() {
|
|
10
|
+
const daemonPath = path.join(__dirname, 'daemon-runner.js');
|
|
11
|
+
return `"${process.execPath}" "${daemonPath}"`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Windows: 注册表
|
|
15
|
+
function enableWindows() {
|
|
16
|
+
try {
|
|
17
|
+
const cmd = getStartCommand();
|
|
18
|
+
execSync(`reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "${APP_NAME}" /t REG_SZ /d "${cmd}" /f`, { stdio: 'ignore' });
|
|
19
|
+
return true;
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function disableWindows() {
|
|
26
|
+
try {
|
|
27
|
+
execSync(`reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "${APP_NAME}" /f`, { stdio: 'ignore' });
|
|
28
|
+
return true;
|
|
29
|
+
} catch (e) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isEnabledWindows() {
|
|
35
|
+
try {
|
|
36
|
+
execSync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "${APP_NAME}"`, { stdio: 'ignore' });
|
|
37
|
+
return true;
|
|
38
|
+
} catch (e) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// macOS: LaunchAgents
|
|
44
|
+
function getMacPlistPath() {
|
|
45
|
+
return path.join(os.homedir(), 'Library', 'LaunchAgents', 'com.atm-droid.daemon.plist');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function enableMac() {
|
|
49
|
+
try {
|
|
50
|
+
const plistPath = getMacPlistPath();
|
|
51
|
+
const daemonPath = path.join(__dirname, 'daemon-runner.js');
|
|
52
|
+
|
|
53
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
54
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
55
|
+
<plist version="1.0">
|
|
56
|
+
<dict>
|
|
57
|
+
<key>Label</key>
|
|
58
|
+
<string>com.atm-droid.daemon</string>
|
|
59
|
+
<key>ProgramArguments</key>
|
|
60
|
+
<array>
|
|
61
|
+
<string>${process.execPath}</string>
|
|
62
|
+
<string>${daemonPath}</string>
|
|
63
|
+
</array>
|
|
64
|
+
<key>RunAtLoad</key>
|
|
65
|
+
<true/>
|
|
66
|
+
<key>KeepAlive</key>
|
|
67
|
+
<false/>
|
|
68
|
+
</dict>
|
|
69
|
+
</plist>`;
|
|
70
|
+
|
|
71
|
+
fs.mkdirSync(path.dirname(plistPath), { recursive: true });
|
|
72
|
+
fs.writeFileSync(plistPath, plist);
|
|
73
|
+
return true;
|
|
74
|
+
} catch (e) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function disableMac() {
|
|
80
|
+
try {
|
|
81
|
+
const plistPath = getMacPlistPath();
|
|
82
|
+
if (fs.existsSync(plistPath)) {
|
|
83
|
+
fs.unlinkSync(plistPath);
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function isEnabledMac() {
|
|
92
|
+
return fs.existsSync(getMacPlistPath());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Linux: ~/.config/autostart
|
|
96
|
+
function getLinuxDesktopPath() {
|
|
97
|
+
return path.join(os.homedir(), '.config', 'autostart', 'atm-droid.desktop');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function enableLinux() {
|
|
101
|
+
try {
|
|
102
|
+
const desktopPath = getLinuxDesktopPath();
|
|
103
|
+
const daemonPath = path.join(__dirname, 'daemon-runner.js');
|
|
104
|
+
|
|
105
|
+
const desktop = `[Desktop Entry]
|
|
106
|
+
Type=Application
|
|
107
|
+
Name=ATM Droid Daemon
|
|
108
|
+
Exec=${process.execPath} ${daemonPath}
|
|
109
|
+
Hidden=false
|
|
110
|
+
NoDisplay=true
|
|
111
|
+
X-GNOME-Autostart-enabled=true
|
|
112
|
+
`;
|
|
113
|
+
|
|
114
|
+
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
|
|
115
|
+
fs.writeFileSync(desktopPath, desktop);
|
|
116
|
+
return true;
|
|
117
|
+
} catch (e) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function disableLinux() {
|
|
123
|
+
try {
|
|
124
|
+
const desktopPath = getLinuxDesktopPath();
|
|
125
|
+
if (fs.existsSync(desktopPath)) {
|
|
126
|
+
fs.unlinkSync(desktopPath);
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
} catch (e) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function isEnabledLinux() {
|
|
135
|
+
return fs.existsSync(getLinuxDesktopPath());
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 统一接口
|
|
139
|
+
function enable() {
|
|
140
|
+
const platform = os.platform();
|
|
141
|
+
if (platform === 'win32') return enableWindows();
|
|
142
|
+
if (platform === 'darwin') return enableMac();
|
|
143
|
+
if (platform === 'linux') return enableLinux();
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function disable() {
|
|
148
|
+
const platform = os.platform();
|
|
149
|
+
if (platform === 'win32') return disableWindows();
|
|
150
|
+
if (platform === 'darwin') return disableMac();
|
|
151
|
+
if (platform === 'linux') return disableLinux();
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function isEnabled() {
|
|
156
|
+
const platform = os.platform();
|
|
157
|
+
if (platform === 'win32') return isEnabledWindows();
|
|
158
|
+
if (platform === 'darwin') return isEnabledMac();
|
|
159
|
+
if (platform === 'linux') return isEnabledLinux();
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = { enable, disable, isEnabled };
|
package/src/commands.js
CHANGED
|
@@ -6,6 +6,7 @@ const path = require('path');
|
|
|
6
6
|
const { config, writeFactoryAuth, readFactoryAuth, getFactoryAuthPath } = require('./config');
|
|
7
7
|
const api = require('./api');
|
|
8
8
|
const daemon = require('./daemon');
|
|
9
|
+
const autostart = require('./autostart');
|
|
9
10
|
|
|
10
11
|
// 格式化数字
|
|
11
12
|
function formatNumber(num) {
|
|
@@ -45,6 +46,13 @@ async function login(code) {
|
|
|
45
46
|
console.log(chalk.green(' ✓ 后台服务已启动'));
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
// 默认启用开机自启动
|
|
50
|
+
if (!autostart.isEnabled()) {
|
|
51
|
+
if (autostart.enable()) {
|
|
52
|
+
console.log(chalk.green(' ✓ 已设置开机自启动'));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
console.log(chalk.yellow('\n 提示: 使用 atm list 查看账号列表'));
|
|
49
57
|
} else {
|
|
50
58
|
spinner.fail(chalk.red('激活失败: ' + (result.error || '未知错误')));
|
package/src/menu.js
CHANGED
|
@@ -4,6 +4,7 @@ const fetch = require('node-fetch');
|
|
|
4
4
|
const { config, writeFactoryAuth, getFactoryAuthPath } = require('./config');
|
|
5
5
|
const api = require('./api');
|
|
6
6
|
const daemon = require('./daemon');
|
|
7
|
+
const autostart = require('./autostart');
|
|
7
8
|
const pkg = require('../package.json');
|
|
8
9
|
|
|
9
10
|
let latestVersion = null;
|
|
@@ -79,6 +80,7 @@ async function showStatus() {
|
|
|
79
80
|
console.log(chalk.gray(` 账号: ${tokens.length} 个可用`));
|
|
80
81
|
console.log(chalk.gray(` 自动切换: ${autoSwitch ? '开启' : '关闭'}`));
|
|
81
82
|
console.log(chalk.gray(` 后台服务: ${daemonStatus.running ? '运行中' : '未运行'}`));
|
|
83
|
+
console.log(chalk.gray(` 开机自启: ${autostart.isEnabled() ? '开启' : '关闭'}`));
|
|
82
84
|
console.log();
|
|
83
85
|
|
|
84
86
|
return tokens;
|
|
@@ -93,6 +95,10 @@ async function showStatus() {
|
|
|
93
95
|
// 主菜单
|
|
94
96
|
async function mainMenu() {
|
|
95
97
|
clearScreen();
|
|
98
|
+
|
|
99
|
+
// 每次刷新菜单时检查新版本(后台执行,不阻塞)
|
|
100
|
+
checkNewVersion();
|
|
101
|
+
|
|
96
102
|
showHeader();
|
|
97
103
|
|
|
98
104
|
const tokens = await showStatus();
|
|
@@ -115,6 +121,13 @@ async function mainMenu() {
|
|
|
115
121
|
choices.push({ name: '▶️ 启动后台服务', value: 'start' });
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
// 开机自启动开关
|
|
125
|
+
if (autostart.isEnabled()) {
|
|
126
|
+
choices.push({ name: '🔕 关闭开机自启', value: 'autostart_off' });
|
|
127
|
+
} else {
|
|
128
|
+
choices.push({ name: '🔔 开启开机自启', value: 'autostart_on' });
|
|
129
|
+
}
|
|
130
|
+
|
|
118
131
|
choices.push(new inquirer.Separator());
|
|
119
132
|
choices.push({ name: '🚪 退出登录', value: 'logout' });
|
|
120
133
|
}
|
|
@@ -482,6 +495,22 @@ async function menu() {
|
|
|
482
495
|
case 'logout':
|
|
483
496
|
await doLogout();
|
|
484
497
|
break;
|
|
498
|
+
case 'autostart_on':
|
|
499
|
+
if (autostart.enable()) {
|
|
500
|
+
console.log(chalk.green('\n ✓ 已开启开机自启动\n'));
|
|
501
|
+
} else {
|
|
502
|
+
console.log(chalk.red('\n ✗ 设置失败\n'));
|
|
503
|
+
}
|
|
504
|
+
await pause();
|
|
505
|
+
break;
|
|
506
|
+
case 'autostart_off':
|
|
507
|
+
if (autostart.disable()) {
|
|
508
|
+
console.log(chalk.yellow('\n ✓ 已关闭开机自启动\n'));
|
|
509
|
+
} else {
|
|
510
|
+
console.log(chalk.red('\n ✗ 设置失败\n'));
|
|
511
|
+
}
|
|
512
|
+
await pause();
|
|
513
|
+
break;
|
|
485
514
|
case 'update':
|
|
486
515
|
await doUpdate();
|
|
487
516
|
break;
|