Git Product home page Git Product logo

jmclaunchlib's Introduction

jMCLaunchLib

A library to make Minecraft launcher development with JVM languages easier by providing a library to do the hard work: actually authenticating and launching Minecraft.

Launching and downloading is done asynchronously, taking just 2s fully cached. The library can launch Minecraft without an internet connection just from the data in .minecraft.

Although this library is written in Groovy, Java support IS a priority for me, some Java-based launchers are already using it.

If you require help and support see me in the #RX14 channel on EsperNet. Do not hesitate to report bugs and feature requests in the Github Issues. Even if you decide not to use this library, please drop a note as to how I can improve.

How do I get it?

The library is available on the jCenter Maven repository.

Using Gradle:

repositories {
    jcenter()
}

dependencies {
    compile "uk.co.rx14.jmclaunchlib:jMCLaunchLib:$version"
}

Usage

First step in launching Minecraft is to get a LaunchTask. This Task object will spawn several other Task objects which run in parallel (10 thread threadpool) to launch Minecraft.

LaunchTask task = new LaunchTaskBuilder()
		.setCachesDir("test/caches") //Directory to cache stuff in, copies caches from .minecraft (and verifies)
		
		.setMinecraftVersion("1.7.10") //Set vanilla version
		//OR
		.setForgeVersion("1.7.10", "1.7.10-10.13.3.1408-1.7.10") //Minecraftforge version
		
		.setInstanceDir("test/instance") //Minecraft directory
		
		.setUsername("RX14") //Username for offline
		.setOffline() //Offline mode
		//OR
		.setUsername("example@email") //Mojang username
		.setPasswordSupplier(new YourPasswordSupplier()) //Callback to request password. Details below.
		
		.build(); //Build LaunchTask

This should be mostly self-explanitory apart from the requirement for a PasswordSupplier. PasswordSupplier is an interface with one method, String getPassword(String username). This is required because jMCLaunchLib stores authentication tokens but does not store passwords, using this interface as a callback to request the password for a specific username enables the launcher to only ask the user for a password when absolutely needed. This will typically be called when the token has expired or when logging in for the first time.

Now you have your LaunchTask, what can you do with it? Now is the time to send the launch task back to your GUI thread, so that your progress dialog can call task.getCompletedPercentage(). After that, call task.getSpec() which calculates the LaunchSpec object which contains the java arguments required to launch Minecraft.

//Open a dialog box to report the percentage with
task.getCompletedPercentage()

LaunchSpec spec = task.getSpec()

You should be able to reuse the LaunchTaskBuilder, it is immutable and each stage copies the object. You should keep a partially constructed LaunchTaskBuilder and reuse it many times. You cannot reuse Task objects.

LaunchSpec is a class which contains the information you need to launch Minecraft: classpath, program arguments for minecraft, JVM arguments and the main class. You can use getLaunchArgs().add(...) and getJvmArgs().add(...) to customise the launch parameters. Use LaunchSpec.getJavaCommandline() to get the arguments to pass to the Java executable as a String, or use LaunchSpec.run(java.nio.file.Path javaExecutable) to let jMCLaunchLib run Minecraft using the path to the java executable. The run() method returns a standard Java Process object so you can control Minecraft and route it's standard output streams. Please note that the instance directory must exist before calling run, or it will fail with a slightly cryptic error 267.

(If you pester me enough I might write something cool to redirect stdout/err from a Process to useful places.)

Below is an example of using the LaunchSpec class to run minecraft, using the current java executable. If you are creating a launcher, I strongly suggest you make the java executable path configurable, with a sensible default.

spec.run(Paths.get(System.getProperty("java.home"), "bin", OS.getCURRENT() == OS.WINDOWS ? "java.exe" : "java"));

Customisation

  • You can make your own custom Version interface, for example for liteloader + forge, and use it in the LaunchtaskBuilder.
  • Make an issue if you want to do something this library does not allow.

jmclaunchlib's People

Contributors

rx14 avatar shadowfacts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

vseryi

jmclaunchlib's Issues

Fix readme

  • refer to jMCLaunchLib instead of "my library"
  • can use tasks independently
  • internal details
  • other shit

IOException when caches directory is not Present

Jul 15, 2015 7:08:03 PM uk.co.rx14.jmclaunchlib.util.Minecraft <clinit>
INFO: Detected minecraft directory: /Volumes/OSX Data/Users/anil/Library/Application Support/minecraft
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8390)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$284/202101492.get(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:927)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1767)
    ... 54 more
Caused by: java.io.IOException: No such file or directory
    at java.io.UnixFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at uk.co.rx14.jmclaunchlib.caches.MinecraftCaches.copyFromMinecraftDirectory(MinecraftCaches.groovy:68)
    at uk.co.rx14.jmclaunchlib.caches.MinecraftCaches.create(MinecraftCaches.groovy:36)
    at uk.co.rx14.jmclaunchlib.MCInstance.createForge(MCInstance.groovy:50)
    at uk.co.rx14.jmclaunchlib.MCInstance.createForge(MCInstance.groovy:70)
    at temporalreality.launcher.util.ModpackUtils.launch(ModpackUtils.java:186)
    at temporalreality.launcher.view.overview.ModpackOverviewController.launchPressed(ModpackOverviewController.java:104)
    ... 64 more

Minecraft not starting in online mode

Im currently working on a costum minecraft launcher for a private server, and to start Minecraft im trying to use this library. Im using version 0.4.1. When im trying to start Minecraft in offline mode (.setOffline() & .setNetOffline()), it starts just fine. But when trying to start Minecraft in online Mode, it doesn't start. It also doesnt throw any errors, it just doesn't do anything at a certain point.
The last thing that gets printed is
Jan 14, 2017 12:30:35 PM uk.co.rx14.jmclaunchlib.caches.EtagCache selectMethod INFORMATION: Downloading https://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.json Jan 14, 2017 12:30:35 PM uk.co.rx14.jmclaunchlib.caches.EtagCache get INFORMATION: Downloading https://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.json Jan 14, 2017 12:30:43 PM uk.co.rx14.jmclaunchlib.caches.EtagCache get INFORMATION: Downloading https://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.jar

Even after waiting up to 30 minutes, nothing happens anymore.

Also, sometimes when trying it throws a NullPointerException.
pastebin log with NullPointerException
pastebin log

The start class im using:
Java start class

Is there a mistake in my Code or is the library not working anymore?

Offline mode

We can launch in offline mode but launch fails when we are actually offline.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.