diff options
Diffstat (limited to 'libraries')
30 files changed, 150 insertions, 1069 deletions
diff --git a/libraries/classparser/CMakeLists.txt b/libraries/classparser/CMakeLists.txt index a6c3fa14..db266f53 100644 --- a/libraries/classparser/CMakeLists.txt +++ b/libraries/classparser/CMakeLists.txt @@ -18,7 +18,7 @@ include_directories(${Qt5Base_INCLUDE_DIRS}) set(CLASSPARSER_HEADERS # Public headers include/classparser_config.h -include/javautils.h +include/classparser.h # Private headers src/annotations.h @@ -30,12 +30,13 @@ src/membuffer.h ) set(CLASSPARSER_SOURCES -src/javautils.cpp +src/classparser.cpp src/annotations.cpp ) add_definitions(-DCLASSPARSER_LIBRARY) -add_library(classparser SHARED ${CLASSPARSER_SOURCES} ${CLASSPARSER_HEADERS}) -target_include_directories(classparser PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") -qt5_use_modules(classparser Core) +add_library(MultiMC_classparser STATIC ${CLASSPARSER_SOURCES} ${CLASSPARSER_HEADERS}) +target_include_directories(MultiMC_classparser PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(MultiMC_classparser MultiMC_quazip) +qt5_use_modules(MultiMC_classparser Core) diff --git a/libraries/classparser/include/javautils.h b/libraries/classparser/include/classparser.h index aad7b504..23a65589 100644 --- a/libraries/classparser/include/javautils.h +++ b/libraries/classparser/include/classparser.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Authors: Orochimarufan <orochimarufan.x3@gmail.com> * @@ -18,9 +18,7 @@ #include <QString> #include "classparser_config.h" -#define MCVer_Unknown "Unknown" - -namespace javautils +namespace classparser { /** * @brief Get the version from a minecraft.jar by parsing its class files. Expensive! diff --git a/libraries/classparser/include/classparser_config.h b/libraries/classparser/include/classparser_config.h index cc903210..db8f40a3 100644 --- a/libraries/classparser/include/classparser_config.h +++ b/libraries/classparser/include/classparser_config.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/classparser/src/annotations.h b/libraries/classparser/src/annotations.h index aa25d241..dd603af3 100644 --- a/libraries/classparser/src/annotations.h +++ b/libraries/classparser/src/annotations.h @@ -42,6 +42,7 @@ protected: public: element_value(element_value_type type, constant_pool &pool) : type(type), pool(pool) {}; + virtual ~element_value() {} element_value_type getElementValueType() { diff --git a/libraries/classparser/src/javautils.cpp b/libraries/classparser/src/classparser.cpp index 719032af..8837781f 100644 --- a/libraries/classparser/src/javautils.cpp +++ b/libraries/classparser/src/classparser.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Authors: Orochimarufan <orochimarufan.x3@gmail.com> * @@ -15,17 +15,18 @@ * limitations under the License. */ #include "classfile.h" -#include "javautils.h" +#include "classparser.h" #include <QFile> #include <quazipfile.h> +#include <QDebug> -namespace javautils +namespace classparser { QString GetMinecraftJarVersion(QString jarName) { - QString version = MCVer_Unknown; + QString version; // check if minecraft.jar exists QFile jar(jarName); @@ -61,6 +62,7 @@ QString GetMinecraftJarVersion(QString jarName) if (constant.type != java::constant::j_string_data) continue; const std::string &str = constant.str_data; + qDebug() << QString::fromStdString(str); if (str.compare(0, 20, "Minecraft Minecraft ") == 0) { version = str.substr(20).data(); diff --git a/libraries/classparser/src/constants.h b/libraries/classparser/src/constants.h index 242b943e..9c74ab20 100644 --- a/libraries/classparser/src/constants.h +++ b/libraries/classparser/src/constants.h @@ -21,14 +21,12 @@ public: j_methodref = 10, j_interface_methodref = 11, j_nameandtype = 12 + // FIXME: missing some constant types, see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 } type; constant(util::membuffer &buf) { buf.read(type); - // invalid constant type! - if (type > j_nameandtype || type == (type_t)0 || type == (type_t)2) - throw new classfile_exception(); // load data depending on type switch (type) @@ -65,10 +63,13 @@ public: buf.read_be(name_and_type.name_index); buf.read_be(name_and_type.descriptor_index); break; + default: + // invalid constant type! + throw new classfile_exception(); } } - constant(int fake) + constant(int) { type = j_hole; } @@ -115,6 +116,9 @@ public: ss << "NameAndType: " << name_and_type.name_index << " " << name_and_type.descriptor_index; break; + default: + ss << "Invalid entry (" << int(type) << ")"; + break; } return ss.str(); } @@ -166,10 +170,10 @@ public: */ void load(util::membuffer &buf) { + // FIXME: @SANITY this should check for the end of buffer. uint16_t length = 0; buf.read_be(length); length--; - uint16_t index = 1; const constant *last_constant = nullptr; while (length) { @@ -182,12 +186,10 @@ public: // push in a fake constant to preserve indexing constants.push_back(constant(0)); length -= 2; - index += 2; } else { length--; - index++; } } } diff --git a/libraries/iconfix/CMakeLists.txt b/libraries/iconfix/CMakeLists.txt index 6a99effe..93bfdd06 100644 --- a/libraries/iconfix/CMakeLists.txt +++ b/libraries/iconfix/CMakeLists.txt @@ -19,3 +19,10 @@ qt5_use_modules(MultiMC_iconfix Core Widgets) set_target_properties(MultiMC_iconfix PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1) generate_export_header(MultiMC_iconfix) + +# Install it +install( + TARGETS MultiMC_iconfix + RUNTIME DESTINATION ${LIBRARY_DEST_DIR} + LIBRARY DESTINATION ${LIBRARY_DEST_DIR} +)
\ No newline at end of file diff --git a/libraries/javacheck/CMakeLists.txt b/libraries/javacheck/CMakeLists.txt index 9768650e..381efe08 100644 --- a/libraries/javacheck/CMakeLists.txt +++ b/libraries/javacheck/CMakeLists.txt @@ -11,3 +11,4 @@ set(SRC ) add_jar(JavaCheck ${SRC}) +install_jar(JavaCheck "${JARS_DEST_DIR}") diff --git a/libraries/launcher/CMakeLists.txt b/libraries/launcher/CMakeLists.txt index 9c0e128b..a4f52edb 100644 --- a/libraries/launcher/CMakeLists.txt +++ b/libraries/launcher/CMakeLists.txt @@ -7,27 +7,15 @@ 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(SRC - # OSX things - org/simplericity/macify/eawt/Application.java - org/simplericity/macify/eawt/ApplicationAdapter.java - org/simplericity/macify/eawt/ApplicationEvent.java - org/simplericity/macify/eawt/ApplicationListener.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 - org/multimc/LegacyFrame.java - - # onesix launcher - org/multimc/onesix/OneSixLauncher.java - - # generic launcher org/multimc/EntryPoint.java org/multimc/Launcher.java + org/multimc/LegacyFrame.java + org/multimc/NotFoundException.java + org/multimc/ParamBucket.java org/multimc/ParseException.java org/multimc/Utils.java - org/multimc/IconLoader.java + org/multimc/onesix/OneSixLauncher.java + net/minecraft/Launcher.java ) add_jar(NewLaunch ${SRC}) - +install_jar(NewLaunch "${JARS_DEST_DIR}") diff --git a/libraries/launcher/net/minecraft/Launcher.java b/libraries/launcher/net/minecraft/Launcher.java index 5aec2654..0c991cf5 100644 --- a/libraries/launcher/net/minecraft/Launcher.java +++ b/libraries/launcher/net/minecraft/Launcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/launcher/org/multimc/EntryPoint.java b/libraries/launcher/org/multimc/EntryPoint.java index e4d335b7..8c9b8074 100644 --- a/libraries/launcher/org/multimc/EntryPoint.java +++ b/libraries/launcher/org/multimc/EntryPoint.java @@ -1,5 +1,5 @@ package org.multimc;/* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,7 @@ package org.multimc;/* */ 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.*; import java.nio.charset.Charset; @@ -34,21 +30,6 @@ public class EntryPoint 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) diff --git a/libraries/launcher/org/multimc/IconLoader.java b/libraries/launcher/org/multimc/IconLoader.java deleted file mode 100644 index f1638f3a..00000000 --- a/libraries/launcher/org/multimc/IconLoader.java +++ /dev/null @@ -1,132 +0,0 @@ -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); - } -}
\ No newline at end of file diff --git a/libraries/launcher/org/multimc/Launcher.java b/libraries/launcher/org/multimc/Launcher.java index fd7af8b8..2e851d18 100644 --- a/libraries/launcher/org/multimc/Launcher.java +++ b/libraries/launcher/org/multimc/Launcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/launcher/org/multimc/LegacyFrame.java b/libraries/launcher/org/multimc/LegacyFrame.java index 8f7a364c..9842eb0e 100644 --- a/libraries/launcher/org/multimc/LegacyFrame.java +++ b/libraries/launcher/org/multimc/LegacyFrame.java @@ -1,5 +1,5 @@ package org.multimc;/* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,12 @@ import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.Scanner; public class LegacyFrame extends Frame implements WindowListener { @@ -43,19 +46,64 @@ public class LegacyFrame extends Frame implements WindowListener this.addWindowListener ( this ); } - public void start ( Applet mcApplet, String user, String session, Dimension winSize, boolean maximize ) + public void start ( Applet mcApplet, String user, String session, int winSizeW, int winSizeH, boolean maximize ) { try { appletWrap = new Launcher( mcApplet, new URL ( "http://www.minecraft.net/game" ) ); } catch ( MalformedURLException ignored ) {} + + // Implements support for launching in to multiplayer on classic servers using a mpticket + // file generated by an external program and stored in the instance's root folder. + File mpticketFile = null; + Scanner fileReader = null; + try { + mpticketFile = new File(System.getProperty("user.dir") + "/../mpticket").getCanonicalFile(); + fileReader = new Scanner(new FileInputStream(mpticketFile), "ascii"); + String[] mpticketParams = new String[3]; + + for(int i=0;i<3;i++) { + if(fileReader.hasNextLine()) { + mpticketParams[i] = fileReader.nextLine(); + } else { + throw new IllegalArgumentException(); + } + } + + // Assumes parameters are valid and in the correct order + appletWrap.setParameter("server", mpticketParams[0]); + appletWrap.setParameter("port", mpticketParams[1]); + appletWrap.setParameter("mppass", mpticketParams[2]); + + fileReader.close(); + mpticketFile.delete(); + } + catch (FileNotFoundException e) {} + catch (IllegalArgumentException e) { + + fileReader.close(); + File mpticketFileCorrupt = new File(System.getProperty("user.dir") + "/../mpticket.corrupt"); + if(mpticketFileCorrupt.exists()) { + mpticketFileCorrupt.delete(); + } + mpticketFile.renameTo(mpticketFileCorrupt); + + System.err.println("Malformed mpticket file, missing argument."); + e.printStackTrace(System.err); + System.exit(-1); + } + catch (Exception e) { + e.printStackTrace(System.err); + System.exit(-1); + } appletWrap.setParameter ( "username", user ); appletWrap.setParameter ( "sessionid", session ); appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button. - appletWrap.setParameter ( "demo", "false" ); - appletWrap.setParameter("fullscreen", "false"); + appletWrap.setParameter ( "haspaid", "true" ); // Some old versions need this for world saves to work. + appletWrap.setParameter ( "demo", "false" ); + appletWrap.setParameter ( "fullscreen", "false" ); mcApplet.setStub(appletWrap); this.add ( appletWrap ); - appletWrap.setPreferredSize ( winSize ); + appletWrap.setPreferredSize ( new Dimension (winSizeW, winSizeH) ); this.pack(); this.setLocationRelativeTo ( null ); this.setResizable ( true ); diff --git a/libraries/launcher/org/multimc/NotFoundException.java b/libraries/launcher/org/multimc/NotFoundException.java index aa27c173..2c5da6de 100644 --- a/libraries/launcher/org/multimc/NotFoundException.java +++ b/libraries/launcher/org/multimc/NotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/launcher/org/multimc/ParamBucket.java b/libraries/launcher/org/multimc/ParamBucket.java index d3880dd7..5e9c3ff6 100644 --- a/libraries/launcher/org/multimc/ParamBucket.java +++ b/libraries/launcher/org/multimc/ParamBucket.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/launcher/org/multimc/ParseException.java b/libraries/launcher/org/multimc/ParseException.java index b2e5ff65..9a8fe521 100644 --- a/libraries/launcher/org/multimc/ParseException.java +++ b/libraries/launcher/org/multimc/ParseException.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libraries/launcher/org/multimc/Utils.java b/libraries/launcher/org/multimc/Utils.java index 860c0864..c5292eaf 100644 --- a/libraries/launcher/org/multimc/Utils.java +++ b/libraries/launcher/org/multimc/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 MultiMC Contributors + * Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,77 +68,6 @@ 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 diff --git a/libraries/launcher/org/multimc/onesix/OneSixLauncher.java b/libraries/launcher/org/multimc/onesix/OneSixLauncher.java index 61a30ede..9667297d 100644 --- a/libraries/launcher/org/multimc/onesix/OneSixLauncher.java +++ b/libraries/launcher/org/multimc/onesix/OneSixLauncher.java @@ -1,4 +1,4 @@ -/* Copyright 2012-2017 MultiMC Contributors +/* Copyright 2012-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import org.multimc.*; import java.applet.Applet; import java.io.File; -import java.awt.*; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -43,7 +42,8 @@ public class OneSixLauncher implements Launcher private String windowParams; // secondary parameters - private Dimension winSize; + private int winSizeW; + private int winSizeH; private boolean maximize; private String cwd; @@ -65,7 +65,9 @@ public class OneSixLauncher implements Launcher windowParams = params.firstSafe("windowParams", "854x480"); cwd = System.getProperty("user.dir"); - winSize = new Dimension(854, 480); + + winSizeW = 854; + winSizeH = 480; maximize = false; String[] dimStrings = windowParams.split("x"); @@ -78,7 +80,8 @@ public class OneSixLauncher implements Launcher { try { - winSize = new Dimension(Integer.parseInt(dimStrings[0]), Integer.parseInt(dimStrings[1])); + winSizeW = Integer.parseInt(dimStrings[0]); + winSizeH = Integer.parseInt(dimStrings[1]); } catch (NumberFormatException ignored) {} } } @@ -111,34 +114,37 @@ public class OneSixLauncher implements Launcher System.setProperty("min |
