Skip to content

Commit

Permalink
stage2/ml9: create mixin bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
Sychic committed Jun 18, 2024
1 parent 65ec87d commit 6a409b6
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package gg.essential.loader.stage2;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;

public class DedicatedJarLoader {
private static final String BASE_URL = System.getProperty(
"essential.download.url",
System.getenv().getOrDefault("ESSENTIAL_DOWNLOAD_URL", "https://api.essential.gg/mods")
);
private static final String VERSION_URL = BASE_URL + "/v1/essential:essential-pinned/versions/stable/platforms/%s";
private static final String DOWNLOAD_URL = VERSION_URL + "/download";

protected static void downloadDedicatedJar(LoaderUI ui, Path modsDir, String gameVersion) throws IOException {
final JsonObject meta = getEssentialDownloadMeta(gameVersion);
final URL url = new URL(meta.get("url").getAsString());
final URLConnection connection = url.openConnection();

ui.setDownloadSize(connection.getContentLength());

final String essentialVersion = getEssentialVersionMeta(gameVersion).get("version").getAsString();
final Path target = modsDir.resolve(String.format("Essential %s (%s).jar", gameVersion, essentialVersion));

try (
final InputStream in = connection.getInputStream();
final OutputStream out = Files.newOutputStream(target);
) {

final byte[] buffer = new byte[1024];
int totalRead = 0;
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
totalRead += read;
ui.setDownloaded(totalRead);
}
}
}

private static JsonObject getEssentialMeta(URL url) throws IOException {
String response;
try (final InputStream in = url.openStream()) {
response = new String(in.readAllBytes());
}
JsonElement json = new JsonParser().parse(response);
return json.getAsJsonObject();
}

private static JsonObject getEssentialVersionMeta(String gameVersion) throws IOException {
return getEssentialMeta(new URL(String.format(VERSION_URL, gameVersion)));
}

private static JsonObject getEssentialDownloadMeta(String gameVersion) throws IOException {
return getEssentialMeta(new URL(String.format(DOWNLOAD_URL, gameVersion)));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package gg.essential.loader.stage2;

import cpw.mods.modlauncher.api.ITransformationService;
import gg.essential.loader.stage2.jvm.ForkedJvmLoaderSwingUI;
import net.minecraftforge.fml.loading.FMLLoader;

import java.io.IOException;
import java.nio.file.Path;

/**
Expand All @@ -26,4 +29,20 @@ public ITransformationService getTransformationService() {
public void load() {
// delayed until ModLauncher exposes the MC version
}

@SuppressWarnings("unused") // called via reflection from stage1
public void loadFromMixin(Path gameDir) throws IOException {
final Path modsDir = gameDir.resolve("mods");
LoaderUI ui = LoaderUI.all(
new LoaderLoggingUI().updatesEveryMillis(1000),
new ForkedJvmLoaderSwingUI().updatesEveryMillis(1000 / 60)
);
ui.start();
DedicatedJarLoader.downloadDedicatedJar(ui, modsDir, "forge_" + FMLLoader.versionInfo().mcVersion());
ui.complete();
RestartUI restartUI = new RestartUI("Restart Required!", "One of the mods you have installed requires Essential. To complete the installation process, please restart.");
restartUI.show();
restartUI.waitForClose();
System.exit(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package gg.essential.loader.stage2;

import gg.essential.loader.stage2.components.EssentialStyle;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static gg.essential.loader.stage2.components.ButtonShadowBorder.X_SHADOW;
import static gg.essential.loader.stage2.components.ButtonShadowBorder.Y_SHADOW;

public class RestartUI implements EssentialStyle {
private final CompletableFuture<Boolean> closedFuture = new CompletableFuture<>();

private final JFrame frame = makeFrame(it -> closedFuture.complete(null));

private final String title;
private final String description;

public RestartUI(String title, String description) {
this.title = title;
this.description = description;
}

public void show() {
final List<JLabel> htmlLabels = new ArrayList<>();

final JPanel content = makeContent(frame);
content.setBorder(new EmptyBorder(0, 60 - X_SHADOW, 0, 60 - X_SHADOW));
content.add(Box.createHorizontalStrut(CONTENT_WIDTH));

htmlLabels.add(makeTitle(content, html(centered(title))));

final JLabel explanation = new JLabel(html(centered(description)), SwingConstants.CENTER);
explanation.setMaximumSize(new Dimension(CONTENT_WIDTH, Integer.MAX_VALUE));
explanation.setForeground(COLOR_FOREGROUND);
explanation.setAlignmentX(Container.CENTER_ALIGNMENT);
if (Fonts.medium != null) {
explanation.setFont(Fonts.medium.deriveFont(16F));
}
content.add(explanation);
htmlLabels.add(explanation);

content.add(Box.createVerticalStrut(32 - Y_SHADOW));

final JPanel buttons = new JPanel();
buttons.setOpaque(false);
buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
buttons.add(makeButton("Restart", COLOR_PRIMARY_BUTTON, COLOR_BUTTON_HOVER, () -> closedFuture.complete(true)));
content.add(buttons);

content.add(Box.createVerticalStrut(32 - Y_SHADOW));

frame.pack();

htmlLabels.forEach(this::fixJLabelHeight);
frame.pack();

frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public Boolean waitForClose() {
Boolean verdict = closedFuture.join();
close();
return verdict;
}

public void close() {
frame.dispose();
}

public static void main(String[] args) {
RestartUI ui = new RestartUI("Restart required!", "A restart is required for something.");
ui.show();
System.out.println(ui.waitForClose());
}
}

0 comments on commit 6a409b6

Please sign in to comment.