@dimzxzzx07/mc-headless 2.2.2 → 2.2.3

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.
@@ -4,12 +4,11 @@ import { Logger } from '../utils/Logger';
4
4
  import * as path from 'path';
5
5
  import axios from 'axios';
6
6
  import * as fs from 'fs-extra';
7
+ import * as stream from 'stream';
8
+ import * as util from 'util';
7
9
 
8
- export interface ViaVersionInfo {
9
- version: string;
10
- downloadUrl: string;
11
- fileName: string;
12
- }
10
+ const pipeline = util.promisify(stream.pipeline);
11
+ const finished = util.promisify(stream.finished);
13
12
 
14
13
  export class ViaVersionManager {
15
14
  private logger = Logger.getInstance();
@@ -24,52 +23,38 @@ export class ViaVersionManager {
24
23
 
25
24
  this.logger.info('Setting up ViaVersion, ViaBackwards, ViaRewind...');
26
25
 
27
- await this.cleanupCorruptFiles(pluginsDir);
28
-
26
+ await this.cleanupRemappedFolders(pluginsDir);
29
27
  await this.downloadViaVersion(pluginsDir);
28
+
29
+ await new Promise(resolve => setTimeout(resolve, 1000));
30
+
30
31
  await this.downloadViaBackwards(pluginsDir);
31
32
  await this.downloadViaRewind(pluginsDir);
32
33
 
33
- await this.verifyAllPlugins(pluginsDir);
34
-
35
34
  this.logger.success('ViaVersion suite installed successfully');
36
- this.logger.info('Players from older versions can now connect to your server');
37
35
  }
38
36
 
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
- ];
45
-
46
- for (const file of files) {
47
- const filePath = path.join(pluginsDir, file.name);
48
-
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
- }
37
+ private async cleanupRemappedFolders(pluginsDir: string): Promise<void> {
38
+ try {
39
+ const files = await fs.readdir(pluginsDir);
40
+ for (const file of files) {
41
+ if (file.includes('.paper-remapped')) {
42
+ const remappedPath = path.join(pluginsDir, file);
43
+ const stat = await fs.stat(remappedPath);
44
+ if (stat.isDirectory()) {
45
+ await fs.remove(remappedPath);
63
46
  }
64
- } catch (error) {
65
- this.logger.warning(`Error checking ${file.name}, removing...`);
66
- await fs.remove(filePath);
67
47
  }
68
48
  }
49
+ } catch (error) {
69
50
  }
70
51
  }
71
52
 
72
53
  private async downloadFile(url: string, destPath: string, fileName: string): Promise<void> {
54
+ if (await FileUtils.fileExists(destPath)) {
55
+ await fs.remove(destPath);
56
+ }
57
+
73
58
  this.logger.info(`Downloading ${fileName}...`);
74
59
 
75
60
  try {
@@ -84,24 +69,16 @@ export class ViaVersionManager {
84
69
  });
85
70
 
86
71
  const writer = fs.createWriteStream(destPath);
87
- response.data.pipe(writer);
88
-
89
- await new Promise<void>((resolve, reject) => {
90
- writer.on('finish', () => resolve());
91
- writer.on('error', (err) => reject(err));
92
- });
72
+
73
+ await pipeline(response.data, writer);
74
+ await finished(writer);
93
75
 
94
76
  const stats = await fs.stat(destPath);
95
77
  if (stats.size < 100000) {
96
78
  throw new Error(`Downloaded file too small: ${stats.size} bytes`);
97
79
  }
98
80
 
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)`);
81
+ this.logger.success(`Downloaded ${fileName} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
105
82
 
