File size: 6,183 Bytes
720114a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12cb430
720114a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12cb430
 
 
 
 
 
 
720114a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d297056
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import { spawn } from 'child_process';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import fs from 'fs';
import os from 'os';
import dotenv from 'dotenv';
import chalk from 'chalk';

// 获取当前文件的目录路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// 加载环境变量
dotenv.config({ path: join(dirname(__dirname), '.env') });

// 日志配置
const logger = {
  info: (message) => console.log(chalk.blue(`[ProxyServer] ${message}`)),
  error: (message) => console.error(chalk.red(`[ProxyServer] ${message}`)),
  warning: (message) => console.warn(chalk.yellow(`[ProxyServer] ${message}`)),
  success: (message) => console.log(chalk.green(`[ProxyServer] ${message}`)),
};

class ProxyServer {
  constructor() {
    this.proxyProcess = null;
    this.platform = process.env.PROXY_SERVER_PLATFORM || 'auto';
    this.port = process.env.PROXY_SERVER_PORT || 10655;
    this.logPath = process.env.PROXY_SERVER_LOG_PATH || './proxy_server.log';
    this.enabled = process.env.ENABLE_PROXY_SERVER === 'true';
    this.proxyAuthToken = process.env.PROXY_AUTH_TOKEN || 'default_token';
    this.logStream = null;
  }

  // 获取当前系统平台
  detectPlatform() {
    if (this.platform !== 'auto') {
      return this.platform;
    }

    const platform = os.platform();
    const arch = os.arch();

    if (platform === 'win32') {
      return 'windows';
    } else if (platform === 'linux') {
      if (arch === 'arm64') {
        return 'android';
      } else {
        return 'linux';
      }
    } else if (platform === 'android') {
      return 'android';
    } else {
      logger.warning(`未知平台: ${platform}, ${arch}, 默认使用linux版本`);
      return 'linux';
    }
  }

  // 获取代理服务器可执行文件路径
  getProxyServerPath() {
    const platform = this.detectPlatform();
    const proxyDir = join(__dirname, 'proxy');

    switch (platform) {
      case 'windows':
        return join(proxyDir, 'chrome_proxy_server_windows_amd64.exe');
      case 'linux':
        return join(proxyDir, 'chrome_proxy_server_linux_amd64');
      case 'android':
        return join(proxyDir, 'chrome_proxy_server_android_arm64');
      default:
        logger.error(`不支持的平台: ${platform}`);
        return null;
    }
  }

  // 启动代理服务器
  async start() {
    if (!this.enabled) {
      logger.info('代理服务器未启用,跳过启动');
      return;
    }

    if (this.proxyProcess) {
      logger.warning('代理服务器已经在运行中');
      return;
    }

    const proxyServerPath = this.getProxyServerPath();
    if (!proxyServerPath) {
      logger.error('无法获取代理服务器路径');
      return;
    }

    try {
      // 确保可执行文件有执行权限(在Linux/Android上)
      if (this.detectPlatform() !== 'windows') {
        try {
          fs.chmodSync(proxyServerPath, 0o755);
        } catch (err) {
          logger.warning(`无法设置执行权限: ${err.message}`);
        }
      }

      // 创建日志文件
      this.logStream = fs.createWriteStream(this.logPath, { flags: 'a' });
      
      // 修复 stdio 参数问题
      // 启动代理服务器进程
      this.proxyProcess = spawn(proxyServerPath, [
        '--port', this.port.toString(),
        '--token', this.proxyAuthToken
      ], {
        stdio: ['ignore', 'pipe', 'pipe'], // 使用pipe而不是直接传递流
        detached: false
      });

      // 将进程的输出重定向到日志文件
      if (this.proxyProcess.stdout) {
        this.proxyProcess.stdout.pipe(this.logStream);
      }
      
      if (this.proxyProcess.stderr) {
        this.proxyProcess.stderr.pipe(this.logStream);
      }

      // 设置进程事件处理
      this.proxyProcess.on('error', (err) => {
        logger.error(`代理服务器启动失败: ${err.message}`);
        this.proxyProcess = null;
        if (this.logStream) {
          this.logStream.end();
          this.logStream = null;
        }
      });

      this.proxyProcess.on('exit', (code, signal) => {
        logger.info(`代理服务器已退出,退出码: ${code}, 信号: ${signal}`);
        this.proxyProcess = null;
        if (this.logStream) {
          this.logStream.end();
          this.logStream = null;
        }
      });

      // 等待一段时间,确保服务器启动
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      if (this.proxyProcess && this.proxyProcess.exitCode === null) {
        logger.success(`代理服务器已启动,端口: ${this.port}, 日志文件: ${this.logPath}`);
        return true;
      } else {
        logger.error('代理服务器启动失败');
        if (this.logStream) {
          this.logStream.end();
          this.logStream = null;
        }
        return false;
      }
    } catch (error) {
      logger.error(`启动代理服务器时出错: ${error.message}`);
      if (this.logStream) {
        this.logStream.end();
        this.logStream = null;
      }
      return false;
    }
  }

  // 停止代理服务器
  stop() {
    if (!this.proxyProcess) {
      //logger.info('代理服务器已关闭');
      return;
    }

    try {
      // 在Windows上使用taskkill确保子进程也被终止
      if (this.detectPlatform() === 'windows' && this.proxyProcess.pid) {
        spawn('taskkill', ['/pid', this.proxyProcess.pid, '/f', '/t']);
      } else {
        // 在Linux/Android上使用kill信号
        this.proxyProcess.kill('SIGTERM');
      }

      logger.success('代理服务器已停止');
    } catch (error) {
      logger.error(`停止代理服务器时出错: ${error.message}`);
    } finally {
      this.proxyProcess = null;
      if (this.logStream) {
        this.logStream.end();
        this.logStream = null;
      }
    }
  }
}

// 创建单例
const proxyServer = new ProxyServer();

// 导出
export { proxyServer };