@oxiaom/adoremix 1.0.3 → 1.0.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxiaom/adoremix",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "AdoreMix broadcast server - cross-platform installer, runner and service manager",
5
5
  "bin": {
6
6
  "adoremix": "./bin/adoremix.js"
package/src/cli.js CHANGED
@@ -117,6 +117,21 @@ function buildProgram() {
117
117
  });
118
118
  });
119
119
 
120
+ config
121
+ .command('network')
122
+ .description('交互式配置 IP(内网选网卡 / 外网手动输入),同时设 LocalIP/Meida_ip/Fip')
123
+ .option('--workdir <path>')
124
+ .option('--ip <addr>', '直接指定 IP(非交互)')
125
+ .option('--no-interactive', '自动选第一个网卡')
126
+ .action(async (opts) => {
127
+ const net = require('./config/network');
128
+ const code = await net.setupNetwork(resolveWorkdir(opts.workdir), {
129
+ ip: opts.ip,
130
+ interactive: opts.interactive !== false
131
+ });
132
+ process.exitCode = code || 0;
133
+ });
134
+
120
135
  const runner = require('./runner');
121
136
  const nativeRef = () => {
122
137
  try { return paths.loadNative(); }
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const os = require('os');
4
+ const prompts = require('prompts');
5
+ const logger = require('../logger');
6
+
7
+ const NET_KEYS = [
8
+ 'Settings.LocalIP',
9
+ 'Settings.Meida_ip',
10
+ 'Settings.Fip'
11
+ ];
12
+
13
+ function listInterfaces() {
14
+ const ifaces = os.networkInterfaces();
15
+ const list = [];
16
+ for (const name of Object.keys(ifaces)) {
17
+ for (const it of ifaces[name] || []) {
18
+ if (it.family === 'IPv4' && !it.internal) {
19
+ list.push({ name, address: it.address, mac: it.mac });
20
+ }
21
+ }
22
+ }
23
+ return list;
24
+ }
25
+
26
+ function isValidIPv4(s) {
27
+ return /^(\d{1,3}\.){3}\d{1,3}$/.test(s) && s.split('.').every(p => +p >= 0 && +p <= 255);
28
+ }
29
+
30
+ async function chooseIpInteractive(initial) {
31
+ const list = listInterfaces();
32
+ if (list.length === 0) {
33
+ logger.warn('未检测到任何 IPv4 网卡');
34
+ }
35
+ const choices = list.map(it => ({
36
+ title: `${it.address} (${it.name}${it.mac ? ', ' + it.mac.slice(0, 17) : ''})`,
37
+ value: it.address,
38
+ description: `网卡 ${it.name}`
39
+ }));
40
+ choices.push({
41
+ title: '🌐 手动输入外网/其他 IP(部署到云服务器用)',
42
+ value: '__custom__'
43
+ });
44
+ if (initial) {
45
+ choices.unshift({
46
+ title: `✓ 保持当前 IP: ${initial}`,
47
+ value: initial,
48
+ description: '不改'
49
+ });
50
+ }
51
+
52
+ const onCancel = () => { logger.warn('已取消'); process.exit(1); };
53
+ const resp = await prompts({
54
+ type: 'select',
55
+ name: 'ip',
56
+ message: '选择绑定的 IP',
57
+ choices,
58
+ initial: initial ? 0 : 0
59
+ }, { onCancel });
60
+ if (!resp.ip) return null;
61
+ if (resp.ip === '__custom__') {
62
+ const r2 = await prompts({
63
+ type: 'text',
64
+ name: 'ip',
65
+ message: '输入 IPv4 地址(外网/公网 IP)',
66
+ validate: v => isValidIPv4(v) ? true : 'IPv4 格式错误,如 1.2.3.4'
67
+ }, { onCancel });
68
+ return r2.ip;
69
+ }
70
+ return resp.ip;
71
+ }
72
+
73
+ async function setupNetwork(workdir, opts) {
74
+ opts = opts || {};
75
+ const cfg = require('./index');
76
+ const current = cfg.getConfigValue(workdir, 'Settings.LocalIP');
77
+ let ip;
78
+
79
+ if (opts.ip) {
80
+ if (!isValidIPv4(opts.ip)) {
81
+ logger.error(`IP 格式错误:${opts.ip}`);
82
+ return 1;
83
+ }
84
+ ip = opts.ip;
85
+ logger.log(`使用命令行指定的 IP: ${ip}`);
86
+ } else if (opts.interactive === false) {
87
+ // 非交互模式:自动选第一个网卡
88
+ const list = listInterfaces();
89
+ if (list.length === 0) {
90
+ logger.error('未检测到 IPv4 网卡,请用 --ip <地址> 指定');
91
+ return 1;
92
+ }
93
+ ip = list[0].address;
94
+ logger.log(`非交互模式:自动选择第一个网卡 ${list[0].name} = ${ip}`);
95
+ } else {
96
+ logger.log('');
97
+ logger.log('=== 网络配置向导 ===');
98
+ logger.log('说明:');
99
+ logger.log(' • 内网部署 → 选本机网卡 IP');
100
+ logger.log(' • 外网/云服务器 → 手动输入公网 IP');
101
+ logger.log(` • 将同时设置:${NET_KEYS.join(' / ')}`);
102
+ logger.log('');
103
+ ip = await chooseIpInteractive(current);
104
+ if (!ip) return 1;
105
+ }
106
+
107
+ for (const key of NET_KEYS) {
108
+ cfg.setConfigValue(workdir, key, ip);
109
+ }
110
+ logger.ok(`已设置 ${NET_KEYS.map(k => k.split('.')[1]).join(' / ')} = ${ip}`);
111
+
112
+ // 顺便显示当前端口配置,方便检查
113
+ const ports = [
114
+ ['listener.port', 'HTTP 网页'],
115
+ ['Settings.wbport', 'web 后台'],
116
+ ['Settings.cuteport', 'cutehttpd'],
117
+ ['Settings.DataPort', '媒体数据'],
118
+ ['Settings.ManagePort', '管理端口']
119
+ ];
120
+ logger.log('');
121
+ logger.log('当前端口配置:');
122
+ for (const [k, desc] of ports) {
123
+ const v = cfg.getConfigValue(workdir, k);
124
+ logger.log(` ${desc.padEnd(12)} ${k} = ${v}`);
125
+ }
126
+ logger.log('');
127
+ logger.log('改完后记得:adoremix restart');
128
+ return 0;
129
+ }
130
+
131
+ module.exports = { setupNetwork, listInterfaces, isValidIPv4, NET_KEYS };