-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpnx-cli.js
153 lines (134 loc) · 5.53 KB
/
pnx-cli.js
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
#!/usr/bin/env node
import * as p from '@clack/prompts';
import { writeFile, chmod, unlink } from 'fs/promises';
import { existsSync, createWriteStream } from 'fs';
import figlet from "figlet";
import gradient from "gradient-string";
import axios from "axios";
import extract from "extract-zip";
import os from 'os';
import { spawn } from 'child_process';
import readline from 'readline';
import title from 'title';
let fileinstall = process.cwd();
let serverAlreadyInstalled = false;
// Fetch the latest release information from GitHub
const getRelease = async () => {
try {
const owner = 'PowerNukkitX';
const repo = 'PowerNukkitX';
const response = await axios.get(`https://api.github.com/repos/${owner}/${repo}/releases`);
return response.data;
} catch (error) {
console.error('Error fetching releases from GitHub:', error);
return [];
}
};
// Display the PowerNukkitX banner using figlet and gradient
const displayBanner = () => {
return new Promise((resolve, reject) => {
figlet('PowerNukkitX', (err, data) => {
if (err) {
reject(err);
} else {
console.log(gradient.cristal.multiline(data));
resolve();
}
});
});
};
// Download a file from the given URL and save it to the specified path
const downloadFile = async (url, filePath) => {
return new Promise((resolve, reject) => {
const writer = createWriteStream(filePath);
axios({
url,
method: 'GET',
responseType: 'stream'
}).then(response => {
response.data.pipe(writer);
writer.on('finish', resolve);
writer.on('error', reject);
}).catch(reject);
});
};
// Handle downloading and extracting the PowerNukkitX zip file
const handleDownloadAndExtraction = async (release) => {
const zipAsset = release.assets.find(asset => asset.name === 'powernukkitx-run.zip');
if (zipAsset) {
const zipUrl = zipAsset.browser_download_url;
const zipPath = `${fileinstall}/${zipAsset.name}`;
const downloadSpinner = p.spinner();
downloadSpinner.start('Downloading PowerNukkitX...');
await downloadFile(zipUrl, zipPath);
downloadSpinner.stop('Download completed.');
const extractSpinner = p.spinner();
extractSpinner.start('Extracting...');
await extract(zipPath, { dir: fileinstall });
extractSpinner.stop('Extraction completed.');
const deleteSpinner = p.spinner();
deleteSpinner.start('Deleting file cache...');
await unlink(zipPath);
await unlink(`${fileinstall}/cli.jar`);
if (os.platform() !== 'win32') {
try {
await chmod(`${fileinstall}/start.sh`, '755');
} catch (error) {
console.error('Error occurred while changing permissions:', error);
}
}
deleteSpinner.stop("Installation completed.");
} else {
console.log('No zip file found in the latest release.');
}
};
// Execute the start script for the server
const executeStartScript = async (installPath) => {
const startScript = os.platform() === 'win32' ? `${installPath}/start.bat` : `${installPath}/start.sh`;
const childProcess = spawn(startScript, [], {
stdio: 'inherit',
cwd: installPath,
shell: true
});
childProcess.on('error', (err) => {
console.error(`Error executing ${startScript}: ${err.message}`);
});
childProcess.on('exit', (code, signal) => {
if (code !== 0) {
console.error(`${startScript} exited with code ${code} and signal ${signal}`);
}
});
};
// Check if the required files for the server are present
const checkRequiredFiles = (installPath) => {
return existsSync(`${installPath}/libs`) &&
(existsSync(`${installPath}/start.sh`) || existsSync(`${installPath}/start.bat`)) &&
existsSync(`${installPath}/powernukkitx.jar`);
};
// Main function to coordinate the installation and configuration process
async function main() {
await title('PowerNukkitX CLI');
await displayBanner();
if (checkRequiredFiles(fileinstall)) {
console.log('Required files are already present. Skipping download and extraction.');
await executeStartScript(fileinstall);
serverAlreadyInstalled = true;
}
if(!serverAlreadyInstalled){
await p.intro("Welcome to PowerNukkitX's automatic installer. This program will ask you questions and, depending on the answers, you'll get an installation that's just right for you.");
}
const releases = await getRelease();
if (!serverAlreadyInstalled && releases.length > 0) {
const latestRelease = releases[0];
const startScriptUrl = os.platform() === 'win32'
? 'https://raw.githubusercontent.com/PowerNukkitX/scripts/master/start.bat'
: 'https://raw.githubusercontent.com/PowerNukkitX/scripts/master/start.sh';
const startScriptFileName = os.platform() === 'win32' ? 'start.bat' : 'start.sh';
await downloadFile(startScriptUrl, `${fileinstall}/${startScriptFileName}`);
await handleDownloadAndExtraction(latestRelease);
await executeStartScript(fileinstall);
} else if (!serverAlreadyInstalled) {
console.log('No releases found or server already installed.');
}
}
main().catch(console.error);