aboutsummaryrefslogtreecommitdiff
path: root/loader/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'loader/src/main')
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java24
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java7
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java227
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java112
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiUnloadingError.java91
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetError.java73
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/ScrollablePanel.java4
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/richtext/FlatTextSpan.java10
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/error.gui60
9 files changed, 165 insertions, 443 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 577e1eb5..36456dbc 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
@@ -22,8 +22,7 @@ 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.GuiDisplayer;
-import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError;
-import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiUnloadingError;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetError;
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;
@@ -146,11 +145,11 @@ public class Main
unload();
} catch (Exception e2) {
e2.printStackTrace();
- GuiDisplayer.INSTANCE.displayGui(new GuiUnloadingError(e2));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e2))));
}
- GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e))));
} catch (DungeonsGuideUnloadingException e) {
- GuiDisplayer.INSTANCE.displayGui(new GuiUnloadingError(e));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e))));
}
}
@@ -211,17 +210,32 @@ public class Main
}
private volatile IDGLoader reqLoader = null;
+ private volatile boolean unload = false;
public void reloadWithoutStacktraceReference(IDGLoader newLoader) {
reqLoader = newLoader;
}
+ public void unloadWithoutStacktraceReference(IDGLoader newLoader) {
+ unload = true;
+ }
@SubscribeEvent
public void onTick(TickEvent.ClientTickEvent tickEvent) {
if (reqLoader != null) {
IDGLoader loader = reqLoader;
reqLoader = null;
+ unload = false;
tryReloadingWithSplash(loader);
}
+ if (unload) {
+ try {
+ unload();
+ } catch (Exception e2) {
+ e2.printStackTrace();
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e2))));
+ }
+ reqLoader = null;
+ unload = false;
+ }
}
public void reload(IDGLoader newLoader) throws DungeonsGuideLoadingException, DungeonsGuideUnloadingException {
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
index 6f9a2d65..384fe5b2 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
@@ -26,7 +26,7 @@ import kr.syeyoung.dungeonsguide.launcher.exceptions.auth.AuthFailedException;
import kr.syeyoung.dungeonsguide.launcher.exceptions.auth.AuthenticationUnavailableException;
import kr.syeyoung.dungeonsguide.launcher.exceptions.auth.PrivacyPolicyRequiredException;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiDisplayer;
-import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetError;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetPrivacyPolicy;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager;
@@ -41,7 +41,6 @@ import org.apache.logging.log4j.Logger;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
@@ -157,7 +156,7 @@ public class AuthManager {
.description("Authentication Error Occurred\n"+e.getMessage())
.titleColor(0xFFFF0000)
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e))));
})
.build()));
}
@@ -210,7 +209,7 @@ public class AuthManager {
.description("Authentication Error Occurred\n"+e.getMessage())
.titleColor(0xFFFF0000)
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e));
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetError(e))));
})
.build()));
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java
deleted file mode 100644
index e42e45dc..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2022 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;
-
-import kr.syeyoung.dungeonsguide.launcher.LoaderMeta;
-import kr.syeyoung.dungeonsguide.launcher.Main;
-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.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.loader.JarLoader;
-import kr.syeyoung.dungeonsguide.launcher.loader.LocalLoader;
-import kr.syeyoung.dungeonsguide.launcher.loader.RemoteLoader;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.client.config.GuiCheckBox;
-
-import java.awt.*;
-import java.awt.datatransfer.StringSelection;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-public class GuiChooseVersion extends SpecialGuiScreen {
- private static final ExecutorService executor = Executors.newSingleThreadExecutor();
- private Throwable cause;
-
- public GuiChooseVersion(Throwable cause) {
- this.cause = cause;
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream printStream = new PrintStream(byteArrayOutputStream);
- cause.printStackTrace(printStream);
- this.stacktrace = byteArrayOutputStream.toString();
-
- try {
- fetchList();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private void fetchList () throws IOException {
- loading.incrementAndGet();
- executor.submit(() -> {
- try {
- branchList = 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());
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- smthUpdated = true;
- loading.decrementAndGet();
- }
- });
- }
-
- private void fetchUpdates(UpdateBranch branch) throws IOException {
- loading.incrementAndGet();
- executor.submit(() -> {
- try {
- updates = UpdateRetrieverUtil.getLatestUpdates(branch.getId(), 0);
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- smthUpdated = true;
- loading.decrementAndGet();
- }
- });
- }
- private final String stacktrace;
-
- private List<UpdateBranch> branchList = Collections.emptyList();
- private List<Update> updates = Collections.emptyList();
- private UpdateBranch current;
- private volatile boolean smthUpdated = false;
- private volatile AtomicInteger loading = new AtomicInteger(0);
-
- private GuiCheckBox checkBox;
- @Override
- public void initGui() {
- super.initGui();
- // Local version
- // Jar embedded version
- // Remote version
- // dg gui lib....?
-
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- this.buttonList.add(new GuiButton(2, 0,sr.getScaledHeight()-20 ,"Copy Error into Clipboard"));
-
- this.buttonList.add(new GuiButton(3, sr.getScaledWidth()/2-100,sr.getScaledHeight()-40 ,"Play Without DG"));
- GuiButton button;
- int tenth = sr.getScaledWidth()/10;
- this.buttonList.add(button = new GuiButton(0, tenth,90 ,"Try loading Locally (classes)"));
- button.enabled = this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.class") != null;
- this.buttonList.add(button = new GuiButton(1, tenth,110 ,"Try loading Local Jar (embedded jar)"));
- button.enabled = this.getClass().getResourceAsStream("/mod.jar") != null;
- this.buttonList.add(button = new GuiButton(4, tenth,sr.getScaledHeight()-100 ,"Refresh Options"));
-
-// this.buttonList.add(checkBox = new GuiCheckBox(5, sr.getScaledWidth() - tenth-200,sr.getScaledHeight()-100 ,"Save This Loader", false));
-
- int k = 0;
- for (UpdateBranch updateBranch : branchList) {
- this.buttonList.add(new GuiButton(10 + k++, tenth, 110 + 20 * k,"Remote Branch: "+ updateBranch.getName()));
- }
-
- k = 0;
- for (Update update : updates) {
- this.buttonList.add(button = new GuiButton(branchList.size() + 10 + k++, tenth+210, 70+ 20 * k, update.getName()));
- if (update.getMetadata().has("loaderVersion") && update.getMetadata().getInt("loaderVersion") > LoaderMeta.LOADER_VERSION) {
- button.enabled = false;
- }
- }
- }
-
- @Override
- protected void actionPerformed(GuiButton button) throws IOException {
- super.actionPerformed(button);
- if (button.id == 2) {
- Toolkit.getDefaultToolkit()
- .getSystemClipboard()
- .setContents(
- new StringSelection(stacktrace),
- null
- );
-
- UUID random = UUID.randomUUID();
- NotificationManager.getInstance().updateNotification(random,
- new WidgetNotificationAutoClose(random, Notification.builder()
- .title("Successfully Copied!")
- .description("")
- .titleColor(0xFF00FF00)
- .build(), 5000L));
- } else if (button.id == 0) {
- dismiss();
- Main.getMain().tryReloadingWithSplash(new LocalLoader());
- } else if (button.id == 1) {
- dismiss();
- Main.getMain().tryReloadingWithSplash(new JarLoader());
- } else if (button.id == 3) {
- dismiss();
- } else if (button.id == 4) {
- branchList = Collections.emptyList();
- updates = Collections.emptyList();
- current = null;
- smthUpdated = true;
- fetchList();
-// } else if (button.id == 5) {
-// // do smt
- } else if (button.id < branchList.size() + 10) {
- int idx = button.id - 10;
- current = branchList.get(idx);
- fetchUpdates(branchList.get(idx));
- } else if (button.id < branchList.size() + 10 + updates.size()){
- int idx = button.id - branchList.size() - 10;
- Update update = updates.get(idx);
-
- dismiss();
- Main.getMain().tryReloadingWithSplash(new RemoteLoader(current.getName(),current.getId(),update.getId()));
- }
- }
-
- @Override
- public void updateScreen() {
- super.updateScreen();
- if (smthUpdated) {
- this.buttonList.clear();
- initGui();
- smthUpdated = false;
- }
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- super.drawBackground(1);
-
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- fontRenderer.drawString("Please choose a new version to load", (sr.getScaledWidth()-fontRenderer.getStringWidth("Please choose a new version to load"))/2,(int) (40),0xFFFF0000);
- fontRenderer.drawString("Problem: "+cause.getMessage(), (sr.getScaledWidth()-fontRenderer.getStringWidth("Problem: "+cause.getMessage()))/2, (int) (40+fontRenderer.FONT_HEIGHT*1.5),0xFFFF0000);
-
- int tenth = sr.getScaledWidth() / 10;
- Gui.drawRect(tenth, 90,sr.getScaledWidth()-tenth, sr.getScaledHeight()-80, 0xFF5B5B5B);
-
- if (loading.get() > 0) {
- fontRenderer.drawString("Loading", sr.getScaledWidth()/2, sr.getScaledHeight()/2, 0xFF000000);
- }
-
- super.drawScreen(mouseX, mouseY, partialTicks);
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java
deleted file mode 100644
index 9b8390bd..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * 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;
-
-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 net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.common.FMLCommonHandler;
-import org.lwjgl.opengl.GL11;
-
-import java.awt.*;
-import java.awt.datatransfer.StringSelection;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.UUID;
-
-public class GuiLoadingError extends SpecialGuiScreen {
- private final String stacktrace;
- public GuiLoadingError(Throwable cause) {
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream printStream = new PrintStream(byteArrayOutputStream);
- cause.printStackTrace(printStream);
- this.stacktrace = byteArrayOutputStream.toString();
- }
-
- @Override
- public void initGui() {
- super.initGui();
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- this.buttonList.add(new GuiButton(0, sr.getScaledWidth()/2-100,sr.getScaledHeight()-70 ,"Close Minecraft"));
- this.buttonList.add(new GuiButton(1, sr.getScaledWidth()/2-100,sr.getScaledHeight()-40 ,"Play Without DG"));
- this.buttonList.add(new GuiButton(2, 0,sr.getScaledHeight()-20 ,"Copy Error into Clipboard"));
- }
-
- @Override
- protected void actionPerformed(GuiButton button) throws IOException {
- super.actionPerformed(button);
- if (button.id == 0) {
- FMLCommonHandler.instance().exitJava(-1,true);
- } else if (button.id == 1) {
- dismiss();
- } else if (button.id == 2) {
- Toolkit.getDefaultToolkit()
- .getSystemClipboard()
- .setContents(
- new StringSelection(stacktrace),
- null
- );
-
- UUID uuid = UUID.randomUUID();
- NotificationManager.getInstance().updateNotification(uuid, new WidgetNotificationAutoClose(uuid, Notification.builder()
- .title("Successfully Copied!")
- .description("")
- .titleColor(0xFF00FF00)
- .build(), 5000L));
- }
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- super.drawBackground(1);
-
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- fontRenderer.drawString("DungeonsGuide has ran into error while loading itself", (sr.getScaledWidth()-fontRenderer.getStringWidth("DungeonsGuide has ran into error while loading itself"))/2,40,0xFFFF0000);
- fontRenderer.drawString("Please contact DungeonsGuide support with this screen", (sr.getScaledWidth()-fontRenderer.getStringWidth("Please contact developer with this screen"))/2, (int) (40+fontRenderer.FONT_HEIGHT*1.5),0xFFFF0000);
-
- int tenth = sr.getScaledWidth() / 10;
-
- Gui.drawRect(tenth, 70,sr.getScaledWidth()-tenth, sr.getScaledHeight()-80, 0xFF5B5B5B);
- String[] split = stacktrace.split("\n");
- clip(sr, tenth, 70,sr.getScaledWidth()-2*tenth, sr.getScaledHeight()-150);
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- for (int i = 0; i < split.length; i++) {
- fontRenderer.drawString(split[i].replace("\t", " "), tenth+2,i*fontRenderer.FONT_HEIGHT + 72, 0xFFFFFFFF);
- }
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
-
- super.drawScreen(mouseX, mouseY, partialTicks);
- }
-
- public static void clip(ScaledResolution resolution, int x, int y, int width, int height) {
- if (width < 0 || height < 0) return;
-
- int scale = resolution.getScaleFactor();
- GL11.glScissor((x ) * scale, Minecraft.getMinecraft().displayHeight - (y + height) * scale, (width) * scale, height * scale);
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiUnloadingError.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiUnloadingError.java
deleted file mode 100644
index 523c1ce4..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiUnloadingError.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * 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;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraftforge.fml.common.FMLCommonHandler;
-import org.lwjgl.opengl.GL11;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-
-public class GuiUnloadingError extends SpecialGuiScreen {
- private final String stacktrace;
- public GuiUnloadingError(Throwable cause) {
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream printStream = new PrintStream(byteArrayOutputStream);
- cause.printStackTrace(printStream);
- this.stacktrace = byteArrayOutputStream.toString();
- }
-
- @Override
- public void initGui() {
- super.initGui();
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- this.buttonList.add(new GuiButton(0, sr.getScaledWidth()/2-100,sr.getScaledHeight()-70 ,"Close Minecraft"));
- this.buttonList.add(new GuiButton(1, sr.getScaledWidth()/2-100,sr.getScaledHeight()-40 ,"Play With DG in Inconsistent State"));
- }
-
- @Override
- protected void actionPerformed(GuiButton button) throws IOException {
- super.actionPerformed(button);
- if (button.id == 0) {
- FMLCommonHandler.instance().exitJava(-1,true);
- } else if (button.id == 1) {
- dismiss();
- }
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- super.drawBackground(1);
-
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- fontRenderer.drawString("DungeonsGuide has ran into error while reloading", (sr.getScaledWidth()-fontRenderer.getStringWidth("DungeonsGuide has ran into error while reloading"))/2,40,0xFFFF0000);
- fontRenderer.drawString("Please contact DungeonsGuide support with this screen", (sr.getScaledWidth()-fontRenderer.getStringWidth("Please contact developer with this screen"))/2, (int) (40+fontRenderer.FONT_HEIGHT*1.5),0xFFFF0000);
- fontRenderer.drawString("Playing in this state is NOT RECOMMENDED. Undesired behaviors might occur.", (sr.getScaledWidth()-fontRenderer.getStringWidth("Playing in this state is NOT RECOMMENDED. Undesired behaviors might occur."))/2, (int) (40+fontRenderer.FONT_HEIGHT*3),0xFFFF0000);
-
- int tenth = sr.getScaledWidth() / 10;
-
- Gui.drawRect(tenth, 90,sr.getScaledWidth()-tenth, sr.getScaledHeight()-80, 0xFF5B5B5B);
- String[] split = stacktrace.split("\n");
- clip(sr, tenth, 90,sr.getScaledWidth()-2*tenth, sr.getScaledHeight()-150);
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- for (int i = 0; i < split.length; i++) {
- fontRenderer.drawString(split[i].replace("\t", " "), tenth+2,i*fontRenderer.FONT_HEIGHT + 92, 0xFFFFFFFF);
- }
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
-
- super.drawScreen(mouseX, mouseY, partialTicks);
- }
-
- public static void clip(ScaledResolution resolution, int x, int y, int width, int height) {
- if (width < 0 || height < 0) return;
-
- int scale = resolution.getScaleFactor();
- GL11.glScissor((x ) * scale, Minecraft.getMinecraft().displayHeight - (y + height) * scale, (width) * scale, height * scale);
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetError.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetError.java
new file mode 100644
index 00000000..0fe4b6a0
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetError.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;
+
+import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification;
+import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager;
+import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotificationAutoClose;
+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;
+
+import java.awt.*;
+import java.awt.datatransfer.StringSelection;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.UUID;
+
+public class WidgetError extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "stacktrace")
+ public final BindableAttribute<String> stacktrace = new BindableAttribute<>(String.class);
+
+ public WidgetError(Throwable cause) {
+ super(new ResourceLocation("dungeons_guide_loader:gui/error.gui"));
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(byteArrayOutputStream);
+ cause.printStackTrace(printStream);
+ this.stacktrace.setValue(byteArrayOutputStream.toString().replace("\t", " "));
+ }
+
+ @On(functionName = "continue")
+ public void exit() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ Minecraft.getMinecraft().displayGuiScreen(null);
+ }
+ @On(functionName = "copy")
+ public void copy() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ Toolkit.getDefaultToolkit()
+ .getSystemClipboard()
+ .setContents(
+ new StringSelection(stacktrace.getValue()),
+ null
+ );
+
+ UUID uuid = UUID.randomUUID();
+ NotificationManager.getInstance().updateNotification(uuid, new WidgetNotificationAutoClose(uuid, Notification.builder()
+ .title("Successfully Copied!")
+ .description("")
+ .titleColor(0xFF00FF00)
+ .build(), 5000L));
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/ScrollablePanel.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/ScrollablePanel.java
index 523a880b..4bb125c0 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/ScrollablePanel.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/ScrollablePanel.java
@@ -121,13 +121,13 @@ public class ScrollablePanel extends AnnotatedWidget {
if (direction.getValue().vertical) {
double old = this.y.getValue(), neu;
this.y.setValue(
- neu = Layouter.clamp(this.y.getValue() + scrollAmount,0, contentHeight.getValue())
+ neu = Layouter.clamp(this.y.getValue() - scrollAmount,0, contentHeight.getValue())
);
return old != neu;
} else if (direction.getValue().horizontal) {
double old = this.x.getValue(), neu;
this.x.setValue(
- neu = Layouter.clamp(this.x.getValue() + scrollAmount,0, contentWidth.getValue())
+ neu = Layouter.clamp(this.x.getValue() - scrollAmount,0, contentWidth.getValue())
);
return old != neu;
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/richtext/FlatTextSpan.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/richtext/FlatTextSpan.java
index f0a93ed7..4692df8d 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/richtext/FlatTextSpan.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/richtext/FlatTextSpan.java
@@ -58,6 +58,7 @@ public class FlatTextSpan {
int endIdx = value.length;
boolean lineBroken = false;
+ boolean wasNewLine = false;
for (int i = 0; i < value.length; i++) {
char character = value[i];
charWidth = textStyle.getFontRenderer().getWidth(character, textStyle);
@@ -83,6 +84,7 @@ public class FlatTextSpan {
if (character == '\n') {
endIdx = i+1;
lineBroken = true;
+ wasNewLine = true;
break;
}
@@ -120,7 +122,8 @@ public class FlatTextSpan {
char[] second = null;
if (lineBroken) {
int startRealWord = -1;
- for (int i = endIdx; i< value.length; i++) {
+ if (wasNewLine) startRealWord = endIdx;
+ else for (int i = endIdx; i< value.length; i++) {
if (value[i] == ' ') continue;
startRealWord = i;
break;
@@ -150,6 +153,7 @@ public class FlatTextSpan {
double totalWidth = 0;
double effectiveWidth = 0;
boolean lineBroken =false;
+ boolean wasNewLine = false;
int endIdx = value.length;
for (int i = 0; i < value.length; i++) {
@@ -162,6 +166,7 @@ public class FlatTextSpan {
// Force break.
endIdx = i + 1;
lineBroken = true;
+ wasNewLine = true;
break;
}
@@ -180,7 +185,8 @@ public class FlatTextSpan {
char[] second = null;
if (lineBroken) {
int startRealWord = -1;
- for (int i = endIdx; i< value.length; i++) {
+ if (wasNewLine) startRealWord = endIdx;
+ else for (int i = endIdx; i< value.length; i++) {
if (value[i] == ' ') continue;
startRealWord = i;
break;
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/error.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/error.gui
new file mode 100644
index 00000000..b99946b3
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/error.gui
@@ -0,0 +1,60 @@
+<!--
+ ~ 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">
+ <stack>
+ <align hAlign="START" vAlign="END">
+ <size width="100" height="20">
+ <RoundButton text="Copy Log" on:click="copy"/>
+ </size>
+ </align>
+ <align vAlign="CENTER">
+ <ConstrainedBox maxHeight="450">
+ <col crossAlign="CENTER">
+ <size width="0" height="10"/>
+ <Text text="Dungeons Guide has ran into error while loading or unloading" color="#FFFFFFFF"/>
+ <size width="0" height="10"/>
+ <flexible>
+ <align hAlign="CENTER">
+ <padding left="10" right="10">
+ <border>
+ <line slot="left" dir="VERTICAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="top" dir="HORIZONTAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="bottom" dir="HORIZONTAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="right" dir="VERTICAL" thickness="1.0" color="#FFFFFFFF"/>
+ <ConstrainedBox maxWidth="600" slot="content">
+ <bgcolor backgroundColor="#FF222222">
+ <ScrollablePanel>
+ <Text bind:text="stacktrace" color="#FFFFFFFF"/>
+ </ScrollablePanel>
+ </bgcolor>
+ </ConstrainedBox>
+ </border>
+ </padding>
+ </align>
+ </flexible>
+ <size width="0" height="15"/>
+ <size width="100" height="20">
+ <RoundButton text="Continue" on:click="continue"/>
+ </size>
+ <size width="0" height="10"/>
+ </col>
+ </ConstrainedBox>
+ </align>
+ </stack>
+</bgcolor> \ No newline at end of file