@dimzxzzx07/mc-headless 1.7.0 → 1.9.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.
- package/README.md +317 -703
- package/dist/core/JavaChecker.d.ts +16 -3
- package/dist/core/JavaChecker.d.ts.map +1 -1
- package/dist/core/JavaChecker.js +179 -31
- package/dist/core/JavaChecker.js.map +1 -1
- package/dist/core/MinecraftServer.d.ts +61 -0
- package/dist/core/MinecraftServer.d.ts.map +1 -1
- package/dist/core/MinecraftServer.js +742 -60
- package/dist/core/MinecraftServer.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -16
- package/dist/index.js.map +1 -1
- package/dist/platforms/BedrockServer.d.ts.map +1 -1
- package/dist/platforms/BedrockServer.js +2 -0
- package/dist/platforms/BedrockServer.js.map +1 -1
- package/dist/platforms/JavaServer.d.ts.map +1 -1
- package/dist/platforms/JavaServer.js +2 -0
- package/dist/platforms/JavaServer.js.map +1 -1
- package/dist/platforms/SkinRestorer.d.ts +14 -0
- package/dist/platforms/SkinRestorer.d.ts.map +1 -0
- package/dist/platforms/SkinRestorer.js +145 -0
- package/dist/platforms/SkinRestorer.js.map +1 -0
- package/dist/platforms/SkinsRestorer.d.ts +14 -0
- package/dist/platforms/SkinsRestorer.d.ts.map +1 -0
- package/dist/platforms/SkinsRestorer.js +145 -0
- package/dist/platforms/SkinsRestorer.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/JavaChecker.ts +170 -34
- package/src/core/MinecraftServer.ts +854 -64
- package/src/index.ts +33 -17
- package/src/platforms/BedrockServer.ts +2 -0
- package/src/platforms/JavaServer.ts +2 -0
- package/src/platforms/SkinRestorer.ts +127 -0
- package/src/scripts/install-java.sh +97 -32
- package/src/types/index.ts +2 -0
package/src/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
import { MinecraftServer } from './core/MinecraftServer';
|
|
2
4
|
import { Logger, LogLevel } from './utils/Logger';
|
|
3
5
|
import { SystemDetector } from './utils/SystemDetector';
|
|
6
|
+
import { JavaChecker } from './core/JavaChecker';
|
|
4
7
|
|
|
5
8
|
export * from './core/MinecraftServer';
|
|
6
9
|
export * from './core/ConfigHandler';
|
|
@@ -9,6 +12,8 @@ export * from './core/ServerManager';
|
|
|
9
12
|
export * from './platforms/JavaServer';
|
|
10
13
|
export * from './platforms/BedrockServer';
|
|
11
14
|
export * from './platforms/GeyserBridge';
|
|
15
|
+
export * from './platforms/ViaVersion';
|
|
16
|
+
export * from './platforms/SkinRestorer';
|
|
12
17
|
export * from './engines/Downloader';
|
|
13
18
|
export * from './engines/PaperEngine';
|
|
14
19
|
export * from './engines/VanillaEngine';
|
|
@@ -29,40 +34,49 @@ if (require.main === module) {
|
|
|
29
34
|
const systemInfo = SystemDetector.getSystemInfo();
|
|
30
35
|
logger.info('System Information:', systemInfo);
|
|
31
36
|
|
|
37
|
+
JavaChecker.cleanupOldJava();
|
|
38
|
+
|
|
32
39
|
const server = new MinecraftServer({
|
|
33
40
|
platform: 'java',
|
|
34
|
-
version: '1.
|
|
41
|
+
version: '1.21.11',
|
|
35
42
|
type: 'paper',
|
|
43
|
+
usePortableJava: true,
|
|
36
44
|
memory: {
|
|
37
|
-
init: '
|
|
38
|
-
max: '
|
|
45
|
+
init: '2G',
|
|
46
|
+
max: '4G',
|
|
39
47
|
useAikarsFlags: true
|
|
40
48
|
},
|
|
41
49
|
world: {
|
|
42
50
|
difficulty: 'normal',
|
|
43
51
|
hardcore: false,
|
|
44
52
|
gamemode: 'survival',
|
|
45
|
-
maxPlayers:
|
|
46
|
-
viewDistance:
|
|
53
|
+
maxPlayers: 20,
|
|
54
|
+
viewDistance: 6,
|
|
47
55
|
levelName: 'world'
|
|
48
|
-
}
|
|
56
|
+
},
|
|
57
|
+
enableViaVersion: true,
|
|
58
|
+
enableViaBackwards: true,
|
|
59
|
+
enableViaRewind: true,
|
|
60
|
+
enableSkinRestorer: true,
|
|
61
|
+
silentMode: true,
|
|
62
|
+
statsInterval: 30000
|
|
49
63
|
});
|
|
50
64
|
|
|
51
65
|
server.on('ready', (info) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
console.log(`
|
|
67
|
+
Minecraft Headless - Powered By Dimzxzzx07
|
|
68
|
+
IP: ${info.ip}:${info.port}
|
|
69
|
+
Version: ${info.version}
|
|
70
|
+
Players: ${info.players}/${info.maxPlayers}
|
|
71
|
+
Memory: ${info.memory.used}/${info.memory.max} MB
|
|
72
|
+
CPU: ${info.cpu}%
|
|
57
73
|
`);
|
|
58
74
|
});
|
|
59
75
|
|
|
60
|
-
server.on('
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
server.on('player-leave', (name) => {
|
|
65
|
-
logger.info(`Player left: ${name}`);
|
|
76
|
+
server.on('resource', (info) => {
|
|
77
|
+
if (info.memory.used > info.memory.max * 0.8) {
|
|
78
|
+
logger.warning(`High memory usage: ${info.memory.used}/${info.memory.max} MB (${info.cpu}% CPU)`);
|
|
79
|
+
}
|
|
66
80
|
});
|
|
67
81
|
|
|
68
82
|
server.start().catch(error => {
|
|
@@ -72,12 +86,14 @@ Mc Headless - Powered By Dimzxzzx07
|
|
|
72
86
|
process.on('SIGINT', async () => {
|
|
73
87
|
logger.info('Received SIGINT, stopping server...');
|
|
74
88
|
await server.stop();
|
|
89
|
+
JavaChecker.cleanupOldJava();
|
|
75
90
|
process.exit(0);
|
|
76
91
|
});
|
|
77
92
|
|
|
78
93
|
process.on('SIGTERM', async () => {
|
|
79
94
|
logger.info('Received SIGTERM, stopping server...');
|
|
80
95
|
await server.stop();
|
|
96
|
+
JavaChecker.cleanupOldJava();
|
|
81
97
|
process.exit(0);
|
|
82
98
|
});
|
|
83
99
|
}
|
|
@@ -39,6 +39,7 @@ export class BedrockServer extends EventEmitter {
|
|
|
39
39
|
maxPlayers: this.config.world.maxPlayers,
|
|
40
40
|
uptime: 0,
|
|
41
41
|
memory: { used: 0, max: 0 },
|
|
42
|
+
cpu: 0,
|
|
42
43
|
status: 'stopped'
|
|
43
44
|
};
|
|
44
45
|
}
|
|
@@ -258,6 +259,7 @@ export class BedrockServer extends EventEmitter {
|
|
|
258
259
|
used: Math.round(stats.memory / 1024 / 1024),
|
|
259
260
|
max: 0
|
|
260
261
|
};
|
|
262
|
+
this.serverInfo.cpu = Math.round(stats.cpu);
|
|
261
263
|
this.serverInfo.uptime = Math.floor((Date.now() - (this.startTime?.getTime() || 0)) / 1000);
|
|
262
264
|
|
|
263
265
|
this.emit('resource', this.serverInfo);
|
|
@@ -41,6 +41,7 @@ export class JavaServer extends EventEmitter {
|
|
|
41
41
|
maxPlayers: this.config.world.maxPlayers,
|
|
42
42
|
uptime: 0,
|
|
43
43
|
memory: { used: 0, max: 0 },
|
|
44
|
+
cpu: 0,
|
|
44
45
|
status: 'stopped'
|
|
45
46
|
};
|
|
46
47
|
}
|
|
@@ -176,6 +177,7 @@ export class JavaServer extends EventEmitter {
|
|
|
176
177
|
used: Math.round(stats.memory / 1024 / 1024),
|
|
177
178
|
max: this.parseMemory(this.config.memory.max)
|
|
178
179
|
};
|
|
180
|
+
this.serverInfo.cpu = Math.round(stats.cpu);
|
|
179
181
|
this.serverInfo.uptime = Math.floor((Date.now() - (this.startTime?.getTime() || 0)) / 1000);
|
|
180
182
|
|
|
181
183
|
if (stats.cpu > 80) {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { MinecraftConfig } from '../types';
|
|
2
|
+
import { FileUtils } from '../utils/FileUtils';
|
|
3
|
+
import { Logger } from '../utils/Logger';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import * as fs from 'fs-extra';
|
|
7
|
+
|
|
8
|
+
export interface SkinRestorerInfo {
|
|
9
|
+
version: string;
|
|
10
|
+
downloadUrl: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class SkinRestorerManager {
|
|
14
|
+
private logger = Logger.getInstance();
|
|
15
|
+
private readonly SKINRESTORER_URL = 'https://github.com/SkinsRestorer/SkinsRestorerX/releases/latest/download/SkinsRestorer.jar';
|
|
16
|
+
|
|
17
|
+
public async setup(config: MinecraftConfig): Promise<void> {
|
|
18
|
+
const pluginsDir = config.folders.plugins;
|
|
19
|
+
await FileUtils.ensureDir(pluginsDir);
|
|
20
|
+
|
|
21
|
+
this.logger.info('Setting up SkinRestorer...');
|
|
22
|
+
|
|
23
|
+
await this.cleanupCorruptFiles(pluginsDir);
|
|
24
|
+
await this.downloadSkinRestorer(pluginsDir);
|
|
25
|
+
await this.verifyPlugin(pluginsDir);
|
|
26
|
+
|
|
27
|
+
this.logger.success('SkinRestorer installed successfully');
|
|
28
|
+
this.logger.info('Player skins will now be restored automatically');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private async cleanupCorruptFiles(pluginsDir: string): Promise<void> {
|
|
32
|
+
const filePath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
33
|
+
|
|
34
|
+
if (await FileUtils.fileExists(filePath)) {
|
|
35
|
+
try {
|
|
36
|
+
const stats = await fs.stat(filePath);
|
|
37
|
+
if (stats.size < 100000) {
|
|
38
|
+
this.logger.warning('Corrupt SkinRestorer detected, removing...');
|
|
39
|
+
await fs.remove(filePath);
|
|
40
|
+
} else {
|
|
41
|
+
const buffer = await fs.readFile(filePath);
|
|
42
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
43
|
+
this.logger.warning('Invalid ZIP header in SkinRestorer, removing...');
|
|
44
|
+
await fs.remove(filePath);
|
|
45
|
+
} else {
|
|
46
|
+
this.logger.info('SkinRestorer is valid, keeping it');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
this.logger.warning('Error checking SkinRestorer, removing...');
|
|
51
|
+
await fs.remove(filePath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async downloadSkinRestorer(pluginsDir: string): Promise<void> {
|
|
57
|
+
const destPath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
58
|
+
|
|
59
|
+
if (await FileUtils.fileExists(destPath)) {
|
|
60
|
+
this.logger.info('SkinRestorer already exists, skipping download');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.logger.info('Downloading SkinRestorer...');
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const response = await axios({
|
|
68
|
+
method: 'GET',
|
|
69
|
+
url: this.SKINRESTORER_URL,
|
|
70
|
+
responseType: 'stream',
|
|
71
|
+
timeout: 60000,
|
|
72
|
+
headers: {
|
|
73
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const writer = fs.createWriteStream(destPath);
|
|
78
|
+
response.data.pipe(writer);
|
|
79
|
+
|
|
80
|
+
await new Promise<void>((resolve, reject) => {
|
|
81
|
+
writer.on('finish', () => resolve());
|
|
82
|
+
writer.on('error', (err) => reject(err));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const stats = await fs.stat(destPath);
|
|
86
|
+
if (stats.size < 100000) {
|
|
87
|
+
throw new Error(`Downloaded file too small: ${stats.size} bytes`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const buffer = await fs.readFile(destPath);
|
|
91
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
92
|
+
throw new Error('Invalid ZIP header');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.logger.success(`Downloaded SkinRestorer (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
|
|
96
|
+
|
|
97
|
+
} catch (error) {
|
|
98
|
+
this.logger.error('Failed to download SkinRestorer:', error);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private async verifyPlugin(pluginsDir: string): Promise<void> {
|
|
104
|
+
const filePath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
105
|
+
|
|
106
|
+
if (!await FileUtils.fileExists(filePath)) {
|
|
107
|
+
throw new Error('SkinRestorer plugin is missing');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
const stats = await fs.stat(filePath);
|
|
112
|
+
if (stats.size < 100000) {
|
|
113
|
+
throw new Error('SkinRestorer plugin is too small');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const buffer = await fs.readFile(filePath);
|
|
117
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
118
|
+
throw new Error('SkinRestorer plugin has invalid ZIP header');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.logger.debug(`SkinRestorer verified OK (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
this.logger.error('Failed to verify SkinRestorer:', error);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -1,38 +1,103 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
echo "
|
|
3
|
+
echo "Minecraft Headless - Java Auto Installer"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
94
|
+
install_java_17
|
|
12
95
|
fi
|
|
13
96
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
package/src/types/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface MinecraftConfig {
|
|
|
30
30
|
seed?: string;
|
|
31
31
|
maxPlayers: number;
|
|
32
32
|
viewDistance: number;
|
|
33
|
+
simulationDistance?: number;
|
|
33
34
|
levelName: string;
|
|
34
35
|
};
|
|
35
36
|
|
|
@@ -63,6 +64,7 @@ export interface ServerInfo {
|
|
|
63
64
|
used: number;
|
|
64
65
|
max: number;
|
|
65
66
|
};
|
|
67
|
+
cpu: number;
|
|
66
68
|
status: 'starting' | 'running' | 'stopping' | 'stopped' | 'crashed';
|
|
67
69
|
}
|
|
68
70
|
|