Merge branch 'feature_better_launch' into develop
This commit is contained in:
commit
b589a12d17
6
depends/javacheck/.gitignore
vendored
Normal file
6
depends/javacheck/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
out
|
||||||
|
.classpath
|
||||||
|
.idea
|
||||||
|
.project
|
6
depends/launcher/.gitignore
vendored
Normal file
6
depends/launcher/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
out
|
||||||
|
.classpath
|
||||||
|
.idea
|
||||||
|
.project
|
@ -3,20 +3,33 @@ project(launcher Java)
|
|||||||
find_package(Java 1.6 REQUIRED COMPONENTS Development)
|
find_package(Java 1.6 REQUIRED COMPONENTS Development)
|
||||||
|
|
||||||
include(UseJava)
|
include(UseJava)
|
||||||
set(CMAKE_JAVA_JAR_ENTRY_POINT MultiMCLauncher)
|
set(CMAKE_JAVA_JAR_ENTRY_POINT org.multimc.EntryPoint)
|
||||||
set(CMAKE_JAVA_COMPILE_FLAGS -target 1.6 -source 1.6 -Xlint:deprecation -Xlint:unchecked)
|
set(CMAKE_JAVA_COMPILE_FLAGS -target 1.6 -source 1.6 -Xlint:deprecation -Xlint:unchecked)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
MultiMCLauncher.java
|
# OSX things
|
||||||
org/simplericity/macify/eawt/Application.java
|
org/simplericity/macify/eawt/Application.java
|
||||||
org/simplericity/macify/eawt/ApplicationAdapter.java
|
org/simplericity/macify/eawt/ApplicationAdapter.java
|
||||||
org/simplericity/macify/eawt/ApplicationEvent.java
|
org/simplericity/macify/eawt/ApplicationEvent.java
|
||||||
org/simplericity/macify/eawt/ApplicationListener.java
|
org/simplericity/macify/eawt/ApplicationListener.java
|
||||||
org/simplericity/macify/eawt/DefaultApplication.java
|
org/simplericity/macify/eawt/DefaultApplication.java
|
||||||
|
|
||||||
|
# legacy applet wrapper thing.
|
||||||
|
# The launcher has to be there for silly FML/Forge relauncher.
|
||||||
net/minecraft/Launcher.java
|
net/minecraft/Launcher.java
|
||||||
MCFrame.java
|
org/multimc/legacy/LegacyLauncher.java
|
||||||
|
org/multimc/legacy/LegacyFrame.java
|
||||||
|
|
||||||
|
# onesix launcher
|
||||||
|
org/multimc/onesix/OneSixLauncher.java
|
||||||
|
|
||||||
|
# generic launcher
|
||||||
|
org/multimc/EntryPoint.java
|
||||||
|
org/multimc/Launcher.java
|
||||||
|
org/multimc/ParseException.java
|
||||||
|
org/multimc/Utils.java
|
||||||
|
org/multimc/IconLoader.java
|
||||||
)
|
)
|
||||||
|
add_jar(NewLaunch ${SRC})
|
||||||
|
|
||||||
add_jar(MultiMCLauncher ${SRC})
|
INSTALL_JAR(NewLaunch "${BINARY_DEST_DIR}/jars")
|
||||||
|
|
||||||
INSTALL_JAR(MultiMCLauncher "${BINARY_DEST_DIR}/jars")
|
|
||||||
|
@ -1,331 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2012 MultiMC Contributors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import java.applet.Applet;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipException;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import org.simplericity.macify.eawt.Application;
|
|
||||||
import org.simplericity.macify.eawt.DefaultApplication;
|
|
||||||
|
|
||||||
public class MultiMCLauncher
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param args
|
|
||||||
* The arguments you want to launch Minecraft with. New path,
|
|
||||||
* Username, Session ID.
|
|
||||||
*/
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
if (args.length < 3)
|
|
||||||
{
|
|
||||||
System.out.println("Not enough arguments.");
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the OSX application icon first, if we are on OSX.
|
|
||||||
Application application = new DefaultApplication();
|
|
||||||
if(application.isMac())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
BufferedImage image = ImageIO.read(new File("icon.png"));
|
|
||||||
application.setApplicationIconImage(image);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String userName = args[0];
|
|
||||||
String sessionId = args[1];
|
|
||||||
String windowtitle = args[2];
|
|
||||||
String windowParams = args[3];
|
|
||||||
String lwjgl = args[4];
|
|
||||||
String cwd = System.getProperty("user.dir");
|
|
||||||
|
|
||||||
Dimension winSize = new Dimension(854, 480);
|
|
||||||
boolean maximize = false;
|
|
||||||
boolean compatMode = false;
|
|
||||||
|
|
||||||
|
|
||||||
String[] dimStrings = windowParams.split("x");
|
|
||||||
|
|
||||||
if (windowParams.equalsIgnoreCase("compatmode"))
|
|
||||||
{
|
|
||||||
compatMode = true;
|
|
||||||
}
|
|
||||||
else if (windowParams.equalsIgnoreCase("max"))
|
|
||||||
{
|
|
||||||
maximize = true;
|
|
||||||
}
|
|
||||||
else if (dimStrings.length == 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
winSize = new Dimension(Integer.parseInt(dimStrings[0]),
|
|
||||||
Integer.parseInt(dimStrings[1]));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
System.out.println("Invalid Window size argument, " +
|
|
||||||
"using default.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println("Invalid Window size argument, " +
|
|
||||||
"using default.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File binDir = new File(cwd, "bin");
|
|
||||||
File lwjglDir;
|
|
||||||
if(lwjgl.equalsIgnoreCase("Mojang"))
|
|
||||||
lwjglDir = binDir;
|
|
||||||
else
|
|
||||||
lwjglDir = new File(lwjgl);
|
|
||||||
|
|
||||||
System.out.println("Loading jars...");
|
|
||||||
String[] lwjglJars = new String[] {
|
|
||||||
"lwjgl.jar", "lwjgl_util.jar", "jinput.jar"
|
|
||||||
};
|
|
||||||
|
|
||||||
URL[] urls = new URL[4];
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File f = new File(binDir, "minecraft.jar");
|
|
||||||
urls[0] = f.toURI().toURL();
|
|
||||||
System.out.println("Loading URL: " + urls[0].toString());
|
|
||||||
|
|
||||||
for (int i = 1; i < urls.length; i++)
|
|
||||||
{
|
|
||||||
File jar = new File(lwjglDir, lwjglJars[i-1]);
|
|
||||||
urls[i] = jar.toURI().toURL();
|
|
||||||
System.out.println("Loading URL: " + urls[i].toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (MalformedURLException e)
|
|
||||||
{
|
|
||||||
System.err.println("MalformedURLException, " + e.toString());
|
|
||||||
System.exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Loading natives...");
|
|
||||||
String nativesDir = new File(lwjglDir, "natives").toString();
|
|
||||||
|
|
||||||
System.setProperty("org.lwjgl.librarypath", nativesDir);
|
|
||||||
System.setProperty("net.java.games.input.librarypath", nativesDir);
|
|
||||||
|
|
||||||
URLClassLoader cl =
|
|
||||||
new URLClassLoader(urls, MultiMCLauncher.class.getClassLoader());
|
|
||||||
|
|
||||||
// Get the Minecraft Class.
|
|
||||||
Class<?> mc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mc = cl.loadClass("net.minecraft.client.Minecraft");
|
|
||||||
|
|
||||||
Field f = getMCPathField(mc);
|
|
||||||
|
|
||||||
if (f == null)
|
|
||||||
{
|
|
||||||
System.err.println("Could not find Minecraft path field. Launch failed.");
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
f.setAccessible(true);
|
|
||||||
f.set(null, new File(cwd));
|
|
||||||
// And set it.
|
|
||||||
System.out.println("Fixed Minecraft Path: Field was " + f.toString());
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
System.err.println("Can't find main class. Searching...");
|
|
||||||
|
|
||||||
// Look for any class that looks like the main class.
|
|
||||||
File mcJar = new File(new File(cwd, "bin"), "minecraft.jar");
|
|
||||||
ZipFile zip = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
zip = new ZipFile(mcJar);
|
|
||||||
} catch (ZipException e1)
|
|
||||||
{
|
|
||||||
e1.printStackTrace();
|
|
||||||
System.err.println("Search failed.");
|
|
||||||
System.exit(-1);
|
|
||||||
} catch (IOException e1)
|
|
||||||
{
|
|
||||||
e1.printStackTrace();
|
|
||||||
System.err.println("Search failed.");
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration<? extends ZipEntry> entries = zip.entries();
|
|
||||||
ArrayList<String> classes = new ArrayList<String>();
|
|
||||||
|
|
||||||
while (entries.hasMoreElements())
|
|
||||||
{
|
|
||||||
ZipEntry entry = entries.nextElement();
|
|
||||||
if (entry.getName().endsWith(".class"))
|
|
||||||
{
|
|
||||||
String entryName = entry.getName().substring(0, entry.getName().lastIndexOf('.'));
|
|
||||||
entryName = entryName.replace('/', '.');
|
|
||||||
System.out.println("Found class: " + entryName);
|
|
||||||
classes.add(entryName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String clsName : classes)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class<?> cls = cl.loadClass(clsName);
|
|
||||||
if (!Runnable.class.isAssignableFrom(cls))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println("Found class implementing runnable: " +
|
|
||||||
cls.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getMCPathField(cls) == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println("Found class implementing runnable " +
|
|
||||||
"with mcpath field: " + cls.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
mc = cls;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e1)
|
|
||||||
{
|
|
||||||
// Ignore
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mc == null)
|
|
||||||
{
|
|
||||||
System.err.println("Failed to find Minecraft main class.");
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println("Found main class: " + mc.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("minecraft.applet.TargetDirectory", cwd);
|
|
||||||
|
|
||||||
String[] mcArgs = new String[2];
|
|
||||||
mcArgs[0] = userName;
|
|
||||||
mcArgs[1] = sessionId;
|
|
||||||
|
|
||||||
if (compatMode)
|
|
||||||
{
|
|
||||||
System.out.println("Launching in compatibility mode...");
|
|
||||||
mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println("Launching with applet wrapper...");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class<?> MCAppletClass = cl.loadClass(
|
|
||||||
"net.minecraft.client.MinecraftApplet");
|
|
||||||
Applet mcappl = (Applet) MCAppletClass.newInstance();
|
|
||||||
MCFrame mcWindow = new MCFrame(windowtitle);
|
|
||||||
mcWindow.start(mcappl, userName, sessionId, winSize, maximize);
|
|
||||||
} catch (InstantiationException e)
|
|
||||||
{
|
|
||||||
System.out.println("Applet wrapper failed! Falling back " +
|
|
||||||
"to compatibility mode.");
|
|
||||||
mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(2);
|
|
||||||
} catch (IllegalAccessException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(2);
|
|
||||||
} catch (InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(3);
|
|
||||||
} catch (NoSuchMethodException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(3);
|
|
||||||
} catch (SecurityException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Field getMCPathField(Class<?> mc)
|
|
||||||
{
|
|
||||||
Field[] fields = mc.getDeclaredFields();
|
|
||||||
|
|
||||||
for (int i = 0; i < fields.length; i++)
|
|
||||||
{
|
|
||||||
Field f = fields[i];
|
|
||||||
if (f.getType() != File.class)
|
|
||||||
{
|
|
||||||
// Has to be File
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (f.getModifiers() != (Modifier.PRIVATE + Modifier.STATIC))
|
|
||||||
{
|
|
||||||
// And Private Static.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +1,18 @@
|
|||||||
//
|
/*
|
||||||
// Copyright 2012 MultiMC Contributors
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
//
|
*
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
//
|
*
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
*
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
* limitations under the License.
|
||||||
//
|
*/
|
||||||
|
|
||||||
package net.minecraft;
|
package net.minecraft;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ public class Launcher extends Applet implements AppletStub
|
|||||||
|
|
||||||
this.setLayout(new BorderLayout());
|
this.setLayout(new BorderLayout());
|
||||||
this.add(applet, "Center");
|
this.add(applet, "Center");
|
||||||
this.wrappedApplet = applet;
|
this.wrappedApplet = applet;
|
||||||
this.documentBase = documentBase;
|
this.documentBase = documentBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,17 +46,17 @@ public class Launcher extends Applet implements AppletStub
|
|||||||
{
|
{
|
||||||
params.put(name, value);
|
params.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replace(Applet applet)
|
public void replace(Applet applet)
|
||||||
{
|
{
|
||||||
this.wrappedApplet = applet;
|
this.wrappedApplet = applet;
|
||||||
|
|
||||||
applet.setStub(this);
|
applet.setStub(this);
|
||||||
applet.setSize(getWidth(), getHeight());
|
applet.setSize(getWidth(), getHeight());
|
||||||
|
|
||||||
this.setLayout(new BorderLayout());
|
this.setLayout(new BorderLayout());
|
||||||
this.add(applet, "Center");
|
this.add(applet, "Center");
|
||||||
|
|
||||||
applet.init();
|
applet.init();
|
||||||
active = true;
|
active = true;
|
||||||
applet.start();
|
applet.start();
|
||||||
@ -99,7 +99,7 @@ public class Launcher extends Applet implements AppletStub
|
|||||||
{
|
{
|
||||||
wrappedApplet.resize(d);
|
wrappedApplet.resize(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
@ -127,7 +127,7 @@ public class Launcher extends Applet implements AppletStub
|
|||||||
{
|
{
|
||||||
wrappedApplet.destroy();
|
wrappedApplet.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getCodeBase() {
|
public URL getCodeBase() {
|
||||||
return wrappedApplet.getCodeBase();
|
return wrappedApplet.getCodeBase();
|
||||||
|
135
depends/launcher/org/multimc/EntryPoint.java
Normal file
135
depends/launcher/org/multimc/EntryPoint.java
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package org.multimc;/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.multimc.legacy.LegacyLauncher;
|
||||||
|
import org.multimc.onesix.OneSixLauncher;
|
||||||
|
import org.simplericity.macify.eawt.Application;
|
||||||
|
import org.simplericity.macify.eawt.DefaultApplication;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class EntryPoint
|
||||||
|
{
|
||||||
|
private enum Action
|
||||||
|
{
|
||||||
|
Proceed,
|
||||||
|
Launch
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
// Set the OSX application icon first, if we are on OSX.
|
||||||
|
Application application = new DefaultApplication();
|
||||||
|
if(application.isMac())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BufferedImage image = ImageIO.read(new File("icon.png"));
|
||||||
|
application.setApplicationIconImage(image);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryPoint listener = new EntryPoint();
|
||||||
|
int retCode = listener.listen();
|
||||||
|
if (retCode != 0)
|
||||||
|
{
|
||||||
|
System.out.println("Exiting with " + retCode);
|
||||||
|
System.exit(retCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action parseLine(String inData) throws ParseException
|
||||||
|
{
|
||||||
|
String[] pair = inData.split(" ", 2);
|
||||||
|
if(pair.length != 2)
|
||||||
|
throw new ParseException();
|
||||||
|
|
||||||
|
String command = pair[0];
|
||||||
|
String param = pair[1];
|
||||||
|
|
||||||
|
if(command.equals("launch"))
|
||||||
|
{
|
||||||
|
if(param.equals("legacy"))
|
||||||
|
{
|
||||||
|
m_launcher = new LegacyLauncher();
|
||||||
|
System.out.println("Using legacy launcher.");
|
||||||
|
System.out.println();
|
||||||
|
return Action.Launch;
|
||||||
|
}
|
||||||
|
if(param.equals("onesix"))
|
||||||
|
{
|
||||||
|
m_launcher = new OneSixLauncher();
|
||||||
|
System.out.println("Using onesix launcher.");
|
||||||
|
System.out.println();
|
||||||
|
return Action.Launch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new ParseException();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_params.add(command, param);
|
||||||
|
//System.out.println(command + " : " + param);
|
||||||
|
return Action.Proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int listen()
|
||||||
|
{
|
||||||
|
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
|
||||||
|
boolean isListening = true;
|
||||||
|
// Main loop
|
||||||
|
while (isListening)
|
||||||
|
{
|
||||||
|
String inData="";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read from the pipe one line at a time
|
||||||
|
inData = buffer.readLine();
|
||||||
|
if (inData != null)
|
||||||
|
{
|
||||||
|
if(parseLine(inData) == Action.Launch)
|
||||||
|
{
|
||||||
|
isListening = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (ParseException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(m_launcher != null)
|
||||||
|
{
|
||||||
|
return m_launcher.launch(m_params);
|
||||||
|
}
|
||||||
|
System.err.println("No valid launcher implementation specified.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParamBucket m_params = new ParamBucket();
|
||||||
|
private org.multimc.Launcher m_launcher;
|
||||||
|
}
|
132
depends/launcher/org/multimc/IconLoader.java
Normal file
132
depends/launcher/org/multimc/IconLoader.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* A convenience class for loading icons from images.
|
||||||
|
*
|
||||||
|
* Icons loaded from this class are formatted to fit within the required
|
||||||
|
* dimension (16x16, 32x32, or 128x128). If the source image is larger than the
|
||||||
|
* target dimension, it is shrunk down to the minimum size that will fit. If it
|
||||||
|
* is smaller, then it is only scaled up if the new scale can be a per-pixel
|
||||||
|
* linear scale (i.e., x2, x3, x4, etc). In both cases, the image's width/height
|
||||||
|
* ratio is kept the same as the source image.
|
||||||
|
*
|
||||||
|
* @author Chris Molini
|
||||||
|
*****************************************************************************/
|
||||||
|
public class IconLoader
|
||||||
|
{
|
||||||
|
/*************************************************************************
|
||||||
|
* Loads an icon in ByteBuffer form.
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* The location of the Image to use as an icon.
|
||||||
|
*
|
||||||
|
* @return An array of ByteBuffers containing the pixel data for the icon in
|
||||||
|
* various sizes (as recommended by the OS).
|
||||||
|
*************************************************************************/
|
||||||
|
public static ByteBuffer[] load(String filepath)
|
||||||
|
{
|
||||||
|
BufferedImage image;
|
||||||
|
try {
|
||||||
|
image = ImageIO.read ( new File( filepath ) );
|
||||||
|
} catch ( IOException e ) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new ByteBuffer[0];
|
||||||
|
}
|
||||||
|
ByteBuffer[] buffers;
|
||||||
|
buffers = new ByteBuffer[1];
|
||||||
|
buffers[0] = loadInstance(image, 128);
|
||||||
|
return buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Copies the supplied image into a square icon at the indicated size.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to place onto the icon.
|
||||||
|
* @param dimension
|
||||||
|
* The desired size of the icon.
|
||||||
|
*
|
||||||
|
* @return A ByteBuffer of pixel data at the indicated size.
|
||||||
|
*************************************************************************/
|
||||||
|
private static ByteBuffer loadInstance(BufferedImage image, int dimension)
|
||||||
|
{
|
||||||
|
BufferedImage scaledIcon = new BufferedImage(dimension, dimension,
|
||||||
|
BufferedImage.TYPE_INT_ARGB_PRE);
|
||||||
|
Graphics2D g = scaledIcon.createGraphics();
|
||||||
|
double ratio = getIconRatio(image, scaledIcon);
|
||||||
|
double width = image.getWidth() * ratio;
|
||||||
|
double height = image.getHeight() * ratio;
|
||||||
|
g.drawImage(image, (int) ((scaledIcon.getWidth() - width) / 2),
|
||||||
|
(int) ((scaledIcon.getHeight() - height) / 2), (int) (width),
|
||||||
|
(int) (height), null);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
return convertToByteBuffer(scaledIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Gets the width/height ratio of the icon. This is meant to simplify
|
||||||
|
* scaling the icon to a new dimension.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* The base image that will be placed onto the icon.
|
||||||
|
* @param icon
|
||||||
|
* The icon that will have the image placed on it.
|
||||||
|
*
|
||||||
|
* @return The amount to scale the source image to fit it onto the icon
|
||||||
|
* appropriately.
|
||||||
|
*************************************************************************/
|
||||||
|
private static double getIconRatio(BufferedImage src, BufferedImage icon)
|
||||||
|
{
|
||||||
|
double ratio = 1;
|
||||||
|
if (src.getWidth() > icon.getWidth())
|
||||||
|
ratio = (double) (icon.getWidth()) / src.getWidth();
|
||||||
|
else
|
||||||
|
ratio = (int) (icon.getWidth() / src.getWidth());
|
||||||
|
if (src.getHeight() > icon.getHeight())
|
||||||
|
{
|
||||||
|
double r2 = (double) (icon.getHeight()) / src.getHeight();
|
||||||
|
if (r2 < ratio)
|
||||||
|
ratio = r2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double r2 = (int) (icon.getHeight() / src.getHeight());
|
||||||
|
if (r2 < ratio)
|
||||||
|
ratio = r2;
|
||||||
|
}
|
||||||
|
return ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Converts a BufferedImage into a ByteBuffer of pixel data.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to convert.
|
||||||
|
*
|
||||||
|
* @return A ByteBuffer that contains the pixel data of the supplied image.
|
||||||
|
*************************************************************************/
|
||||||
|
public static ByteBuffer convertToByteBuffer(BufferedImage image)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[image.getWidth() * image.getHeight() * 4];
|
||||||
|
int counter = 0;
|
||||||
|
for (int i = 0; i < image.getHeight(); i++)
|
||||||
|
for (int j = 0; j < image.getWidth(); j++)
|
||||||
|
{
|
||||||
|
int colorSpace = image.getRGB(j, i);
|
||||||
|
buffer[counter + 0] = (byte) ((colorSpace << 8) >> 24);
|
||||||
|
buffer[counter + 1] = (byte) ((colorSpace << 16) >> 24);
|
||||||
|
buffer[counter + 2] = (byte) ((colorSpace << 24) >> 24);
|
||||||
|
buffer[counter + 3] = (byte) (colorSpace >> 24);
|
||||||
|
counter += 4;
|
||||||
|
}
|
||||||
|
return ByteBuffer.wrap(buffer);
|
||||||
|
}
|
||||||
|
}
|
22
depends/launcher/org/multimc/Launcher.java
Normal file
22
depends/launcher/org/multimc/Launcher.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
public interface Launcher
|
||||||
|
{
|
||||||
|
abstract int launch(ParamBucket params);
|
||||||
|
}
|
21
depends/launcher/org/multimc/NotFoundException.java
Normal file
21
depends/launcher/org/multimc/NotFoundException.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
public class NotFoundException extends Exception
|
||||||
|
{
|
||||||
|
}
|
86
depends/launcher/org/multimc/ParamBucket.java
Normal file
86
depends/launcher/org/multimc/ParamBucket.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ParamBucket
|
||||||
|
{
|
||||||
|
public void add(String key, String value)
|
||||||
|
{
|
||||||
|
List<String> coll = null;
|
||||||
|
if(!m_params.containsKey(key))
|
||||||
|
{
|
||||||
|
coll = new ArrayList<String>();
|
||||||
|
m_params.put(key, coll);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coll = m_params.get(key);
|
||||||
|
}
|
||||||
|
coll.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> all(String key) throws NotFoundException
|
||||||
|
{
|
||||||
|
if(!m_params.containsKey(key))
|
||||||
|
throw new NotFoundException();
|
||||||
|
return m_params.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> allSafe(String key, List<String> def)
|
||||||
|
{
|
||||||
|
if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
|
||||||
|
{
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
return m_params.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> allSafe(String key)
|
||||||
|
{
|
||||||
|
return allSafe(key, new ArrayList<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String first(String key) throws NotFoundException
|
||||||
|
{
|
||||||
|
List<String> list = all(key);
|
||||||
|
if(list.size() < 1)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
return list.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String firstSafe(String key, String def)
|
||||||
|
{
|
||||||
|
if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
|
||||||
|
{
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
return m_params.get(key).get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String firstSafe(String key)
|
||||||
|
{
|
||||||
|
return firstSafe(key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, List<String>> m_params = new HashMap<String, List<String>>();
|
||||||
|
}
|
22
depends/launcher/org/multimc/ParseException.java
Normal file
22
depends/launcher/org/multimc/ParseException.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
public class ParseException extends java.lang.Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
125
depends/launcher/org/multimc/Utils.java
Normal file
125
depends/launcher/org/multimc/Utils.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Utils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Adds the specified library to the classpath
|
||||||
|
*
|
||||||
|
* @param s the path to add
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void addToClassPath(String s) throws Exception
|
||||||
|
{
|
||||||
|
File f = new File(s);
|
||||||
|
URL u = f.toURI().toURL();
|
||||||
|
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||||
|
Class urlClass = URLClassLoader.class;
|
||||||
|
Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class});
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(urlClassLoader, new Object[]{u});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds many libraries to the classpath
|
||||||
|
*
|
||||||
|
* @param jars the paths to add
|
||||||
|
*/
|
||||||
|
public static boolean addToClassPath(List<String> jars)
|
||||||
|
{
|
||||||
|
boolean pure = true;
|
||||||
|
// initialize the class path
|
||||||
|
for (String jar : jars)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Utils.addToClassPath(jar);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Unable to load: " + jar);
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
pure = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the specified path to the java library path
|
||||||
|
*
|
||||||
|
* @param pathToAdd the path to add
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Deprecated public static void addLibraryPath(String pathToAdd) throws Exception
|
||||||
|
{
|
||||||
|
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
|
||||||
|
usrPathsField.setAccessible(true);
|
||||||
|
|
||||||
|
//get array of paths
|
||||||
|
final String[] paths = (String[]) usrPathsField.get(null);
|
||||||
|
|
||||||
|
//check if the path to add is already present
|
||||||
|
for (String path : paths)
|
||||||
|
{
|
||||||
|
if (path.equals(pathToAdd))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add the new path
|
||||||
|
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
|
||||||
|
newPaths[newPaths.length - 1] = pathToAdd;
|
||||||
|
usrPathsField.set(null, newPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a field that looks like a Minecraft base folder in a supplied class
|
||||||
|
*
|
||||||
|
* @param mc the class to scan
|
||||||
|
*/
|
||||||
|
public static Field getMCPathField(Class<?> mc)
|
||||||
|
{
|
||||||
|
Field[] fields = mc.getDeclaredFields();
|
||||||
|
|
||||||
|
for (Field f : fields)
|
||||||
|
{
|
||||||
|
if (f.getType() != File.class)
|
||||||
|
{
|
||||||
|
// Has to be File
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (f.getModifiers() != (Modifier.PRIVATE + Modifier.STATIC))
|
||||||
|
{
|
||||||
|
// And Private Static.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +1,39 @@
|
|||||||
//
|
package org.multimc.legacy;/*
|
||||||
// Copyright 2012 MultiMC Contributors
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
//
|
*
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
//
|
*
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
*
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
* limitations under the License.
|
||||||
//
|
*/
|
||||||
|
|
||||||
import net.minecraft.Launcher;
|
import net.minecraft.Launcher;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.applet.Applet;
|
import java.applet.Applet;
|
||||||
import java.awt.Dimension;
|
import java.awt.*;
|
||||||
import java.awt.Frame;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.awt.event.WindowListener;
|
import java.awt.event.WindowListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.File;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
public class MCFrame extends Frame implements WindowListener
|
public class LegacyFrame extends Frame implements WindowListener
|
||||||
{
|
{
|
||||||
private Launcher appletWrap = null;
|
private Launcher appletWrap = null;
|
||||||
public MCFrame ( String title )
|
public LegacyFrame(String title)
|
||||||
{
|
{
|
||||||
super ( title );
|
super ( title );
|
||||||
BufferedImage image = null;
|
BufferedImage image;
|
||||||
try {
|
try {
|
||||||
image = ImageIO.read ( new File ( "icon.png" ) );
|
image = ImageIO.read ( new File ( "icon.png" ) );
|
||||||
setIconImage ( image );
|
setIconImage ( image );
|
||||||
@ -47,14 +46,14 @@ public class MCFrame extends Frame implements WindowListener
|
|||||||
public void start ( Applet mcApplet, String user, String session, Dimension winSize, boolean maximize )
|
public void start ( Applet mcApplet, String user, String session, Dimension winSize, boolean maximize )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
appletWrap = new Launcher ( mcApplet, new URL ( "http://www.minecraft.net/game" ) );
|
appletWrap = new Launcher( mcApplet, new URL ( "http://www.minecraft.net/game" ) );
|
||||||
} catch ( MalformedURLException ignored ) {}
|
} catch ( MalformedURLException ignored ) {}
|
||||||
|
|
||||||
appletWrap.setParameter ( "username", user );
|
appletWrap.setParameter ( "username", user );
|
||||||
appletWrap.setParameter ( "sessionid", session );
|
appletWrap.setParameter ( "sessionid", session );
|
||||||
appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button.
|
appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button.
|
||||||
mcApplet.setStub ( appletWrap );
|
appletWrap.setParameter ( "demo", "false" );
|
||||||
|
appletWrap.setParameter("fullscreen", "false");
|
||||||
|
mcApplet.setStub(appletWrap);
|
||||||
this.add ( appletWrap );
|
this.add ( appletWrap );
|
||||||
appletWrap.setPreferredSize ( winSize );
|
appletWrap.setPreferredSize ( winSize );
|
||||||
this.pack();
|
this.pack();
|
||||||
@ -63,7 +62,6 @@ public class MCFrame extends Frame implements WindowListener
|
|||||||
if ( maximize ) {
|
if ( maximize ) {
|
||||||
this.setExtendedState ( MAXIMIZED_BOTH );
|
this.setExtendedState ( MAXIMIZED_BOTH );
|
||||||
}
|
}
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
appletWrap.init();
|
appletWrap.init();
|
||||||
appletWrap.start();
|
appletWrap.start();
|
178
depends/launcher/org/multimc/legacy/LegacyLauncher.java
Normal file
178
depends/launcher/org/multimc/legacy/LegacyLauncher.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
package org.multimc.legacy;/*
|
||||||
|
* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.multimc.Launcher;
|
||||||
|
import org.multimc.NotFoundException;
|
||||||
|
import org.multimc.ParamBucket;
|
||||||
|
import org.multimc.Utils;
|
||||||
|
|
||||||
|
import java.applet.Applet;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
public class LegacyLauncher implements Launcher
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int launch(ParamBucket params)
|
||||||
|
{
|
||||||
|
String userName, sessionId, windowTitle, windowParams, lwjgl;
|
||||||
|
String mainClass = "net.minecraft.client.Minecraft";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userName = params.first("userName");
|
||||||
|
sessionId = params.first("sessionId");
|
||||||
|
windowTitle = params.first("windowTitle");
|
||||||
|
windowParams = params.first("windowParams");
|
||||||
|
lwjgl = params.first("lwjgl");
|
||||||
|
} catch (NotFoundException e)
|
||||||
|
{
|
||||||
|
System.err.println("Not enough arguments.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cwd = System.getProperty("user.dir");
|
||||||
|
Dimension winSize = new Dimension(854, 480);
|
||||||
|
boolean maximize = false;
|
||||||
|
|
||||||
|
String[] dimStrings = windowParams.split("x");
|
||||||
|
|
||||||
|
if (windowParams.equalsIgnoreCase("max"))
|
||||||
|
{
|
||||||
|
maximize = true;
|
||||||
|
}
|
||||||
|
else if (dimStrings.length == 2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
winSize = new Dimension(Integer.parseInt(dimStrings[0]), Integer.parseInt(dimStrings[1]));
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
File binDir = new File(cwd, "bin");
|
||||||
|
File lwjglDir;
|
||||||
|
if (lwjgl.equalsIgnoreCase("Mojang"))
|
||||||
|
{
|
||||||
|
lwjglDir = binDir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lwjglDir = new File(lwjgl);
|
||||||
|
}
|
||||||
|
|
||||||
|
URL[] classpath;
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
classpath = new URL[]
|
||||||
|
{
|
||||||
|
new File(binDir, "minecraft.jar").toURI().toURL(),
|
||||||
|
new File(lwjglDir, "lwjgl.jar").toURI().toURL(),
|
||||||
|
new File(lwjglDir, "lwjgl_util.jar").toURI().toURL(),
|
||||||
|
new File(lwjglDir, "jinput.jar").toURI().toURL(),
|
||||||
|
};
|
||||||
|
} catch (MalformedURLException e)
|
||||||
|
{
|
||||||
|
System.err.println("Class path entry is badly formed:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String nativesDir = new File(lwjglDir, "natives").toString();
|
||||||
|
|
||||||
|
System.setProperty("org.lwjgl.librarypath", nativesDir);
|
||||||
|
System.setProperty("net.java.games.input.librarypath", nativesDir);
|
||||||
|
|
||||||
|
// print the pretty things
|
||||||
|
{
|
||||||
|
System.out.println("Main Class:");
|
||||||
|
System.out.println(mainClass);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("Class Path:");
|
||||||
|
for (URL s : classpath)
|
||||||
|
{
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("Native Path:");
|
||||||
|
System.out.println(nativesDir);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
URLClassLoader cl = new URLClassLoader(classpath, LegacyLauncher.class.getClassLoader());
|
||||||
|
|
||||||
|
// Get the Minecraft Class and set the base folder
|
||||||
|
Class<?> mc;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mc = cl.loadClass(mainClass);
|
||||||
|
|
||||||
|
Field f = Utils.getMCPathField(mc);
|
||||||
|
|
||||||
|
if (f == null)
|
||||||
|
{
|
||||||
|
System.err.println("Could not find Minecraft path field. Launch failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(null, new File(cwd));
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Could not set base folder. Failed to find/access Minecraft main class:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.setProperty("minecraft.applet.TargetDirectory", cwd);
|
||||||
|
|
||||||
|
String[] mcArgs = new String[2];
|
||||||
|
mcArgs[0] = userName;
|
||||||
|
mcArgs[1] = sessionId;
|
||||||
|
|
||||||
|
System.out.println("Launching with applet wrapper...");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> MCAppletClass = cl.loadClass("net.minecraft.client.MinecraftApplet");
|
||||||
|
Applet mcappl = (Applet) MCAppletClass.newInstance();
|
||||||
|
LegacyFrame mcWindow = new LegacyFrame(windowTitle);
|
||||||
|
mcWindow.start(mcappl, userName, sessionId, winSize, maximize);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Applet wrapper failed:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
System.err.println();
|
||||||
|
System.out.println("Falling back to compatibility mode.");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
|
||||||
|
} catch (Exception e1)
|
||||||
|
{
|
||||||
|
System.err.println("Failed to invoke the Minecraft main class:");
|
||||||
|
e1.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
196
depends/launcher/org/multimc/onesix/OneSixLauncher.java
Normal file
196
depends/launcher/org/multimc/onesix/OneSixLauncher.java
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/* Copyright 2012-2014 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.multimc.onesix;
|
||||||
|
|
||||||
|
import org.multimc.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OneSixLauncher implements Launcher
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int launch(ParamBucket params)
|
||||||
|
{
|
||||||
|
// get and process the launch script params
|
||||||
|
List<String> libraries;
|
||||||
|
List<String> mcparams;
|
||||||
|
List<String> mods;
|
||||||
|
String mainClass;
|
||||||
|
String natives;
|
||||||
|
final String windowTitle;
|
||||||
|
String windowParams;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
libraries = params.all("cp");
|
||||||
|
mcparams = params.all("param");
|
||||||
|
mainClass = params.first("mainClass");
|
||||||
|
mods = params.allSafe("mods", new ArrayList<String>());
|
||||||
|
natives = params.first("natives");
|
||||||
|
windowTitle = params.first("windowTitle");
|
||||||
|
// windowParams = params.first("windowParams");
|
||||||
|
} catch (NotFoundException e)
|
||||||
|
{
|
||||||
|
System.err.println("Not enough arguments.");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> allJars = new ArrayList<String>();
|
||||||
|
allJars.addAll(mods);
|
||||||
|
allJars.addAll(libraries);
|
||||||
|
|
||||||
|
if(!Utils.addToClassPath(allJars))
|
||||||
|
{
|
||||||
|
System.err.println("Halting launch due to previous errors.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||||
|
|
||||||
|
// print the pretty things
|
||||||
|
{
|
||||||
|
System.out.println("Main Class:");
|
||||||
|
System.out.println(mainClass);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("Libraries:");
|
||||||
|
for (String s : libraries)
|
||||||
|
{
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
if(mods.size() > 0)
|
||||||
|
{
|
||||||
|
System.out.println("Class Path Mods:");
|
||||||
|
for (String s : mods)
|
||||||
|
{
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Params:");
|
||||||
|
System.out.println(mcparams.toString());
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up the natives path(s).
|
||||||
|
System.setProperty("java.library.path", natives );
|
||||||
|
Field fieldSysPath;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
|
||||||
|
fieldSysPath.setAccessible( true );
|
||||||
|
fieldSysPath.set( null, null );
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Failed to set the native library path:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Minecraft Class.
|
||||||
|
Class<?> mc;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mc = cl.loadClass(mainClass);
|
||||||
|
} catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
System.err.println("Failed to find Minecraft main class:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the main method.
|
||||||
|
Method meth;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
meth = mc.getMethod("main", String[].class);
|
||||||
|
} catch (NoSuchMethodException e)
|
||||||
|
{
|
||||||
|
System.err.println("Failed to acquire the main method:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: works only on linux, we need a better solution
|
||||||
|
/*
|
||||||
|
final java.nio.ByteBuffer[] icons = IconLoader.load("icon.png");
|
||||||
|
new Thread() {
|
||||||
|
public void run() {
|
||||||
|
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> Display;
|
||||||
|
Method isCreated;
|
||||||
|
Method setTitle;
|
||||||
|
Method setIcon;
|
||||||
|
|
||||||
|
Display = cl.loadClass("org.lwjgl.opengl.Display");
|
||||||
|
isCreated = Display.getMethod("isCreated");
|
||||||
|
setTitle = Display.getMethod("setTitle", String.class);
|
||||||
|
setIcon = Display.getMethod("setIcon", java.nio.ByteBuffer[].class);
|
||||||
|
|
||||||
|
// set the window title? Maybe?
|
||||||
|
while(!(Boolean) isCreated.invoke(null))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(150);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
// Give it a bit more time ;)
|
||||||
|
Thread.sleep(150);
|
||||||
|
// set the title
|
||||||
|
setTitle.invoke(null,windowTitle);
|
||||||
|
// only set icon when there's actually something to set...
|
||||||
|
if(icons.length > 0)
|
||||||
|
{
|
||||||
|
setIcon.invoke(null,(Object)icons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Couldn't set window icon or title.");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.start();
|
||||||
|
*/
|
||||||
|
// start Minecraft
|
||||||
|
String[] paramsArray = mcparams.toArray(new String[mcparams.size()]); // init params accordingly
|
||||||
|
try
|
||||||
|
{
|
||||||
|
meth.invoke(null, (Object) paramsArray); // static method doesn't have an instance
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Failed to start Minecraft:");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -166,6 +166,10 @@ void ConsoleWindow::on_closeButton_clicked()
|
|||||||
|
|
||||||
void ConsoleWindow::setMayClose(bool mayclose)
|
void ConsoleWindow::setMayClose(bool mayclose)
|
||||||
{
|
{
|
||||||
|
if(mayclose)
|
||||||
|
ui->closeButton->setText(tr("Close"));
|
||||||
|
else
|
||||||
|
ui->closeButton->setText(tr("Hide"));
|
||||||
m_mayclose = mayclose;
|
m_mayclose = mayclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>689</width>
|
<width>689</width>
|
||||||
<height>331</height>
|
<height>311</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -229,7 +229,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>689</width>
|
<width>689</width>
|
||||||
<height>331</height>
|
<height>311</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -245,7 +245,7 @@
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:600;">MultiMC</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:600;">MultiMC</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Andrew Okin &lt;</span><a href="mailto:forkk@forkk.net"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; text-decoration: underline; color:#0000ff;">forkk@forkk.net</span></a><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Andrew Okin &lt;</span><a href="mailto:forkk@forkk.net"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; text-decoration: underline; color:#0000ff;">forkk@forkk.net</span></a><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Petr Mrázek &lt;</span><a href="mailto:peterix@gmail.com"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; text-decoration: underline; color:#0000ff;">peterix@gmail.com</span></a><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Petr Mrázek &lt;</span><a href="mailto:peterix@gmail.com"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; text-decoration: underline; color:#0000ff;">peterix@gmail.com</span></a><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">&gt;</span></p>
|
||||||
@ -282,7 +282,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>689</width>
|
<width>689</width>
|
||||||
<height>331</height>
|
<height>311</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -309,7 +309,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:9pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">MultiMC</span></p>
|
<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">MultiMC</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2012-2014 MultiMC Contributors</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2012-2014 MultiMC Contributors</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p>
|
||||||
@ -430,7 +430,36 @@ p, li { white-space: pre-wrap; }
|
|||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * This file has been put into the public domain.</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * This file has been put into the public domain.</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * You can do whatever you want with this file.</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * You can do whatever you want with this file.</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p>
|
||||||
|
<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Java IconLoader class</span></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Copyright (c) 2011, Chris Molini</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">All rights reserved.</span></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Redistribution and use in source and binary forms, with or without</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">modification, are permitted provided that the following conditions are met:</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Redistributions of source code must retain the above copyright</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> notice, this list of conditions and the following disclaimer.</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Redistributions in binary form must reproduce the above copyright</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> notice, this list of conditions and the following disclaimer in the</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> documentation and/or other materials provided with the distribution.</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Neither the name of the &lt;organization&gt; nor the</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> names of its contributors may be used to endorse or promote products</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> derived from this software without specific prior written permission.</span></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p>
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -442,7 +471,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>689</width>
|
<width>689</width>
|
||||||
<height>331</height>
|
<height>311</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -455,12 +484,12 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.</p>
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans'; font-size:11pt;"><br /></p>
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">Part of the reason for using the Apache license is we don't want people using the &quot;MultiMC&quot; name when redistributing the project. This means people must take the time to go through the source code and remove all references to &quot;MultiMC&quot;, including but not limited to the project icon and the title of windows, (no *MultiMC-fork* in the title).</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Part of the reason for using the Apache license is we don't want people using the &quot;MultiMC&quot; name when redistributing the project. This means people must take the time to go through the source code and remove all references to &quot;MultiMC&quot;, including but not limited to the project icon and the title of windows, (no *MultiMC-fork* in the title).</p>
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans'; font-size:11pt;"><br /></p>
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">The Apache license covers reasonable use for the name - a mention of the project's origins in the About dialog and the license is acceptable. However, it should be abundantly clear that the project is a fork </span><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:600;">without</span><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;"> implying that you have our blessing.</span></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The Apache license covers reasonable use for the name - a mention of the project's origins in the About dialog and the license is acceptable. However, it should be abundantly clear that the project is a fork <span style=" font-weight:600;">without</span> implying that you have our blessing.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textInteractionFlags">
|
<property name="textInteractionFlags">
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "overridesetting.h"
|
#include "overridesetting.h"
|
||||||
|
|
||||||
#include "pathutils.h"
|
#include "pathutils.h"
|
||||||
|
#include <cmdutils.h>
|
||||||
#include "lists/MinecraftVersionList.h"
|
#include "lists/MinecraftVersionList.h"
|
||||||
#include "logic/icons/IconList.h"
|
#include "logic/icons/IconList.h"
|
||||||
|
|
||||||
@ -248,8 +249,14 @@ void BaseInstance::setName(QString val)
|
|||||||
d->m_settings->set("name", val);
|
d->m_settings->set("name", val);
|
||||||
emit propertiesChanged(this);
|
emit propertiesChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BaseInstance::name() const
|
QString BaseInstance::name() const
|
||||||
{
|
{
|
||||||
I_D(BaseInstance);
|
I_D(BaseInstance);
|
||||||
return d->m_settings->get("name").toString();
|
return d->m_settings->get("name").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList BaseInstance::extraArguments() const
|
||||||
|
{
|
||||||
|
return Util::Commandline::splitArgs(settings().get("JvmArgs").toString());
|
||||||
|
}
|
||||||
|
@ -81,6 +81,8 @@ public:
|
|||||||
void setGroupInitial(QString val);
|
void setGroupInitial(QString val);
|
||||||
void setGroupPost(QString val);
|
void setGroupPost(QString val);
|
||||||
|
|
||||||
|
QStringList extraArguments() const;
|
||||||
|
|
||||||
virtual QString intendedVersionId() const = 0;
|
virtual QString intendedVersionId() const = 0;
|
||||||
virtual bool setIntendedVersionId(QString version) = 0;
|
virtual bool setIntendedVersionId(QString version) = 0;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ std::shared_ptr<Task> LegacyInstance::doUpdate(bool only_prepare)
|
|||||||
// make sure the jar mods list is initialized by asking for it.
|
// make sure the jar mods list is initialized by asking for it.
|
||||||
auto list = jarModList();
|
auto list = jarModList();
|
||||||
// create an update task
|
// create an update task
|
||||||
return std::shared_ptr<Task> (new LegacyUpdate(this, only_prepare , this));
|
return std::shared_ptr<Task>(new LegacyUpdate(this, only_prepare, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
|
MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
|
||||||
@ -58,58 +58,27 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
|
|||||||
auto pixmap = icon.pixmap(128, 128);
|
auto pixmap = icon.pixmap(128, 128);
|
||||||
pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
|
pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
|
||||||
|
|
||||||
// extract the legacy launcher
|
// create the launch script
|
||||||
QString launcherJar = PathCombine(MMC->bin(), "jars", "MultiMCLauncher.jar");
|
QString launchScript;
|
||||||
|
|
||||||
// set the process arguments
|
|
||||||
{
|
{
|
||||||
QStringList args;
|
|
||||||
|
|
||||||
// window size
|
// window size
|
||||||
QString windowSize;
|
QString windowParams;
|
||||||
if (settings().get("LaunchMaximized").toBool())
|
if (settings().get("LaunchMaximized").toBool())
|
||||||
windowSize = "max";
|
windowParams = "max";
|
||||||
else
|
else
|
||||||
windowSize = QString("%1x%2").arg(settings().get("MinecraftWinWidth").toInt()).arg(
|
windowParams = QString("%1x%2").arg(settings().get("MinecraftWinWidth").toInt()).arg(
|
||||||
settings().get("MinecraftWinHeight").toInt());
|
settings().get("MinecraftWinHeight").toInt());
|
||||||
|
|
||||||
// window title
|
|
||||||
QString windowTitle;
|
|
||||||
windowTitle.append("MultiMC: ").append(name());
|
|
||||||
|
|
||||||
// Java arguments
|
|
||||||
args.append(Util::Commandline::splitArgs(settings().get("JvmArgs").toString()));
|
|
||||||
|
|
||||||
#ifdef OSX
|
|
||||||
// OSX dock icon and name
|
|
||||||
args << "-Xdock:icon=icon.png";
|
|
||||||
args << QString("-Xdock:name=\"%1\"").arg(windowTitle);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString lwjgl = QDir(MMC->settings()->get("LWJGLDir").toString() + "/" + lwjglVersion())
|
QString lwjgl = QDir(MMC->settings()->get("LWJGLDir").toString() + "/" + lwjglVersion())
|
||||||
.absolutePath();
|
.absolutePath();
|
||||||
|
launchScript += "userName " + account->currentProfile()->name + "\n";
|
||||||
// launcher arguments
|
launchScript += "sessionId " + account->sessionId() + "\n";
|
||||||
args << QString("-Xms%1m").arg(settings().get("MinMemAlloc").toInt());
|
launchScript += "windowTitle MultiMC: " + name() + "\n";
|
||||||
args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt());
|
launchScript += "windowParams " + windowParams + "\n";
|
||||||
args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt());
|
launchScript += "lwjgl " + lwjgl + "\n";
|
||||||
/**
|
launchScript += "launch legacy\n";
|
||||||
* HACK: Stupid hack for Intel drivers.
|
|
||||||
* See: https://mojang.atlassian.net/browse/MCL-767
|
|
||||||
*/
|
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
|
|
||||||
"minecraft.exe.heapdump");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
args << "-jar" << launcherJar;
|
|
||||||
args << account->currentProfile()->name;
|
|
||||||
args << account->sessionId();
|
|
||||||
args << windowTitle;
|
|
||||||
args << windowSize;
|
|
||||||
args << lwjgl;
|
|
||||||
proc->setArguments(args);
|
|
||||||
}
|
}
|
||||||
|
proc->setLaunchScript(launchScript);
|
||||||
|
|
||||||
// set the process work path
|
// set the process work path
|
||||||
proc->setWorkdir(minecraftRoot());
|
proc->setWorkdir(minecraftRoot());
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "MultiMC.h"
|
||||||
|
|
||||||
#include "MinecraftProcess.h"
|
#include "MinecraftProcess.h"
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
//#include <QImage>
|
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
#include "BaseInstance.h"
|
#include "BaseInstance.h"
|
||||||
@ -59,11 +59,6 @@ MinecraftProcess::MinecraftProcess(BaseInstance *inst) : m_instance(inst)
|
|||||||
connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut()));
|
connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinecraftProcess::setArguments(QStringList args)
|
|
||||||
{
|
|
||||||
m_args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MinecraftProcess::setWorkdir(QString path)
|
void MinecraftProcess::setWorkdir(QString path)
|
||||||
{
|
{
|
||||||
QDir mcDir(path);
|
QDir mcDir(path);
|
||||||
@ -197,13 +192,43 @@ void MinecraftProcess::launch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_instance->setLastLaunch();
|
m_instance->setLastLaunch();
|
||||||
|
auto &settings = m_instance->settings();
|
||||||
|
|
||||||
|
//////////// java arguments ////////////
|
||||||
|
QStringList args;
|
||||||
|
{
|
||||||
|
// custom args go first. we want to override them if we have our own here.
|
||||||
|
args.append(m_instance->extraArguments());
|
||||||
|
|
||||||
|
// OSX dock icon and name
|
||||||
|
#ifdef OSX
|
||||||
|
args << "-Xdock:icon=icon.png";
|
||||||
|
args << QString("-Xdock:name=\"%1\"").arg(windowTitle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
|
||||||
|
"minecraft.exe.heapdump");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
args << QString("-Xms%1m").arg(settings.get("MinMemAlloc").toInt());
|
||||||
|
args << QString("-Xmx%1m").arg(settings.get("MaxMemAlloc").toInt());
|
||||||
|
args << QString("-XX:PermSize=%1m").arg(settings.get("PermGen").toInt());
|
||||||
|
if(!m_nativeFolder.isEmpty())
|
||||||
|
args << QString("-Djava.library.path=%1").arg(m_nativeFolder);
|
||||||
|
args << "-jar" << PathCombine(MMC->bin(), "jars", "NewLaunch.jar");
|
||||||
|
}
|
||||||
|
|
||||||
emit log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
|
|
||||||
QString JavaPath = m_instance->settings().get("JavaPath").toString();
|
QString JavaPath = m_instance->settings().get("JavaPath").toString();
|
||||||
emit log(QString("Java path: '%1'").arg(JavaPath));
|
emit log("MultiMC version: " + MMC->version().toString() + "\n\n");
|
||||||
QString allArgs = m_args.join("' '");
|
emit log("Minecraft folder is:\n" + workingDirectory() + "\n\n");
|
||||||
emit log(QString("Arguments: '%1'").arg(censorPrivateInfo(allArgs)));
|
emit log("Java path is:\n" + JavaPath + "\n\n");
|
||||||
start(JavaPath, m_args);
|
QString allArgs = args.join(", ");
|
||||||
|
emit log("Java Arguments:\n[" + censorPrivateInfo(allArgs) + "]\n\n");
|
||||||
|
|
||||||
|
// instantiate the launcher part
|
||||||
|
start(JavaPath, args);
|
||||||
if (!waitForStarted())
|
if (!waitForStarted())
|
||||||
{
|
{
|
||||||
//: Error message displayed if instace can't start
|
//: Error message displayed if instace can't start
|
||||||
@ -212,11 +237,13 @@ void MinecraftProcess::launch()
|
|||||||
emit launch_failed(m_instance);
|
emit launch_failed(m_instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// send the launch script to the launcher part
|
||||||
|
QByteArray bytes = launchScript.toUtf8();
|
||||||
|
writeData(bytes.constData(), bytes.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageLevel::Enum MinecraftProcess::getLevel(const QString &line, MessageLevel::Enum level)
|
MessageLevel::Enum MinecraftProcess::getLevel(const QString &line, MessageLevel::Enum level)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
|
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
|
||||||
line.contains("[FINER]") || line.contains("[FINEST]"))
|
line.contains("[FINER]") || line.contains("[FINEST]"))
|
||||||
level = MessageLevel::Message;
|
level = MessageLevel::Message;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QString>
|
||||||
#include "BaseInstance.h"
|
#include "BaseInstance.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +65,15 @@ public:
|
|||||||
|
|
||||||
void setWorkdir(QString path);
|
void setWorkdir(QString path);
|
||||||
|
|
||||||
void setArguments(QStringList args);
|
void setLaunchScript(QString script)
|
||||||
|
{
|
||||||
|
launchScript = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNativeFolder(QString natives)
|
||||||
|
{
|
||||||
|
m_nativeFolder = natives;
|
||||||
|
}
|
||||||
|
|
||||||
void killMinecraft();
|
void killMinecraft();
|
||||||
|
|
||||||
@ -104,12 +112,13 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseInstance *m_instance = nullptr;
|
BaseInstance *m_instance = nullptr;
|
||||||
QStringList m_args;
|
|
||||||
QString m_err_leftover;
|
QString m_err_leftover;
|
||||||
QString m_out_leftover;
|
QString m_out_leftover;
|
||||||
QProcess m_prepostlaunchprocess;
|
QProcess m_prepostlaunchprocess;
|
||||||
bool killed = false;
|
bool killed = false;
|
||||||
MojangAccountPtr m_account;
|
MojangAccountPtr m_account;
|
||||||
|
QString launchScript;
|
||||||
|
QString m_nativeFolder;
|
||||||
|
|
||||||
protected
|
protected
|
||||||
slots:
|
slots:
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "MultiMC.h"
|
||||||
#include "OneSixInstance.h"
|
#include "OneSixInstance.h"
|
||||||
#include "OneSixInstance_p.h"
|
#include "OneSixInstance_p.h"
|
||||||
#include "OneSixUpdate.h"
|
#include "OneSixUpdate.h"
|
||||||
#include "MinecraftProcess.h"
|
#include "MinecraftProcess.h"
|
||||||
#include "OneSixVersion.h"
|
#include "OneSixVersion.h"
|
||||||
#include "JavaChecker.h"
|
#include "JavaChecker.h"
|
||||||
|
#include "logic/icons/IconList.h"
|
||||||
|
|
||||||
#include <setting.h>
|
#include <setting.h>
|
||||||
#include <pathutils.h>
|
#include <pathutils.h>
|
||||||
@ -27,6 +29,7 @@
|
|||||||
#include "gui/dialogs/OneSixModEditDialog.h"
|
#include "gui/dialogs/OneSixModEditDialog.h"
|
||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
#include "logic/assets/AssetsUtils.h"
|
#include "logic/assets/AssetsUtils.h"
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
|
OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
@ -40,7 +43,7 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o
|
|||||||
|
|
||||||
std::shared_ptr<Task> OneSixInstance::doUpdate(bool only_prepare)
|
std::shared_ptr<Task> OneSixInstance::doUpdate(bool only_prepare)
|
||||||
{
|
{
|
||||||
return std::shared_ptr<Task> (new OneSixUpdate(this, only_prepare));
|
return std::shared_ptr<Task>(new OneSixUpdate(this, only_prepare));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
||||||
@ -78,24 +81,25 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr<OneSixVersion> version)
|
|||||||
QFile indexFile(indexPath);
|
QFile indexFile(indexPath);
|
||||||
QDir virtualRoot(PathCombine(virtualDir.path(), version->assets));
|
QDir virtualRoot(PathCombine(virtualDir.path(), version->assets));
|
||||||
|
|
||||||
if(!indexFile.exists())
|
if (!indexFile.exists())
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "No assets index file" << indexPath << "; can't reconstruct assets";
|
QLOG_ERROR() << "No assets index file" << indexPath << "; can't reconstruct assets";
|
||||||
return virtualRoot;
|
return virtualRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
QLOG_DEBUG() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path();
|
QLOG_DEBUG() << "reconstructAssets" << assetsDir.path() << indexDir.path()
|
||||||
|
<< objectDir.path() << virtualDir.path() << virtualRoot.path();
|
||||||
|
|
||||||
AssetsIndex index;
|
AssetsIndex index;
|
||||||
bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index);
|
bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index);
|
||||||
|
|
||||||
if(loadAssetsIndex)
|
if (loadAssetsIndex)
|
||||||
{
|
{
|
||||||
if(index.isVirtual)
|
if (index.isVirtual)
|
||||||
{
|
{
|
||||||
QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path();
|
QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path();
|
||||||
|
|
||||||
for(QString map : index.objects.keys())
|
for (QString map : index.objects.keys())
|
||||||
{
|
{
|
||||||
AssetObject asset_object = index.objects.value(map);
|
AssetObject asset_object = index.objects.value(map);
|
||||||
QString target_path = PathCombine(virtualRoot.path(), map);
|
QString target_path = PathCombine(virtualRoot.path(), map);
|
||||||
@ -103,17 +107,20 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr<OneSixVersion> version)
|
|||||||
|
|
||||||
QString tlk = asset_object.hash.left(2);
|
QString tlk = asset_object.hash.left(2);
|
||||||
|
|
||||||
QString original_path = PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash);
|
QString original_path =
|
||||||
|
PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash);
|
||||||
QFile original(original_path);
|
QFile original(original_path);
|
||||||
if(!target.exists())
|
if (!target.exists())
|
||||||
{
|
{
|
||||||
QFileInfo info(target_path);
|
QFileInfo info(target_path);
|
||||||
QDir target_dir = info.dir();
|
QDir target_dir = info.dir();
|
||||||
//QLOG_DEBUG() << target_dir;
|
// QLOG_DEBUG() << target_dir;
|
||||||
if(!target_dir.exists()) QDir("").mkpath(target_dir.path());
|
if (!target_dir.exists())
|
||||||
|
QDir("").mkpath(target_dir.path());
|
||||||
|
|
||||||
bool couldCopy = original.copy(target_path);
|
bool couldCopy = original.copy(target_path);
|
||||||
QLOG_DEBUG() << " Copying" << original_path << "to" << target_path << QString::number(couldCopy);// << original.errorString();
|
QLOG_DEBUG() << " Copying" << original_path << "to" << target_path
|
||||||
|
<< QString::number(couldCopy); // << original.errorString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +162,7 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
|
|||||||
|
|
||||||
auto user = account->user();
|
auto user = account->user();
|
||||||
QJsonObject userAttrs;
|
QJsonObject userAttrs;
|
||||||
for(auto key: user.properties.keys())
|
for (auto key : user.properties.keys())
|
||||||
{
|
{
|
||||||
auto array = QJsonArray::fromStringList(user.properties.values(key));
|
auto array = QJsonArray::fromStringList(user.properties.values(key));
|
||||||
userAttrs.insert(key, array);
|
userAttrs.insert(key, array);
|
||||||
@ -180,71 +187,56 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account)
|
|||||||
{
|
{
|
||||||
I_D(OneSixInstance);
|
I_D(OneSixInstance);
|
||||||
|
|
||||||
QString natives_dir_raw = PathCombine(instanceRoot(), "natives/");
|
QIcon icon = MMC->icons()->getIcon(iconKey());
|
||||||
|
auto pixmap = icon.pixmap(128, 128);
|
||||||
|
pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
|
||||||
|
|
||||||
auto version = d->version;
|
auto version = d->version;
|
||||||
if (!version)
|
if (!version)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
QString launchScript;
|
||||||
QStringList args;
|
|
||||||
args.append(Util::Commandline::splitArgs(settings().get("JvmArgs").toString()));
|
|
||||||
args << QString("-Xms%1m").arg(settings().get("MinMemAlloc").toInt());
|
|
||||||
args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt());
|
|
||||||
args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HACK: Stupid hack for Intel drivers.
|
|
||||||
* See: https://mojang.atlassian.net/browse/MCL-767
|
|
||||||
*/
|
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
|
|
||||||
"minecraft.exe.heapdump");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QDir natives_dir(natives_dir_raw);
|
|
||||||
args << QString("-Djava.library.path=%1").arg(natives_dir.absolutePath());
|
|
||||||
QString classPath;
|
|
||||||
{
|
{
|
||||||
auto libs = version->getActiveNormalLibs();
|
auto libs = version->getActiveNormalLibs();
|
||||||
for (auto lib : libs)
|
for (auto lib : libs)
|
||||||
{
|
{
|
||||||
QFileInfo fi(QString("libraries/") + lib->storagePath());
|
QFileInfo fi(QString("libraries/") + lib->storagePath());
|
||||||
classPath.append(fi.absoluteFilePath());
|
launchScript += "cp " + fi.absoluteFilePath() + "\n";
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
classPath.append(';');
|
|
||||||
#else
|
|
||||||
classPath.append(':');
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
QString targetstr = "versions/" + version->id + "/" + version->id + ".jar";
|
QString targetstr = "versions/" + version->id + "/" + version->id + ".jar";
|
||||||
QFileInfo fi(targetstr);
|
QFileInfo fi(targetstr);
|
||||||
classPath.append(fi.absoluteFilePath());
|
launchScript += "cp " + fi.absoluteFilePath() + "\n";
|
||||||
}
|
}
|
||||||
if (classPath.size())
|
launchScript += "mainClass " + version->mainClass + "\n";
|
||||||
|
|
||||||
|
for (auto param : processMinecraftArgs(account))
|
||||||
{
|
{
|
||||||
args << "-cp";
|
launchScript += "param " + param + "\n";
|
||||||
args << classPath;
|
|
||||||
}
|
}
|
||||||
args << version->mainClass;
|
|
||||||
args.append(processMinecraftArgs(account));
|
|
||||||
|
|
||||||
// Set the width and height for 1.6 instances
|
// Set the width and height for 1.6 instances
|
||||||
bool maximize = settings().get("LaunchMaximized").toBool();
|
bool maximize = settings().get("LaunchMaximized").toBool();
|
||||||
if (maximize)
|
if (maximize)
|
||||||
{
|
{
|
||||||
// this is probably a BAD idea
|
// this is probably a BAD idea
|
||||||
// args << QString("--fullscreen");
|
// launchScript += "param --fullscreen\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args << QString("--width") << settings().get("MinecraftWinWidth").toString();
|
launchScript +=
|
||||||
args << QString("--height") << settings().get("MinecraftWinHeight").toString();
|
"param --width\nparam " + settings().get("MinecraftWinWidth").toString() + "\n";
|
||||||
|
launchScript +=
|
||||||
|
"param --height\nparam " + settings().get("MinecraftWinHeight").toString() + "\n";
|
||||||
}
|
}
|
||||||
|
QDir natives_dir(PathCombine(instanceRoot(), "natives/"));
|
||||||
|
launchScript += "windowTitle MultiMC: " + name() + "\n";
|
||||||
|
launchScript += "natives " + natives_dir.absolutePath() + "\n";
|
||||||
|
launchScript += "launch onesix\n";
|
||||||
|
|
||||||
// create the process and set its parameters
|
// create the process and set its parameters
|
||||||
MinecraftProcess *proc = new MinecraftProcess(this);
|
MinecraftProcess *proc = new MinecraftProcess(this);
|
||||||
proc->setArguments(args);
|
|
||||||
proc->setWorkdir(minecraftRoot());
|
proc->setWorkdir(minecraftRoot());
|
||||||
|
proc->setLaunchScript(launchScript);
|
||||||
|
// proc->setNativeFolder(natives_dir.absolutePath());
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user