@dimzxzzx07/mc-headless 1.6.0 → 1.8.0

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.
@@ -3,192 +3,179 @@ import { FileUtils } from '../utils/FileUtils';
3
3
  import { Logger } from '../utils/Logger';
4
4
  import * as path from 'path';
5
5
  import axios from 'axios';
6
+ import * as fs from 'fs-extra';
6
7
 
7
8
  export interface ViaVersionInfo {
8
9
  version: string;
9
- build: number;
10
10
  downloadUrl: string;
11
+ fileName: string;
11
12
  }
12
13
 
13
14
  export class ViaVersionManager {
14
15
  private logger = Logger.getInstance();
15
16
 
17
+ private readonly VIAVERSION_URL = 'https://github.com/ViaVersion/ViaVersion/releases/download/5.7.2/ViaVersion-5.7.2.jar';
18
+ private readonly VIABACKWARDS_URL = 'https://github.com/ViaVersion/ViaBackwards/releases/download/5.7.2/ViaBackwards-5.7.2.jar';
19
+ private readonly VIAREWIND_URL = 'https://github.com/ViaVersion/ViaRewind/releases/download/4.0.15/ViaRewind-4.0.15.jar';
20
+
16
21
  public async setup(config: MinecraftConfig): Promise<void> {
17
22
  const pluginsDir = config.folders.plugins;
18
23
  await FileUtils.ensureDir(pluginsDir);
19
24
 
20
25
  this.logger.info('Setting up ViaVersion, ViaBackwards, ViaRewind...');
21
26
 
27
+ await this.cleanupCorruptFiles(pluginsDir);
28
+
22
29
  await this.downloadViaVersion(pluginsDir);
23
30
  await this.downloadViaBackwards(pluginsDir);
24
31
  await this.downloadViaRewind(pluginsDir);
25
32
 
33
+ await this.verifyAllPlugins(pluginsDir);
34
+
26
35
  this.logger.success('ViaVersion suite installed successfully');
27
36
  this.logger.info('Players from older versions can now connect to your server');
28
37
  }
29
38
 
30
- private async getLatestViaVersionInfo(): Promise<ViaVersionInfo> {
31
- try {
32
- const response = await axios.get('https://api.github.com/repos/ViaVersion/ViaVersion/releases/latest');
33
- const tag = response.data.tag_name;
34
- const version = tag.replace('v', '');
35
-
36
- return {
37
- version: version,
38
- build: 0,
39
- downloadUrl: response.data.assets[0].browser_download_url
40
- };
41
- } catch (error) {
42
- this.logger.error('Failed to get ViaVersion info from GitHub, using fallback URL');
43
- return {
44
- version: '4.9.0',
45
- build: 0,
46
- downloadUrl: 'https://github.com/ViaVersion/ViaVersion/releases/download/v4.9.0/ViaVersion-4.9.0.jar'
47
- };
48
- }
49
- }
39
+ private async cleanupCorruptFiles(pluginsDir: string): Promise<void> {
40
+ const files = [
41
+ { name: 'ViaVersion.jar', url: this.VIAVERSION_URL },
42
+ { name: 'ViaBackwards.jar', url: this.VIABACKWARDS_URL },
43
+ { name: 'ViaRewind.jar', url: this.VIAREWIND_URL }
44
+ ];
50
45
 
51
- private async getLatestViaBackwardsInfo(): Promise<ViaVersionInfo> {
52
- try {
53
- const response = await axios.get('https://api.github.com/repos/ViaVersion/ViaBackwards/releases/latest');
54
- const tag = response.data.tag_name;
55
- const version = tag.replace('v', '');
46
+ for (const file of files) {
47
+ const filePath = path.join(pluginsDir, file.name);
56
48
 
57
- return {
58
- version: version,
59
- build: 0,
60
- downloadUrl: response.data.assets[0].browser_download_url
61
- };
62
- } catch (error) {
63
- this.logger.error('Failed to get ViaBackwards info from GitHub, using fallback URL');
64
- return {
65
- version: '4.9.0',
66
- build: 0,
67
- downloadUrl: 'https://github.com/ViaVersion/ViaBackwards/releases/download/v4.9.0/ViaBackwards-4.9.0.jar'
68
- };
49
+ if (await FileUtils.fileExists(filePath)) {
50
+ try {
51
+ const stats = await fs.stat(filePath);
52
+ if (stats.size < 100000) {
53
+ this.logger.warning(`Corrupt ${file.name} detected (${stats.size} bytes), removing...`);
54
+ await fs.remove(filePath);
55
+ } else {
56
+ const buffer = await fs.readFile(filePath);
57
+ if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
58
+ this.logger.warning(`Invalid ZIP header in ${file.name}, removing...`);
59
+ await fs.remove(filePath);
60
+ } else {
61
+ this.logger.info(`${file.name} is valid, keeping it`);
62
+ }
63
+ }
64
+ } catch (error) {
65
+ this.logger.warning(`Error checking ${file.name}, removing...`);
66
+ await fs.remove(filePath);
67
+ }
68
+ }
69
69
  }
70
70
  }
71
71
 
72
- private async getLatestViaRewindInfo(): Promise<ViaVersionInfo> {
73
- try {
74
- const response = await axios.get('https://api.github.com/repos/ViaVersion/ViaRewind/releases/latest');
75
- const tag = response.data.tag_name;
76
- const version = tag.replace('v', '');
77
-
78
- return {
79
- version: version,
80
- build: 0,
81
- downloadUrl: response.data.assets[0].browser_download_url
82
- };
83
- } catch (error) {
84
- this.logger.error('Failed to get ViaRewind info from GitHub, using fallback URL');
85
- return {
86
- version: '3.0.0',
87
- build: 0,
88
- downloadUrl: 'https://github.com/ViaVersion/ViaRewind/releases/download/v3.0.0/ViaRewind-3.0.0.jar'
89
- };
90
- }
91
- }
72
+ private async downloadFile(url: string, destPath: string, fileName: string): Promise<void> {
73
+ this.logger.info(`Downloading ${fileName}...`);
92
74
 
93
- private async downloadViaVersion(pluginsDir: string): Promise<void> {
94
- const viaVersionJar = path.join(pluginsDir, 'ViaVersion.jar');
95
-
96
- if (await FileUtils.fileExists(viaVersionJar)) {
97
- this.logger.info('ViaVersion already exists, skipping download');
98
- return;
99
- }
100
-
101
- this.logger.info('Downloading ViaVersion...');
102
-
103
75
  try {
104
- const info = await this.getLatestViaVersionInfo();
105
-
106
76
  const response = await axios({
107
77
  method: 'GET',
108
- url: info.downloadUrl,
109
- responseType: 'stream'
78
+ url: url,
79
+ responseType: 'stream',
80
+ timeout: 60000,
81
+ headers: {
82
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
83
+ }
110
84
  });
111
85
 
112
- const writer = require('fs').createWriteStream(viaVersionJar);
86
+ const writer = fs.createWriteStream(destPath);
113
87
  response.data.pipe(writer);
114
88
 
115
- await new Promise((resolve, reject) => {
116
- writer.on('finish', resolve);
117
- writer.on('error', reject);
89
+ await new Promise<void>((resolve, reject) => {
90
+ writer.on('finish', () => resolve());
91
+ writer.on('error', (err) => reject(err));
118
92
  });
119
93
 
120
- this.logger.success(`ViaVersion ${info.version} downloaded`);
94
+ const stats = await fs.stat(destPath);
95
+ if (stats.size < 100000) {
96
+ throw new Error(`Downloaded file too small: ${stats.size} bytes`);
97
+ }
98
+
99
+ const buffer = await fs.readFile(destPath);
100
+ if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
101
+ throw new Error('Invalid ZIP header');
102
+ }
103
+
104
+ this.logger.success(`Downloaded: ${fileName} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
105
+
121
106
  } catch (error) {
122
- this.logger.error('Failed to download ViaVersion', error);
107
+ this.logger.error(`Failed to download ${fileName}:`, error);
123
108
  throw error;
124
109
  }
125
110
  }
126
111
 
127
- private async downloadViaBackwards(pluginsDir: string): Promise<void> {
128
- const viaBackwardsJar = path.join(pluginsDir, 'ViaBackwards.jar');
112
+ private async downloadViaVersion(pluginsDir: string): Promise<void> {
113
+ const destPath = path.join(pluginsDir, 'ViaVersion.jar');
129
114
 
130
- if (await FileUtils.fileExists(viaBackwardsJar)) {
131
- this.logger.info('ViaBackwards already exists, skipping download');
132
- return;
115
+ if (await FileUtils.fileExists(destPath)) {
116
+ await fs.remove(destPath);
133
117
  }
134
118
 
135
- this.logger.info('Downloading ViaBackwards...');
136
-
137
- try {
138
- const info = await this.getLatestViaBackwardsInfo();
139
-
140
- const response = await axios({
141
- method: 'GET',
142
- url: info.downloadUrl,
143
- responseType: 'stream'
144
- });
145
-
146
- const writer = require('fs').createWriteStream(viaBackwardsJar);
147
- response.data.pipe(writer);
148
-
149
- await new Promise((resolve, reject) => {
150
- writer.on('finish', resolve);
151
- writer.on('error', reject);
152
- });
119
+ await this.downloadFile(this.VIAVERSION_URL, destPath, 'ViaVersion.jar');
120
+ }
153
121
 
154
- this.logger.success(`ViaBackwards ${info.version} downloaded`);
155
- } catch (error) {
156
- this.logger.error('Failed to download ViaBackwards', error);
157
- throw error;
122
+ private async downloadViaBackwards(pluginsDir: string): Promise<void> {
123
+ const destPath = path.join(pluginsDir, 'ViaBackwards.jar');
124
+
125
+ if (await FileUtils.fileExists(destPath)) {
126
+ await fs.remove(destPath);
158
127
  }
128
+
129
+ await this.downloadFile(this.VIABACKWARDS_URL, destPath, 'ViaBackwards.jar');
159
130
  }
160
131
 
161
132
  private async downloadViaRewind(pluginsDir: string): Promise<void> {
162
- const viaRewindJar = path.join(pluginsDir, 'ViaRewind.jar');
133
+ const destPath = path.join(pluginsDir, 'ViaRewind.jar');
163
134
 
164
- if (await FileUtils.fileExists(viaRewindJar)) {
165
- this.logger.info('ViaRewind already exists, skipping download');
166
- return;
135
+ if (await FileUtils.fileExists(destPath)) {
136
+ await fs.remove(destPath);
167
137
  }
168
138
 
169
- this.logger.info('Downloading ViaRewind...');
170
-
171
- try {
172
- const info = await this.getLatestViaRewindInfo();
173
-
174
- const response = await axios({
175
- method: 'GET',
176
- url: info.downloadUrl,
177
- responseType: 'stream'
178
- });
139
+ await this.downloadFile(this.VIAREWIND_URL, destPath, 'ViaRewind.jar');
140
+ }
179
141
 
180
- const writer = require('fs').createWriteStream(viaRewindJar);
181
- response.data.pipe(writer);
142
+ private async verifyAllPlugins(pluginsDir: string): Promise<void> {
143
+ const files = ['ViaVersion.jar', 'ViaBackwards.jar', 'ViaRewind.jar'];
144
+ let allValid = true;
182
145
 
183
- await new Promise((resolve, reject) => {
184
- writer.on('finish', resolve);
185
- writer.on('error', reject);
186
- });
146
+ for (const file of files) {
147
+ const filePath = path.join(pluginsDir, file);
148
+
149
+ if (!await FileUtils.fileExists(filePath)) {
150
+ this.logger.error(`${file} is missing!`);
151
+ allValid = false;
152
+ continue;
153
+ }
154
+
155
+ try {
156
+ const stats = await fs.stat(filePath);
157
+ if (stats.size < 100000) {
158
+ this.logger.error(`${file} is too small: ${stats.size} bytes`);
159
+ allValid = false;
160
+ continue;
161
+ }
162
+
163
+ const buffer = await fs.readFile(filePath);
164
+ if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
165
+ this.logger.error(`${file} has invalid ZIP header`);
166
+ allValid = false;
167
+ continue;
168
+ }
169
+
170
+ this.logger.debug(`${file} verified OK (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
171
+ } catch (error) {
172
+ this.logger.error(`Failed to verify ${file}:`, error);
173
+ allValid = false;
174
+ }
175
+ }
187
176
 
188
- this.logger.success(`ViaRewind ${info.version} downloaded`);
189
- } catch (error) {
190
- this.logger.error('Failed to download ViaRewind', error);
191
- throw error;
177
+ if (!allValid) {
178
+ throw new Error('Some ViaVersion plugins are corrupt or missing');
192
179
  }
193
180
  }
194
181
 
@@ -202,25 +189,23 @@ export class ViaVersionManager {
202
189
  const configContent = `# ViaVersion Configuration
203
190
  # Auto-generated by mc-headless
204
191
 
205
- # Allow older clients to connect
206
192
  enable-client-side-block-updates: true
207
193
  prevent-collision: true
208
194
  auto-team: true
209
195
  suppress-metadata-errors: false
210
196
  enable-legacy-server-ping: true
211
197
  block-connection-method: true
212
-
213
- # Protocol support
214
198
  nms-player-ticking: true
215
199
  debug: false
216
200
  max-pps: 800
217
201
  max-pp-interval: 4
218
-
219
- # Version-specific fixes
220
202
  fix-self-rendering: true
221
203
  fix-low-level-collision: true
222
204
  shield-blocking: true
223
205
  fix-infested-block-breaking: true
206
+ ignore-long-1_16-channel: true
207
+ force-json-transform: false
208
+ use-natives: true
224
209
  `;
225
210
 
226
211
  await FileUtils.writeFile(configFile, configContent);
@@ -1,38 +1,103 @@
1
1
  #!/bin/bash
2
2
 
3
- echo "Installing Java for Minecraft Server..."
3
+ echo "Minecraft Headless - Java Auto Installer"
4
4
 
5
- if [ -f /etc/os-release ]; then
6
- . /etc/os-release
7
- OS=$ID
8
- elif [ -n "$TERMUX_VERSION" ]; then
9
- OS="termux"
5
+ JAVA_VERSION=${1:-17}
6
+ echo "Target Java version: $JAVA_VERSION"
7
+
8
+ detect_os() {
9
+ if [ -f /etc/os-release ]; then
10
+ . /etc/os-release
11
+ echo "$ID"
12
+ elif [ -n "$TERMUX_VERSION" ]; then
13
+ echo "termux"
14
+ elif [ "$(uname)" == "Darwin" ]; then
15
+ echo "macos"
16
+ elif [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then
17
+ echo "windows"
18
+ else
19
+ echo "unknown"
20
+ fi
21
+ }
22
+
23
+ OS=$(detect_os)
24
+ echo "Detected OS: $OS"
25
+
26
+ install_java_17() {
27
+ case $OS in
28
+ ubuntu|debian)
29
+ apt update
30
+ apt install -y openjdk-17-jre-headless
31
+ ;;
32
+ centos|rhel|fedora)
33
+ if command -v dnf &> /dev/null; then
34
+ dnf install -y java-17-openjdk-headless
35
+ else
36
+ yum install -y java-17-openjdk-headless
37
+ fi
38
+ ;;
39
+ arch)
40
+ pacman -S --noconfirm jre17-openjdk-headless
41
+ ;;
42
+ termux)
43
+ pkg install -y openjdk-17
44
+ ;;
45
+ macos)
46
+ if ! command -v brew &> /dev/null; then
47
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
48
+ fi
49
+ brew install openjdk@17
50
+ ;;
51
+ *)
52
+ echo "Unsupported OS for Java 17 installation"
53
+ return 1
54
+ ;;
55
+ esac
56
+ }
57
+
58
+ install_java_21() {
59
+ case $OS in
60
+ ubuntu|debian)
61
+ apt update
62
+ apt install -y openjdk-21-jre-headless
63
+ ;;
64
+ centos|rhel|fedora)
65
+ if command -v dnf &> /dev/null; then
66
+ dnf install -y java-21-openjdk-headless
67
+ else
68
+ yum install -y java-21-openjdk-headless
69
+ fi
70
+ ;;
71
+ arch)
72
+ pacman -S --noconfirm jre21-openjdk-headless
73
+ ;;
74
+ termux)
75
+ echo "Java 21 not available in Termux, installing Java 17 instead"
76
+ install_java_17
77
+ ;;
78
+ macos)
79
+ if ! command -v brew &> /dev/null; then
80
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
81
+ fi
82
+ brew install openjdk@21
83
+ ;;
84
+ *)
85
+ echo "Unsupported OS for Java 21 installation"
86
+ return 1
87
+ ;;
88
+ esac
89
+ }
90
+
91
+ if [ "$JAVA_VERSION" = "21" ]; then
92
+ install_java_21
10
93
  else
11
- OS="unknown"
94
+ install_java_17
12
95
  fi
13
96
 
14
- case $OS in
15
- ubuntu|debian)
16
- apt update
17
- apt install -y openjdk-17-jre-headless
18
- ;;
19
- centos|rhel)
20
- yum install -y java-17-openjdk-headless
21
- ;;
22
- fedora)
23
- dnf install -y java-17-openjdk-headless
24
- ;;
25
- arch)
26
- pacman -S --noconfirm jre17-openjdk-headless
27
- ;;
28
- termux)
29
- pkg install -y openjdk-17
30
- ;;
31
- *)
32
- echo "Unsupported OS. Please install Java 17 manually."
33
- exit 1
34
- ;;
35
- esac
36
-
37
- echo "Java installation completed."
38
- java -version
97
+ if [ $? -eq 0 ]; then
98
+ echo "Java installation completed."
99
+ java -version
100
+ else
101
+ echo "Java installation failed."
102
+ exit 1
103
+ fi