106
83
  } catch (error) {
107
84
  this.logger.error(`Failed to download ${fileName}:`, error);
@@ -111,74 +88,19 @@ export class ViaVersionManager {
111
88
 
112
89
  private async downloadViaVersion(pluginsDir: string): Promise<void> {
113
90
  const destPath = path.join(pluginsDir, 'ViaVersion.jar');
114
-
115
- if (await FileUtils.fileExists(destPath)) {
116
- await fs.remove(destPath);
117
- }
118
-
119
91
  await this.downloadFile(this.VIAVERSION_URL, destPath, 'ViaVersion.jar');
120
92
  }
121
93
 
122
94
  private async downloadViaBackwards(pluginsDir: string): Promise<void> {
123
95
  const destPath = path.join(pluginsDir, 'ViaBackwards.jar');
124
-
125
- if (await FileUtils.fileExists(destPath)) {
126
- await fs.remove(destPath);
127
- }
128
-
129
96
  await this.downloadFile(this.VIABACKWARDS_URL, destPath, 'ViaBackwards.jar');
130
97
  }
131
98
 
132
99
  private async downloadViaRewind(pluginsDir: string): Promise<void> {
133
100
  const destPath = path.join(pluginsDir, 'ViaRewind.jar');
134
-
135
- if (await FileUtils.fileExists(destPath)) {
136
- await fs.remove(destPath);
137
- }
138
-
139
101
  await this.downloadFile(this.VIAREWIND_URL, destPath, 'ViaRewind.jar');
140
102
  }
141
103
 
142
- private async verifyAllPlugins(pluginsDir: string): Promise<void> {
143
- const files = ['ViaVersion.jar', 'ViaBackwards.jar', 'ViaRewind.jar'];
144
- let allValid = true;
145
-
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
- }
176
-
177
- if (!allValid) {
178
- throw new Error('Some ViaVersion plugins are corrupt or missing');
179
- }
180
- }
181
-
182
104
  public async configureViaVersion(config: MinecraftConfig): Promise<void> {
183
105
  const pluginsDir = config.folders.plugins;
184
106
  const viaConfigDir = path.join(pluginsDir, 'ViaVersion');
@@ -187,8 +109,6 @@ export class ViaVersionManager {
187
109
  const configFile = path.join(viaConfigDir, 'config.yml');
188
110
 
189
111
  const configContent = `# ViaVersion Configuration
190
- # Auto-generated by mc-headless
191
-
192
112
  enable-client-side-block-updates: true
193
113
  prevent-collision: true
194
114
  auto-team: true
@@ -209,6 +129,5 @@ use-natives: true
209
129
  `;
210
130
 
211
131
  await FileUtils.writeFile(configFile, configContent);
212
- this.logger.debug('ViaVersion configuration created');
213
132
  }
214
133
  }
@@ -88,4 +88,210 @@ export interface Player {
88
88
  ip: string;
89
89
  ping: number;
90
90
  connectedAt: Date;
91
+ }
92
+
93
+ export interface JavaInfo {
94
+ path: string;
95
+ version: string;
96
+ type: 'system' | 'portable';
97
+ }
98
+
99
+ export interface GeyserConfig {
100
+ bedrock: {
101
+ port: number;
102
+ address: string;
103
+ };
104
+ remote: {
105
+ address: string;
106
+ port: number;
107
+ authType: string;
108
+ };
109
+ floodgateKeyFile: string;
110
+ passthroughMotd: boolean;
111
+ passthroughPlayerCounts: boolean;
112
+ passthroughProtocolName: boolean;
113
+ }
114
+
115
+ export interface ViaVersionConfig {
116
+ enableClientSideBlockUpdates: boolean;
117
+ preventCollision: boolean;
118
+ autoTeam: boolean;
119
+ suppressMetadataErrors: boolean;
120
+ enableLegacyServerPing: boolean;
121
+ blockConnectionMethod: boolean;
122
+ nmsPlayerTicking: boolean;
123
+ debug: boolean;
124
+ maxPps: number;
125
+ maxPpInterval: number;
126
+ fixSelfRendering: boolean;
127
+ fixLowLevelCollision: boolean;
128
+ shieldBlocking: boolean;
129
+ fixInfestedBlockBreaking: boolean;
130
+ ignoreLong1_16Channel: boolean;
131
+ forceJsonTransform: boolean;
132
+ useNatives: boolean;
133
+ }
134
+
135
+ export interface SkinRestorerConfig {
136
+ enabled: boolean;
137
+ updateSkins: boolean;
138
+ allowDefaultSkins: boolean;
139
+ allowCustomSkins: boolean;
140
+ allowThirdParty: boolean;
141
+ skinCacheSize: number;
142
+ }
143
+
144
+ export interface PluginInfo {
145
+ name: string;
146
+ version: string;
147
+ enabled: boolean;
148
+ main: string;
149
+ authors: string[];
150
+ website?: string;
151
+ description?: string;
152
+ depends?: string[];
153
+ softDepends?: string[];
154
+ loadBefore?: string[];
155
+ }
156
+
157
+ export interface WorldInfo {
158
+ name: string;
159
+ size: number;
160
+ players: number;
161
+ loadedChunks: number;
162
+ entities: number;
163
+ tiles: number;
164
+ seed: string;
165
+ difficulty: Difficulty;
166
+ gamemode: Gamemode;
167
+ hardcore: boolean;
168
+ spawn: {
169
+ x: number;
170
+ y: number;
171
+ z: number;
172
+ };
173
+ }
174
+
175
+ export interface BackupOptions {
176
+ type: 'full' | 'world' | 'plugins' | 'config';
177
+ compression: 'none' | 'gzip' | 'zip';
178
+ includePlayerData: boolean;
179
+ maxBackups: number;
180
+ retentionDays: number;
181
+ }
182
+
183
+ export interface RamdiskConfig {
184
+ enabled: boolean;
185
+ world: boolean;
186
+ plugins: boolean;
187
+ addons: boolean;
188
+ backupInterval: number;
189
+ masterStorage: string;
190
+ size: string;
191
+ mountPoint: string;
192
+ }
193
+
194
+ export interface SymlinkConfig {
195
+ enabled: boolean;
196
+ masterPath: string;
197
+ worlds: boolean;
198
+ plugins: boolean;
199
+ addons: boolean;
200
+ mods: boolean;
201
+ }
202
+
203
+ export interface NetworkOptimizationConfig {
204
+ tcpFastOpen: boolean;
205
+ tcpNoDelay: boolean;
206
+ preferIPv4: boolean;
207
+ compressionThreshold: number;
208
+ bungeeMode: boolean;
209
+ proxyProtocol: boolean;
210
+ velocity?: {
211
+ enabled: boolean;
212
+ secret: string;
213
+ forwardingMode: 'legacy' | 'modern';
214
+ };
215
+ }
216
+
217
+ export interface MemoryMonitorConfig {
218
+ enabled: boolean;
219
+ threshold: number;
220
+ interval: number;
221
+ action: 'restart' | 'stop' | 'warn';
222
+ maxMemoryLeakRestarts: number;
223
+ gcOnWarning: boolean;
224
+ }
225
+
226
+ export interface OwnerConfig {
227
+ usernames: string[];
228
+ prefix: string;
229
+ enabled: boolean;
230
+ permissions: string[];
231
+ }
232
+
233
+ export interface PterodactylConfig {
234
+ autoDetect: boolean;
235
+ useSystemJava: boolean;
236
+ respectPortEnv: boolean;
237
+ respectMemoryEnv: boolean;
238
+ cleanupRemapped: boolean;
239
+ warnUdp: boolean;
240
+ }
241
+
242
+ export interface PluginManagerConfig {
243
+ autoUpdate: boolean;
244
+ verifyOnLoad: boolean;
245
+ cleanupCorrupt: boolean;
246
+ downloadDelay: number;
247
+ retryCount: number;
248
+ retryDelay: number;
249
+ }
250
+
251
+ export interface ViaVersionManagerConfig {
252
+ autoDownload: boolean;
253
+ autoUpdate: boolean;
254
+ configureAutomatically: boolean;
255
+ downloadDelay: number;
256
+ versions: {
257
+ viaversion: string;
258
+ viabackwards: string;
259
+ viarewind: string;
260
+ };
261
+ }
262
+
263
+ export interface SkinRestorerManagerConfig {
264
+ autoDownload: boolean;
265
+ autoUpdate: boolean;
266
+ configureAutomatically: boolean;
267
+ downloadUrl: string;
268
+ }
269
+
270
+ export interface MinecraftServerOptions extends Partial<MinecraftConfig> {
271
+ enableViaVersion?: boolean;
272
+ enableViaBackwards?: boolean;
273
+ enableViaRewind?: boolean;
274
+ enableSkinRestorer?: boolean;
275
+ enableProtocolSupport?: boolean;
276
+ enableProtocolLib?: boolean;
277
+ enableTCPShield?: boolean;
278
+ enableSpigotOptimizers?: boolean;
279
+ enableSpark?: boolean;
280
+ enableViewDistanceTweaks?: boolean;
281
+ enableFarmControl?: boolean;
282
+ enableEntityDetection?: boolean;
283
+ customJavaArgs?: string[];
284
+ javaVersion?: '17' | '21' | 'auto';
285
+ usePortableJava?: boolean;
286
+ memoryMonitor?: MemoryMonitorConfig;
287
+ autoInstallJava?: boolean;
288
+ networkOptimization?: NetworkOptimizationConfig;
289
+ owners?: string[];
290
+ ownerCommands?: OwnerConfig;
291
+ silentMode?: boolean;
292
+ statsInterval?: number;
293
+ cleanLogsInterval?: number;
294
+ optimizeForPterodactyl?: boolean;
295
+ ramdisk?: RamdiskConfig;
296
+ symlinkMaster?: string;
91
297
  }