aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java18
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/exceptions/DungeonsGuideUnloadingException.java1
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java2
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/BranchButton.java44
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/TriConsumer.java24
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranch.java126
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranchVersion.java122
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseVersion.java76
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfo.java73
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfoRemote.java51
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Column.java6
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Slot.java3
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/AnnotatedImportOnlyWidget.java2
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DevEnvLoader.java8
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java1
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java12
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java11
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java12
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchButton.gui22
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchList.gui25
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchVersionList.gui52
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionChooser.gui62
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionInfo.gui62
23 files changed, 795 insertions, 20 deletions
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
index 6039823b..577e1eb5 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
@@ -21,14 +21,16 @@ package kr.syeyoung.dungeonsguide.launcher;
import kr.syeyoung.dungeonsguide.launcher.auth.AuthManager;
import kr.syeyoung.dungeonsguide.launcher.branch.UpdateRetrieverUtil;
import kr.syeyoung.dungeonsguide.launcher.exceptions.*;
-import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiChooseVersion;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiDisplayer;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiUnloadingError;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.version.WidgetChooseVersion;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotificationAutoClose;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.GuiScreenAdapter;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.GlobalHUDScale;
import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.richtext.fonts.DefaultFontRenderer;
import kr.syeyoung.dungeonsguide.launcher.loader.*;
import kr.syeyoung.dungeonsguide.launcher.util.ProgressStateHolder;
@@ -102,7 +104,7 @@ public class Main
.titleColor(0xFFFF0000)
.description("Click to try reloading....")
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiChooseVersion(new RuntimeException("just unloaded")));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetChooseVersion())));
})
.build()));
@@ -114,7 +116,7 @@ public class Main
tryReloading(idgLoader);
} catch (NoSuitableLoaderFoundException | NoVersionFoundException e) {
e.printStackTrace();
- GuiDisplayer.INSTANCE.displayGui(new GuiChooseVersion(e));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetChooseVersion())));
}
}
@@ -166,7 +168,7 @@ public class Main
.titleColor(0xFFFF0000)
.description("Click to try reloading....")
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiChooseVersion(new RuntimeException("just unloaded")));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetChooseVersion())));
})
.build()));
try {
@@ -189,8 +191,8 @@ public class Main
currentLoader = newLoader;
try {
dgInterface.init(configDir);
- } catch (Exception e) {
- throw new DungeonsGuideLoadingException("Exception occurred while calling init", e);
+ } catch (Throwable e) {
+ throw new DungeonsGuideLoadingException("Exception occurred while calling init\nInfo: "+currentLoader.toString(), e);
}
for (DungeonsGuideReloadListener listener : listeners) {
listener.onLoad(dgInterface);
@@ -289,7 +291,9 @@ public class Main
main = this;
dgInterface = null;
currentLoader = null;
- configDir = preInitializationEvent.getModConfigurationDirectory();
+ configDir = new File(preInitializationEvent.getModConfigurationDirectory().getAbsolutePath(), "dungeonsguide");
+ if (!configDir.exists())
+ configDir.mkdirs();
// setup preinit progress bar for well, progress bar!
ProgressManager.ProgressBar bar = ProgressManager.push("DungeonsGuide", 1);
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/exceptions/DungeonsGuideUnloadingException.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/exceptions/DungeonsGuideUnloadingException.java
index 78beeaa7..2c651314 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/exceptions/DungeonsGuideUnloadingException.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/exceptions/DungeonsGuideUnloadingException.java
@@ -21,4 +21,5 @@ package kr.syeyoung.dungeonsguide.launcher.exceptions;
public class DungeonsGuideUnloadingException extends Exception {
public DungeonsGuideUnloadingException(String message) {super(message);}
public DungeonsGuideUnloadingException(Throwable cause) {super(cause);}
+ public DungeonsGuideUnloadingException(String message, Throwable cause) {super(message, cause);}
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java
index fc5e569e..1ac4556b 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java
@@ -45,7 +45,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class WidgetPrivacyPolicy extends AnnotatedImportOnlyWidget {
- private static final ExecutorService executor = Executors.newSingleThreadExecutor();
+ public static final ExecutorService executor = Executors.newSingleThreadExecutor();
@Bind(variableName = "policy")
public final BindableAttribute<Widget> policy = new BindableAttribute<>(Widget.class);
@Bind(variableName = "policyVisibility")
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/BranchButton.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/BranchButton.java
new file mode 100644
index 00000000..c14d9b94
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/BranchButton.java
@@ -0,0 +1,44 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+
+public class BranchButton extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "branch")
+ public final BindableAttribute<String> branch = new BindableAttribute<>(String.class);
+ private final Runnable onClick;
+ public BranchButton(String branch, Runnable onClick) {
+ super(new ResourceLocation("dungeons_guide_loader:gui/versions/branchButton.gui"));
+ this.branch.setValue(branch);
+ this.onClick = onClick;
+ }
+
+ @On(functionName = "click")
+ public void click() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ this.onClick.run();
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/TriConsumer.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/TriConsumer.java
new file mode 100644
index 00000000..14050466
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/TriConsumer.java
@@ -0,0 +1,24 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+@FunctionalInterface
+public interface TriConsumer<A,B,C> {
+ void accept(A a, B b, C c);
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranch.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranch.java
new file mode 100644
index 00000000..a78bffc4
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranch.java
@@ -0,0 +1,126 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateBranch;
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateRetrieverUtil;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetPrivacyPolicy;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.Column;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.Text;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.data.WidgetList;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.client.gui.GuiButton;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+public class WidgetChooseBranch extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "versionListVisibility")
+ public final BindableAttribute<String> visibility = new BindableAttribute<>(String.class, "loading");
+ @Bind(variableName = "versionList")
+ public final BindableAttribute<Column> versionList = new BindableAttribute<>(Column.class);
+
+ @Bind(variableName = "widgetList")
+ public final BindableAttribute<List<Widget>> widgetList = new BindableAttribute(WidgetList.class);
+
+ public Consumer<UpdateBranch> onBranchChoose;
+ public Runnable onLocalChoose;
+ public Runnable onJarChoose;
+
+ public WidgetChooseBranch(Consumer<UpdateBranch> onBranch, Runnable onLocal, Runnable onJar) {
+ super(new ResourceLocation("dungeons_guide_loader:gui/versions/branchList.gui"));
+ this.onBranchChoose = onBranch;
+ this.onLocalChoose = onLocal;
+ this.onJarChoose = onJar;
+ widgetList.setValue(new ArrayList<>());
+ reload0();
+ }
+
+ @On(functionName = "reload")
+ public void reload() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ reload0();
+ }
+
+ private volatile boolean isLoading = false;
+ private void reload0() {
+ if (isLoading) return;
+ isLoading = true;
+ visibility.setValue("loading");
+ WidgetPrivacyPolicy.executor.submit(() -> {
+ try {
+ List<Widget> widgets = new ArrayList<>();
+ if (this.getClass().getResource("/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.class") != null)
+ widgets.add(new BranchButton("Local", () -> {
+ onLocalChoose.run();
+ }));
+ if (this.getClass().getResource("/mod.jar") != null)
+ widgets.add(new BranchButton("Jar", () -> {
+ onJarChoose.run();
+ }));
+
+ try {
+ List<UpdateBranch> branches = UpdateRetrieverUtil.getUpdateBranches().stream()
+ .filter(updateBranch ->
+ Optional.ofNullable(updateBranch.getMetadata())
+ .filter(a -> a.has("additionalMeta"))
+ .map(a -> a.getJSONObject("additionalMeta"))
+ .filter(a -> a.has("type"))
+ .map(a -> a.getString("type")).orElse("").equals("mod"))
+ .collect(Collectors.toList());
+ for (UpdateBranch branch : branches) {
+ widgets.add(new BranchButton("Remote: "+branch.getName(), () -> {
+ onBranchChoose.accept(branch);
+ }));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ widgets.add(new Text("Remote Error", 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0, 8.0));
+ }
+ if (widgets.isEmpty()) {
+ widgets.add(new Text("Seems Empty", 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0, 8.0));
+ }
+
+ widgetList.setValue(widgets);
+ if (versionList.getValue().getDomElement().getWidget() != null) {
+ versionList.getValue().removeAll();
+ for (Widget widget : widgets) {
+ versionList.getValue().addWidget(widget);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ visibility.setValue("loaded");
+ isLoading = false;
+ }
+ });
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranchVersion.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranchVersion.java
new file mode 100644
index 00000000..3a393adf
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseBranchVersion.java
@@ -0,0 +1,122 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.branch.Update;
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateBranch;
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateRetrieverUtil;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetPrivacyPolicy;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.Column;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.Text;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.data.WidgetList;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+public class WidgetChooseBranchVersion extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "versionListVisibility")
+ public final BindableAttribute<String> visibility = new BindableAttribute<>(String.class, "loading");
+ @Bind(variableName = "versionList")
+ public final BindableAttribute<Column> versionList = new BindableAttribute<>(Column.class);
+
+ @Bind(variableName = "widgetList")
+ public final BindableAttribute<List<Widget>> widgetList = new BindableAttribute(WidgetList.class);
+ @Bind(variableName = "branch")
+ public final BindableAttribute<String> branchName = new BindableAttribute<>(String.class);
+
+ public TriConsumer<UpdateBranch, Update, Boolean> onVersionChoose;
+ private UpdateBranch branch;
+
+ @Bind(variableName = "back")
+ public final BindableAttribute<Runnable> back = new BindableAttribute<>(Runnable.class);
+
+ public WidgetChooseBranchVersion(TriConsumer<UpdateBranch, Update, Boolean> onVersion, UpdateBranch branch, Runnable back) {
+ super(new ResourceLocation("dungeons_guide_loader:gui/versions/branchVersionList.gui"));
+ this.onVersionChoose = onVersion;
+ this.branch = branch;
+ this.branchName.setValue(branch.getName());
+ this.back.setValue(back);
+
+ widgetList.setValue(new ArrayList<>());
+ reload0();
+ }
+
+ @On(functionName = "reload")
+ public void reload() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ reload0();
+ }
+
+ private volatile boolean isLoading = false;
+ private void reload0() {
+ if (isLoading) return;
+ isLoading = true;
+ visibility.setValue("loading");
+ WidgetPrivacyPolicy.executor.submit(() -> {
+ try {
+ List<Widget> widgets = new ArrayList<>();
+ try {
+ List<Update> branches = UpdateRetrieverUtil.getLatestUpdates(branch.getId(), 0);
+ if (!branches.isEmpty()) {
+ widgets.add(new BranchButton("Latest", () -> {
+ onVersionChoose.accept(branch, branches.get(0), true);
+ }));
+ }
+
+ for (Update update : branches) {
+ widgets.add(new BranchButton(update.getName(), () -> {
+ onVersionChoose.accept(branch, update, false);
+ }));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ widgets.add(new Text("Remote Error", 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0, 8.0));
+ }
+ if (widgets.isEmpty()) {
+ widgets.add(new Text("Seems Empty", 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0, 8.0));
+ }
+
+ widgetList.setValue(widgets);
+ if (versionList.getValue().getDomElement().getWidget() != null) {
+ versionList.getValue().removeAll();
+ for (Widget widget : widgets) {
+ versionList.getValue().addWidget(widget);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ visibility.setValue("loaded");
+ isLoading = false;
+ }
+ });
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseVersion.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseVersion.java
new file mode 100644
index 00000000..b62cd91f
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetChooseVersion.java
@@ -0,0 +1,76 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.branch.Update;
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateBranch;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Export;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+
+public class WidgetChooseVersion extends AnnotatedImportOnlyWidget {
+
+ @Bind(variableName = "branchWidget")
+ public final BindableAttribute<Widget> branchWidget = new BindableAttribute<>(Widget.class, new WidgetChooseBranch(this::branch, this::local, this::jar));
+ @Bind(variableName = "versionWidget")
+ public final BindableAttribute<Widget> versionWidget = new BindableAttribute<>(Widget.class);
+
+ @Bind(variableName = "listVisibility")
+ public final BindableAttribute<String> listVisibility = new BindableAttribute<>(String.class, "branch");
+ @Bind(variableName = "infoVisibility")
+ public final BindableAttribute<String> infoVisibility = new BindableAttribute<>(String.class, "hide");
+
+ @Bind(variableName = "infoWidget")
+ public final BindableAttribute<Widget> infoWidget = new BindableAttribute<>(Widget.class);
+ private void back() {
+ listVisibility.setValue("branch");
+ }
+
+ private void jar() {
+ }
+
+ private void local() {
+ }
+
+ private void remote(UpdateBranch branch, Update update, boolean isLatest) {
+ infoWidget.setValue(new WidgetInfoRemote(branch, update, isLatest));
+ infoVisibility.setValue("show");
+ }
+
+ private void branch(UpdateBranch updateBranch) {
+ versionWidget.setValue(new WidgetChooseBranchVersion(this::remote, updateBranch, this::back));
+ listVisibility.setValue("version");
+ }
+
+ public WidgetChooseVersion() {
+ super(new ResourceLocation("dungeons_guide_loader:gui/versions/versionChooser.gui"));
+ }
+
+ @On(functionName = "exit")
+ public void exit() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ Minecraft.getMinecraft().displayGuiScreen(null);
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfo.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfo.java
new file mode 100644
index 00000000..7196c5e2
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfo.java
@@ -0,0 +1,73 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.Main;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.launcher.loader.IDGLoader;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.config.Configuration;
+
+import java.io.File;
+
+public abstract class WidgetInfo extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "default")
+ public final BindableAttribute<Boolean> makeItDefault = new BindableAttribute<>(Boolean.class, true);
+ @Bind(variableName = "updatelog")
+ public final BindableAttribute<String> updateLog = new BindableAttribute<>(String.class, "");
+
+ @Bind(variableName = "version")
+ public final BindableAttribute<String> version = new BindableAttribute<>(String.class, "");
+
+ public WidgetInfo() {
+ super(new ResourceLocation("dungeons_guide_loader:gui/versions/versionInfo.gui"));
+ makeItDefault.addOnUpdate((old, neu) ->{
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ });
+ }
+
+ public void setUpdateLog(String log) {
+ updateLog.setValue(log);
+ }
+ public void setVersion(String version) {this.version.setValue(version);}
+
+ public abstract IDGLoader getLoader();
+
+ public void setConfiguration(Configuration configuration) {}
+
+ @On(functionName = "load")
+ public void load() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ IDGLoader idgLoader = getLoader();
+
+ if (makeItDefault.getValue()) {
+ File f = new File(Main.getConfigDir(), "loader.cfg");
+ Configuration configuration = new Configuration(f);
+ configuration.load();
+ setConfiguration(configuration);
+ configuration.save();
+ }
+ // do smth
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfoRemote.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfoRemote.java
new file mode 100644
index 00000000..6b450a67
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/version/WidgetInfoRemote.java
@@ -0,0 +1,51 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen.version;
+
+import kr.syeyoung.dungeonsguide.launcher.branch.Update;
+import kr.syeyoung.dungeonsguide.launcher.branch.UpdateBranch;
+import kr.syeyoung.dungeonsguide.launcher.loader.IDGLoader;
+import net.minecraftforge.common.config.Configuration;
+
+public class WidgetInfoRemote extends WidgetInfo {
+ private UpdateBranch updateBranch;
+ private Update update;
+ private boolean isLatest;
+ public WidgetInfoRemote(UpdateBranch branch, Update update, boolean isLatest) {
+ super();
+ this.updateBranch = branch;
+ this.update = update;
+ this.isLatest = isLatest;
+ setUpdateLog(update.getUpdateLog());
+ this.isLatest = isLatest;
+ setVersion(branch.getName()+"/"+update.getName()+ " ("+branch.getId()+"/"+update.getId()+")");
+ }
+
+ @Override
+ public void setConfiguration(Configuration configuration) {
+ configuration.get("loader", "modsource", "").set("remote");
+ configuration.get("loader", "remoteBranch", "").set(updateBranch.getName());
+ configuration.get("loader", "remoteVersion", "").set(isLatest ? "latest" : update.getName());
+ }
+
+ @Override
+ public IDGLoader getLoader() {
+ return null;
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Column.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Column.java
index 6d618886..5e658718 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Column.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Column.java
@@ -83,6 +83,12 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter {
getDomElement().removeElement(widget.getDomElement());
}
+ public void removeAll() {
+ for (DomElement child : getDomElement().getChildren()) {
+ getDomElement().removeElement(child);
+ }
+ }
+
@Override
public Size layout(DomElement buildContext, ConstraintBox constraints) {
double width = 0;
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Slot.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Slot.java
index d239946b..251d4bbb 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Slot.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Slot.java
@@ -40,7 +40,8 @@ public class Slot extends AnnotatedExportOnlyWidget {
private void update(Widget widget, Widget widget1) {
if (this.getDomElement().getParent() == null) return;
- getDomElement().removeElement(getDomElement().getChildren().get(0));
+ if (!this.getDomElement().getChildren().isEmpty())
+ getDomElement().removeElement(getDomElement().getChildren().get(0));
DomElement domElement = null;
if (replacement.getValue() != null) domElement = replacement.getValue().createDomElement(getDomElement());
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/AnnotatedImportOnlyWidget.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/AnnotatedImportOnlyWidget.java
index 29bcc4ef..8a0fb56d 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/AnnotatedImportOnlyWidget.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/AnnotatedImportOnlyWidget.java
@@ -85,7 +85,7 @@ public abstract class AnnotatedImportOnlyWidget extends Widget implements Import
protected static Map<String, MethodHandle> getInvocationTargets(Class clazz, Object inst) {
Map<String, MethodHandle> invocationTargets = new HashMap<>();
- for (Method declaredMethod : clazz.getDeclaredMethods()) {
+ for (Method declaredMethod : clazz.getMethods()) {
if (declaredMethod.getAnnotation(On.class) != null) {
On on = declaredMethod.getAnnotation(On.class);
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DevEnvLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DevEnvLoader.java
index 4f0fc0be..5b12d23a 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DevEnvLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DevEnvLoader.java
@@ -34,7 +34,7 @@ public class DevEnvLoader implements IDGLoader {
return dgInterface;
} catch (Throwable e) {
- throw new DungeonsGuideLoadingException(e);
+ throw new DungeonsGuideLoadingException(toString(), e);
}
}
@@ -66,4 +66,10 @@ public class DevEnvLoader implements IDGLoader {
public String version() {
return "unknown";
}
+
+
+ @Override
+ public String toString() {
+ return loaderName()+":"+version();
+ }
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
index 52982355..ea555386 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
@@ -21,6 +21,7 @@ package kr.syeyoung.dungeonsguide.launcher.loader;
import kr.syeyoung.dungeonsguide.launcher.DGInterface;
import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideLoadingException;
import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideUnloadingException;
+import net.minecraftforge.common.config.Configuration;
public interface IDGLoader {
DGInterface loadDungeonsGuide() throws DungeonsGuideLoadingException;
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
index 93368801..d428b1b1 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
@@ -81,7 +81,7 @@ public class JarLoader implements IDGLoader {
return dgInterface;
} catch (Throwable e) {
- throw new DungeonsGuideLoadingException(e);
+ throw new DungeonsGuideLoadingException(toString(), e);
} finally {
ProgressStateHolder.pop();
}
@@ -102,7 +102,7 @@ public class JarLoader implements IDGLoader {
} catch (Throwable e) {
dgInterface = null;
ProgressStateHolder.pop();
- throw new DungeonsGuideUnloadingException(e);
+ throw new DungeonsGuideUnloadingException(toString(),e);
}
if (classLoader != null)
classLoader.cleanup();
@@ -111,7 +111,7 @@ public class JarLoader implements IDGLoader {
System.gc();// pls do
Reference<? extends ClassLoader> t = refQueue.poll();
phantomReference = null;
- if (t == null) throw new DungeonsGuideUnloadingException(new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
+ if (t == null) throw new DungeonsGuideUnloadingException(toString(),new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
t.clear();
}
@@ -134,4 +134,10 @@ public class JarLoader implements IDGLoader {
public String version() {
return "unknown"; // maybe read the thing...
}
+
+
+ @Override
+ public String toString() {
+ return loaderName()+":"+version();
+ }
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
index f0e099e4..07748968 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
@@ -74,7 +74,7 @@ public class LocalLoader implements IDGLoader {
return dgInterface;
} catch (Throwable e) {
- throw new DungeonsGuideLoadingException(e);
+ throw new DungeonsGuideLoadingException(toString(), e);
} finally {
ProgressStateHolder.pop();
}
@@ -93,7 +93,7 @@ public class LocalLoader implements IDGLoader {
dgInterface.unload();
} catch (Throwable e) {
dgInterface = null;
- throw new DungeonsGuideUnloadingException(e);
+ throw new DungeonsGuideUnloadingException(toString(),e);
}
if (classLoader != null)
classLoader.cleanup();
@@ -102,7 +102,7 @@ public class LocalLoader implements IDGLoader {
System.gc(); // pls do
Reference<? extends ClassLoader> t = refQueue.poll();
phantomReference = null;
- if (t == null) throw new DungeonsGuideUnloadingException(new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
+ if (t == null) throw new DungeonsGuideUnloadingException(toString(),new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
t.clear();
}
@@ -125,4 +125,9 @@ public class LocalLoader implements IDGLoader {
public String version() {
return "unknown";
}
+
+ @Override
+ public String toString() {
+ return loaderName()+":"+version();
+ }
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java
index 6e26239f..6202c233 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java
@@ -118,7 +118,7 @@ public class RemoteLoader implements IDGLoader {
return dgInterface;
} catch (Throwable e) { // the reason why I am catching throwable here: in case NoClassDefFoundError.
- throw new DungeonsGuideLoadingException("Version: "+branchId+" / "+updateId,e);
+ throw new DungeonsGuideLoadingException(toString(),e);
} finally {
ProgressStateHolder.pop();
}
@@ -137,7 +137,7 @@ public class RemoteLoader implements IDGLoader {
dgInterface.unload();
} catch (Throwable e) {
dgInterface = null;
- throw new DungeonsGuideUnloadingException(e);
+ throw new DungeonsGuideUnloadingException(toString(),e);
}
if (classLoader != null)
classLoader.cleanup();
@@ -147,7 +147,7 @@ public class RemoteLoader implements IDGLoader {
System.gc();// pls do
Reference<? extends ClassLoader> t = refQueue.poll();
phantomReference = null;
- if (t == null) throw new DungeonsGuideUnloadingException(new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
+ if (t == null) throw new DungeonsGuideUnloadingException(toString(),new ReferenceLeakedException("Reference Leaked")); // Why do you have to be that strict? Well, to tell them to actually listen on DungeonsGuideReloadListener. If it starts causing issues then I will remove check cus it's not really loaded (classes are loaded by child classloader)
t.clear();
}
@@ -177,4 +177,10 @@ public class RemoteLoader implements IDGLoader {
public String version() {
return friendlyBranchName+"("+branchId+")@"+friendlyVersionName+"("+updateId+")"; // maybe read the thing...
}
+
+
+ @Override
+ public String toString() {
+ return loaderName()+":"+version();
+ }
}
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchButton.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchButton.gui
new file mode 100644
index 00000000..5ec1b8e6
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchButton.gui
@@ -0,0 +1,22 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+<padding top="5">
+ <size height="15">
+ <RoundButton bind:text="branch" on:click="click"/>
+ </size>
+</padding> \ No newline at end of file
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchList.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchList.gui
new file mode 100644
index 00000000..86f4c6d0
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchList.gui
@@ -0,0 +1,25 @@
+
+<col>
+ <padding top="10" left="10" right="10" bottom="5">
+ <Text text="Available Versions" color="#FFFFFFFF"/>
+ </padding>
+ <flexible>
+ <SelectiveContainer bind:visible="versionListVisibility">
+ <padding left="10" right="10" slot="loading">
+ <align vAlign="CENTER" hAlign="CENTER">
+ <Text text="Loading..." color="#FFFFFFFF"/>
+ </align>
+ </padding>
+ <ScrollablePanel direction="VERTICAL" slot="loaded">
+ <padding left="10" right="10">
+ <col bind:api="versionList" bind:_="widgetList"/>
+ </padding>
+ </ScrollablePanel>
+ </SelectiveContainer>
+ </flexible>
+ <padding left="10" right="10" top="5" bottom="10">
+ <size height="20">
+ <RoundButton text="Reload" on:click="reload"/>
+ </size>
+ </padding>
+</col> \ No newline at end of file
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchVersionList.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchVersionList.gui
new file mode 100644
index 00000000..f1450087
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/branchVersionList.gui
@@ -0,0 +1,52 @@
+
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<col crossAlign="START">
+ <padding left="5" right="10" top="5">
+ <size width="50" height="11">
+ <RoundButton text="Go Back" bind:click="back"/>
+ </size>
+ </padding>
+ <padding top="5" left="10" right="10" bottom="5">
+ <row mainAlign="CENTER">
+ <Text text="Versions (" color="#FFFFFFFF"/>
+ <Text bind:text="branch" color="#FFFFFFFF"/>
+ <Text text=")" color="#FFFFFFFF"/>
+ </row>
+ </padding>
+ <flexible>
+ <SelectiveContainer bind:visible="versionListVisibility">
+ <padding left="10" right="10" slot="loading">
+ <align vAlign="CENTER" hAlign="CENTER">
+ <Text text="Loading..." color="#FFFFFFFF"/>
+ </align>
+ </padding>
+ <ScrollablePanel direction="VERTICAL" slot="loaded">
+ <padding left="10" right="10">
+ <col bind:api="versionList" bind:_="widgetList"/>
+ </padding>
+ </ScrollablePanel>
+ </SelectiveContainer>
+ </flexible>
+ <padding left="10" right="10" top="5" bottom="10">
+ <size height="20">
+ <RoundButton text="Reload" on:click="reload"/>
+ </size>
+ </padding>
+</col> \ No newline at end of file
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionChooser.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionChooser.gui
new file mode 100644
index 00000000..fe0e65b3
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionChooser.gui
@@ -0,0 +1,62 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<bgcolor backgroundColor="#FF111111">
+ <align vAlign="CENTER">
+ <ConstrainedBox maxHeight="450">
+ <col crossAlign="CENTER">
+ <size width="0" height="10"/>
+ <Text text="Please choose a version to load" color="#FFFFFFFF"/>
+ <size width="0" height="10"/>
+ <flexible>
+ <align hAlign="CENTER">
+ <ConstrainedBox maxWidth="600">
+ <padding left="10" right="10">
+ <row>
+ <flexible flex="1">
+ <bgcolor backgroundColor="#FF000000">
+ <SelectiveContainer bind:visible="listVisibility">
+ <slot slot="branch" bind:child="branchWidget"/>
+ <slot slot="version" bind:child="versionWidget"/>
+ </SelectiveContainer>
+ </bgcolor>
+ </flexible>
+ <flexible flex="2">
+ <bgcolor backgroundColor="#FF222222">
+ <SelectiveContainer bind:visible="infoVisibility">
+ <slot slot="show" bind:child="infoWidget"/>
+ <slot slot="hide"/>
+ </SelectiveContainer>
+ </bgcolor>
+ </flexible>
+ </row>
+ </padding>
+ </ConstrainedBox>
+ </align>
+ </flexible>
+ <size width="0" height="15"/>
+ <row mainAlign="CENTER">
+ <size width="200" height="20">
+ <RoundButton text="Play without Dungeons Guide" on:click="exit"/>
+ </size>
+ </row>
+ <size width="0" height="10"/>
+ </col>
+ </ConstrainedBox>
+ </align>
+</bgcolor> \ No newline at end of file
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionInfo.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionInfo.gui
new file mode 100644
index 00000000..cccbefde
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/versions/versionInfo.gui
@@ -0,0 +1,62 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<stack>
+ <align vAlign="END" hAlign="END">
+ <padding right="8" bottom="8">
+ <UnconstrainedBox>
+ <bgcolor backgroundColor="#CC222222">
+ <padding right="3" bottom="3" top="3" left="3">
+ <row mainAlign="END" crossAlign="CENTER">
+ <Text text="Make this version default" color="#FFFFFFFF"/>
+ <size width="5" height="0"/>
+ <size width="40" height="15">
+ <SimpleToggleButton bind:enabled="default"/>
+ </size>
+ <size width="5" height="0"/>
+ <size width="40" height="15">
+ <RoundButton text="Load" on:click="load"/>
+ </size>
+ </row>
+ </padding>
+ </bgcolor>
+ </UnconstrainedBox>
+ </padding>
+ </align>
+ <ScrollablePanel direction="VERTICAL">
+ <padding left="10" top="10" right="10" bottom="10">
+ <col crossAlign="START">
+ <Text text="Version Info" size="16" color="#FFFFFFFF"/>
+ <size width="0" height="5"/>
+ <line color="#FFFFFFFF"/>
+ <size width="0" height="5"/>
+ <row>
+ <Text text="Version: " color="#FFFFFFFF"/>
+ <Text bind:text="version" color="#FFFFFFFF"/>
+ </row>
+ <size width="0" height="10"/>
+ <Text text="Update log" size="16" color="#FFFFFFFF"/>
+ <size width="0" height="5"/>
+ <line color="#FFFFFFFF"/>
+ <size width="0" height="5"/>
+ <Text bind:text="updatelog" color="#FFFFFFFF"/>
+ <size width="0" height="25"/>
+ </col>
+ </padding>
+ </ScrollablePanel>
+</stack> \ No newline at end of file