HeadlessMC Dart

A Dart package that simplifies downloading and running HeadlessMC, allowing you to launch and manage Minecraft servers and clients headlessly.

Features

  • Download and manage HeadlessMC launcher
  • Launch Minecraft with various configurations
  • Support for different Minecraft versions and mod loaders
  • Process management and interaction
  • Environment variable management
  • Headless operation mode (without GUI)

Installation

Add this package to your pubspec.yaml:

dependencies:
  headlessmc_dart: ^0.0.1

Then run:

flutter pub get

Usage

Basic Launch Flow

The basic flow involves setting up a launcher with the proper configuration and then launching Minecraft:

import 'package:headlessmc_dart/headlessmc_dart.dart';

// Initialize the launcher with Java executable and HeadlessMC JAR path
final launcher = HeadlessMCLauncher(
  javaExecutablePath: 'java',
  headlessmcJarPath: '/path/to/headlessmc-launcher-wrapper.jar',
);

// Set up a working directory
launcher.setWorkingDirectory('/path/to/minecraft/directory');

// Configure launch options
final options = LauncherOptions(
  version: '1.20.4',  // Vanilla Minecraft version
  lwjgl: true,        // Enable headless mode
  noOutput: false,    // Show Minecraft output
  commands: true,     // Enable headlessmc-runtime
);

// Launch Minecraft with the configured options
Future<void> launchMinecraft() async {
  try {
    final process = await launcher.launch(options);
    
    // Listen to the output stream
    launcher.onOutput.listen((line) {
      print('Minecraft: $line');
    });
    
    // Wait for the process to exit
    final exitCode = await process.exitCode;
    print('Minecraft exited with code: $exitCode');
  } catch (e) {
    print('Failed to launch Minecraft: $e');
  }
}

Using Mod Loaders

You can launch Minecraft with different mod loaders like Forge or Fabric:

import 'package:headlessmc_dart/headlessmc_dart.dart';

// Create a specific Minecraft version with a mod loader
final forgeVersion = MinecraftVersion(
  baseVersion: '1.20.4',
  modLoader: 'forge',
);

// Convert to string format for launcher options
final versionString = '${forgeVersion.modLoader}:${forgeVersion.baseVersion}';

// Configure launch options with the forge version
final options = LauncherOptions(
  version: versionString,
  lwjgl: true,
  noOutput: false,
  commands: true,
);

// Launch Minecraft with Forge
await launcher.launch(options);

Downloading Libraries

You can use the library downloader to fetch HeadlessMC or other required files:

import 'package:headlessmc_dart/headlessmc_dart.dart';
import 'dart:io';

// Create a downloader for HeadlessMC JAR
final downloader = LibraryDownloader(
  url: 'https://github.com/MCRcortex/headlessmc/releases/download/3.0.0/headlessmc-launcher-wrapper-3.0.0.jar',
  destinationDirectory: '/path/to/download/directory',
  onProgress: (progress) {
    print('Downloaded: ${progress.downloadedBytes} / ${progress.totalBytes} bytes');
    print('Progress: ${progress.percentComplete}%');
  },
  onComplete: (file) {
    print('Download complete: ${file.path}');
  },
);

// Start the download
File downloadedFile = await downloader.download();

Interactive Commands

You can send commands to a running Minecraft instance:

import 'package:headlessmc_dart/headlessmc_dart.dart';

// After launching Minecraft, you can send commands
Future<void> sendMinecraftCommands() async {
  // Send a command to the Minecraft console
  await launcher.sendCommand('/help');
  
  // Wait for a specific output
  final successMessage = await launcher.waitForOutput(
    (line) => line.contains('Loaded'), 
    timeout: Duration(seconds: 30),
  );
  
  if (successMessage != null) {
    print('Server loaded successfully!');
    
    // Send more commands
    await launcher.sendCommand('/op username');
    await launcher.sendCommand('/gamemode creative username');
  }
}

Advanced Configuration with Java Options

You can customize Java options for better performance:

import 'package:headlessmc_dart/headlessmc_dart.dart';

// Configure Java options
launcher.javaOptions
  ..setMaxMemory('4G')            // Set maximum memory
  ..setMinMemory('1G')            // Set minimum memory
  ..addGCOption('-XX:+UseG1GC')   // Use G1 Garbage Collector
  ..addSystemProperty('java.net.preferIPv4Stack', 'true');

// Launch with custom Java options
await launcher.launch(options);

Environment Variables

You can set environment variables for the Minecraft process:

import 'package:headlessmc_dart/headlessmc_dart.dart';

// Set environment variables
launcher.environmentVariables
  ..set('MINECRAFT_OPTS', '-Dfml.queryResult=confirm')
  ..set('JAVA_HOME', '/path/to/java');

// Launch with environment variables
await launcher.launch(options);

License

This package is available under the MIT License.