Skip to content

Commit

Permalink
Use some object oriented programming
Browse files Browse the repository at this point in the history
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
  • Loading branch information
TheKodeToad committed Oct 26, 2022
1 parent deb42d1 commit 41a1926
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 224 deletions.
13 changes: 12 additions & 1 deletion launcher/minecraft/MinecraftInstance.cpp
Expand Up @@ -3,6 +3,7 @@
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright ()
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -647,7 +648,17 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
{
launchScript += "traits " + trait + "\n";
}
launchScript += "launcher onesix\n";

launchScript += "launcher ";

// use legacy launcher if the traits are set
if (profile->getTraits().contains("legacyLaunch") || profile->getTraits().contains("alphaLaunch"))
launchScript += "legacy";
else
launchScript += "standard";

launchScript += "\n";

// qDebug() << "Generated launch script:" << launchScript;
return launchScript;
}
Expand Down
6 changes: 3 additions & 3 deletions libraries/README.md
Expand Up @@ -51,10 +51,10 @@ It:

This means the process is essentially idle until the final command is sent. You can, for example, attach a profiler before you send it.

A `legacy` and `onesix` launchers are available.
A `legacy` and `standard` launchers are available.

- `legacy` is intended for use with Minecraft versions < 1.6 and is deprecated.
- `onesix` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).
- `standard` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).

Example (some parts have been censored):

