-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontroller.js
More file actions
268 lines (235 loc) · 6.19 KB
/
controller.js
File metadata and controls
268 lines (235 loc) · 6.19 KB
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
const { spawn, exec } = require('child_process');
const readline = require('readline');
const net = require('net');
const PORT = 4000; // Define the port for TCP server
let chalk;
let serverProcess = null;
let lastPromptCleared = false;
(async () => {
chalk = (await import('chalk')).default;
startCLI(); // Start CLI only after chalk is ready
startTCPServer(); // Start the TCP server for remote commands
})();
// Function to display logs with color and ensure prompt is shown correctly
function logWithPrompt(prefix, message, color = 'white') {
clearPrompt(); // Remove previous command list before logging new output
let coloredPrefix = prefix;
if (chalk) {
if (prefix === '[Server Manager]') {
coloredPrefix = chalk.magenta.bold(prefix);
} else if (prefix === '[Server]') {
coloredPrefix = chalk.green.bold(prefix);
}
}
console.log(coloredPrefix + ' ' + message);
redisplayPrompt(); // Ensure prompt remains at the bottom
}
// Function to clear the previous command list before outputting new logs
function clearPrompt() {
if (!lastPromptCleared) {
readline.moveCursor(process.stdout, 0, -1);
readline.clearLine(process.stdout, 0);
lastPromptCleared = true;
}
}
// Ensure the prompt remains at the bottom and only prints once
function redisplayPrompt() {
lastPromptCleared = false;
console.log(
chalk.magenta.bold('[Server Manager] ') +
chalk.green('START') +
' | ' +
chalk.yellow('STOP') +
' | ' +
chalk.magenta('RESTART') +
' | ' +
chalk.blue('UPDATE') +
' | ' +
chalk.red('EXIT')
);
process.stdout.write('> ');
}
// Function to start the server
function startServer() {
if (serverProcess) {
logWithPrompt('[Server Manager]', 'Server is already running.', 'yellow');
return;
}
logWithPrompt('[Server Manager]', 'Starting server...', 'green');
serverProcess = spawn('npm', ['run', 'controller'], {
shell: true,
detached: false,
stdio: ['pipe', 'pipe', 'pipe'],
});
serverProcess.stdout.on('data', (data) => {
logWithPrompt('[Server]', data.toString().trim());
});
serverProcess.stderr.on('data', (data) => {
logWithPrompt('[Server Error]', data.toString().trim(), 'red');
});
serverProcess.on('close', (code) => {
logWithPrompt(
'[Server Manager]',
`Server process exited with code ${code}`,
'yellow'
);
serverProcess = null;
});
logWithPrompt('[Server Manager]', 'Server started.', 'green');
}
// Function to stop the server
async function stopServer() {
if (!serverProcess) {
logWithPrompt('[Server Manager]', 'No server running.', 'yellow');
return;
}
logWithPrompt('[Server Manager]', 'Stopping server...', 'yellow');
const pid = serverProcess.pid;
serverProcess = null;
if (process.platform === 'win32') {
exec(`taskkill /pid ${pid} /T /F`, (err) => {
if (err) {
logWithPrompt('[Server Manager]', 'Error stopping server.', 'red');
} else {
logWithPrompt('[Server Manager]', 'Server stopped.', 'green');
}
});
} else {
try {
process.kill(-pid, 'SIGTERM');
logWithPrompt(
'[Server Manager]',
'SIGTERM sent to process group.',
'cyan'
);
setTimeout(() => {
try {
process.kill(-pid, 0);
logWithPrompt(
'[Server Manager]',
'Process still running. Force killing...',
'red'
);
process.kill(-pid, 'SIGKILL');
} catch (error) {
logWithPrompt(
'[Server Manager]',
'Server process successfully stopped.',
'green'
);
}
}, 3000);
} catch (err) {
logWithPrompt('[Server Manager]', 'Error stopping server.', 'red');
}
}
}
// Function to restart the server
async function restartServer() {
logWithPrompt('[Server Manager]', 'Restarting server...', 'cyan');
await stopServer();
setTimeout(() => {
startServer();
}, 2000);
}
// Function to update code and restart
async function updateAndRestart() {
logWithPrompt('[Server Manager]', 'Updating code...', 'cyan');
await stopServer();
const gitFetch = spawn('git', ['fetch'], { shell: true });
gitFetch.stdout.on('data', (data) =>
logWithPrompt('[Git]', data.toString().trim(), 'cyan')
);
gitFetch.stderr.on('data', (data) =>
logWithPrompt('[Git Error]', data.toString().trim(), 'red')
);
gitFetch.on('close', (fetchCode) => {
if (fetchCode !== 0) {
logWithPrompt(
'[Server Manager]',
'Git fetch failed. Aborting update.',
'red'
);
return;
}
const gitPull = spawn('git', ['pull'], { shell: true });
gitPull.stdout.on('data', (data) =>
logWithPrompt('[Git]', data.toString().trim(), 'cyan')
);
gitPull.stderr.on('data', (data) =>
logWithPrompt('[Git Error]', data.toString().trim(), 'red')
);
gitPull.on('close', (pullCode) => {
if (pullCode === 0) {
logWithPrompt(
'[Server Manager]',
'Git pull successful. Restarting server...',
'green'
);
startServer();
} else {
logWithPrompt(
'[Server Manager]',
'Git pull failed. Server will not restart.',
'red'
);
}
});
});
}
// Start TCP server for remote commands
function startTCPServer() {
const server = net.createServer((socket) => {
logWithPrompt('[TCP]', 'Remote connection established.', 'cyan');
socket.on('data', (data) => {
const command = data.toString().trim();
logWithPrompt('[TCP]', `Received command: ${command}`, 'yellow');
handleCommand(command);
});
socket.on('close', () => {
logWithPrompt('[TCP]', 'Remote connection closed.', 'cyan');
});
});
server.listen(PORT, '0.0.0.0', () => {
logWithPrompt(
'[Server Manager]',
`Listening for remote commands on port ${PORT}...`,
'cyan'
);
});
}
// Function to handle commands
function handleCommand(command) {
switch (command) {
case 'start':
startServer();
break;
case 'stop':
stopServer();
break;
case 'restart':
restartServer();
break;
case 'update':
updateAndRestart();
break;
case 'exit':
logWithPrompt('[Server Manager]', 'Exiting...', 'red');
stopServer();
process.exit(0);
break;
default:
logWithPrompt('[Server Manager]', chalk.red('Unknown command'), 'yellow');
}
}
// Function to start the CLI
function startCLI() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on('line', (input) => {
handleCommand(input.trim());
});
startServer();
}