Expand Down Expand Up @@ -132,7 +132,7 @@ ext /home/peterix/minecraft/FTB/libraries/org/lwjgl/lwjgl/lwjgl-platform/2.9.1/l
ext /home/peterix/minecraft/FTB/libraries/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar
natives /home/peterix/minecraft/FTB/17ForgeTest/natives
cp /home/peterix/minecraft/FTB/versions/1.7.10/1.7.10.jar
launcher onesix
launcher standard
```

Available under `GPL-3.0-only` (with classpath exception), sublicensed from its original `Apache-2.0` codebase
Expand Down
4 changes: 3 additions & 1 deletion libraries/launcher/CMakeLists.txt
Expand Up @@ -10,7 +10,9 @@ set(SRC
org/prismlauncher/EntryPoint.java
org/prismlauncher/Launcher.java
org/prismlauncher/LauncherFactory.java
org/prismlauncher/impl/OneSixLauncher.java
org/prismlauncher/impl/AbstractLauncher.java
org/prismlauncher/impl/LegacyLauncher.java
org/prismlauncher/impl/StandardLauncher.java
org/prismlauncher/applet/LegacyFrame.java
org/prismlauncher/exception/ParameterNotFoundException.java
org/prismlauncher/exception/ParseException.java
Expand Down
32 changes: 17 additions & 15 deletions libraries/launcher/org/prismlauncher/EntryPoint.java
Expand Up @@ -81,28 +81,30 @@ public static void main(String[] args) {
}

private Action parseLine(String inData) throws ParseException {
String[] tokens = inData.split("\\s+", 2);

if (tokens.length == 0)
if (inData.length() == 0)
throw new ParseException("Unexpected empty string!");

switch (tokens[0]) {
case "launch": {
return Action.LAUNCH;
}
String first = inData;
String second = null;
int splitPoint = inData.indexOf(' ');

case "abort": {
return Action.ABORT;
}
if (splitPoint != -1) {
first = first.substring(0, splitPoint);
second = inData.substring(splitPoint + 1);
}

default: {
if (tokens.length != 2)
switch (first) {
case "launch":
return Action.LAUNCH;
case "abort":
return Action.ABORT;
default:
if (second == null || second.isEmpty())
throw new ParseException("Error while parsing:" + inData);

params.add(tokens[0], tokens[1]);
params.add(first, second);

return Action.PROCEED;
}
}
}

Expand All @@ -123,7 +125,7 @@ public int listen() {
}
}
} catch (IOException | ParseException e) {
LOGGER.log(Level.SEVERE, "Launcher ABORT due to exception:", e);
LOGGER.log(Level.SEVERE, "Launcher abort due to exception:", e);

return 1;
}
Expand Down
13 changes: 10 additions & 3 deletions libraries/launcher/org/prismlauncher/LauncherFactory.java
Expand Up @@ -35,7 +35,8 @@

package org.prismlauncher;

import org.prismlauncher.impl.OneSixLauncher;
import org.prismlauncher.impl.LegacyLauncher;
import org.prismlauncher.impl.StandardLauncher;
import org.prismlauncher.utils.Parameters;

import java.util.HashMap;
Expand All @@ -48,10 +49,16 @@ public final class LauncherFactory {
private final Map<String, LauncherProvider> launcherRegistry = new HashMap<>();

private LauncherFactory() {
launcherRegistry.put("onesix", new LauncherProvider() {
launcherRegistry.put("standard", new LauncherProvider() {
@Override
public Launcher provide(Parameters parameters) {
return new OneSixLauncher(parameters);
return new StandardLauncher(parameters);
}
});
launcherRegistry.put("legacy", new LauncherProvider() {
@Override
public Launcher provide(Parameters parameters) {
return new LegacyLauncher(parameters);
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion libraries/launcher/org/prismlauncher/applet/LegacyFrame.java
Expand Up @@ -34,6 +34,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

@SuppressWarnings("removal")
public final class LegacyFrame extends Frame {

private static final Logger LOGGER = Logger.getLogger("LegacyFrame");
Expand All @@ -44,7 +45,6 @@ public LegacyFrame(String title, Applet mcApplet) {
super(title);

appletWrap = new Launcher(mcApplet);
appletWrap.setParameter("stand-alone", "true"); // Show the quit button. Required here otherwise the option will be ignored.

mcApplet.setStub(appletWrap);

Expand Down Expand Up @@ -106,6 +106,7 @@ public void start (

appletWrap.setParameter("username", user);
appletWrap.setParameter("sessionid", session);
appletWrap.setParameter("stand-alone", "true"); // Show the quit button. TODO: why won't this work?
appletWrap.setParameter("haspaid", "true"); // Some old versions need this for world saves to work.
appletWrap.setParameter("demo", isDemo ? "true" : "false");
appletWrap.setParameter("fullscreen", "false");
Expand Down
95 changes: 95 additions & 0 deletions libraries/launcher/org/prismlauncher/impl/AbstractLauncher.java
@@ -0,0 +1,95 @@
/* Copyright 2012-2021 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.prismlauncher.impl;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.prismlauncher.Launcher;
import org.prismlauncher.exception.ParseException;
import org.prismlauncher.utils.Parameters;

public abstract class AbstractLauncher implements Launcher {

private static final int DEFAULT_WINDOW_WIDTH = 854;
private static final int DEFAULT_WINDOW_HEIGHT = 480;

// parameters, separated from ParamBucket
protected final List<String> mcParams;
private final String mainClass;

// secondary parameters
protected final int width;
protected final int height;
protected final boolean maximize;

protected final String serverAddress, serverPort;

protected final ClassLoader classLoader;

public AbstractLauncher(Parameters params) {
classLoader = ClassLoader.getSystemClassLoader();

mcParams = params.allSafe("param", new ArrayList<String>());
mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");

serverAddress = params.firstSafe("serverAddress", null);
serverPort = params.firstSafe("serverPort", null);

String windowParams = params.firstSafe("windowParams", null);

if ("max".equals(windowParams) || windowParams == null) {
maximize = windowParams != null;

width = DEFAULT_WINDOW_WIDTH;
height = DEFAULT_WINDOW_HEIGHT;
} else {
maximize = false;

int byIndex = windowParams.indexOf('x');

if (byIndex != -1) {
try {
width = Integer.parseInt(windowParams.substring(0, byIndex));
height = Integer.parseInt(windowParams.substring(byIndex + 1));
return;
} catch(NumberFormatException pass) {
}
}

throw new ParseException("Invalid window size parameter value: " + windowParams);
}
}

protected Class<?> loadMain() throws ClassNotFoundException {
return classLoader.loadClass(mainClass);
}

protected void loadAndInvokeMain() throws Throwable, ClassNotFoundException {
invokeMain(loadMain());
}

protected void invokeMain(Class<?> mainClass) throws Throwable {
MethodHandle method = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));

method.invokeExact(mcParams.toArray(new String[0]));
}

}
104 changes: 104 additions & 0 deletions libraries/launcher/org/prismlauncher/impl/LegacyLauncher.java
@@ -0,0 +1,104 @@
/* Copyright 2012-2021 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.prismlauncher.impl;

import java.applet.Applet;
import java.io.File;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.prismlauncher.applet.LegacyFrame;
import org.prismlauncher.utils.Parameters;
import org.prismlauncher.utils.Utils;

@SuppressWarnings("removal")
public final class LegacyLauncher extends AbstractLauncher {

private static final Logger LOGGER = Logger.getLogger("LegacyLauncher");

private final String user, session;
private final String title;
private final String appletClass;

private final boolean noApplet;
private final String cwd;

public LegacyLauncher(Parameters params) {
super(params);

user = params.first("userName");
session = params.first("sessionId");
title = params.firstSafe("windowTitle", "Minecraft");
appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");

List<String> traits = params.allSafe("traits", Collections.<String>emptyList());
noApplet = traits.contains("noapplet");

cwd = System.getProperty("user.dir");
}

@Override
public void launch() throws Throwable {
Class<?> main = loadMain();
Field gameDirField = Utils.getMinecraftGameDirField(main);

if (gameDirField == null) {
LOGGER.warning("Could not find Mineraft path field.");
} else {
gameDirField.setAccessible(true);
gameDirField.set(null, new File(cwd));
}

if (!noApplet) {
LOGGER.info("Launching with applet wrapper...");

try {
Class<?> appletClass = classLoader.loadClass(this.appletClass);

MethodHandle constructor = MethodHandles.lookup().findConstructor(appletClass, MethodType.methodType(void.class));
Applet applet = (Applet) constructor.invoke();

LegacyFrame window = new LegacyFrame(title, applet);

window.start(
user,
session,
width,
height,
maximize,
serverAddress,
serverPort,
mcParams.contains("--demo")
);

return;
} catch (Throwable e) {
LOGGER.log(Level.SEVERE, "Applet wrapper failed:", e);

LOGGER.warning("Falling back to using main class.");
}
}

invokeMain(main);
}

}

0 comments on commit 41a1926

Please sign in to comment.