aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrashRecoveryPage.java147
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java137
2 files changed, 249 insertions, 35 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrashRecoveryPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrashRecoveryPage.java
new file mode 100644
index 00000000..d68f4a26
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrashRecoveryPage.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2024 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.profileviewer;
+
+import io.github.moulberry.moulconfig.internal.ClipboardUtils;
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
+import io.github.moulberry.notenoughupdates.util.Rectangle;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import lombok.val;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.crash.CrashReport;
+import net.minecraft.init.Bootstrap;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+
+public class CrashRecoveryPage extends GuiProfileViewerPage {
+ private final Exception exception;
+ private final String timestamp;
+ private final GuiProfileViewer.ProfileViewerPage lastViewedPage;
+ private int offset = 0;
+ private final CrashReport crashReport;
+
+ public CrashRecoveryPage(
+ GuiProfileViewer instance,
+ Exception exception,
+ GuiProfileViewer.ProfileViewerPage lastViewedPage
+ ) {
+ super(instance);
+ this.lastViewedPage = lastViewedPage;
+ this.timestamp = DateTimeFormatter.ISO_ZONED_DATE_TIME.format(OffsetDateTime.ofInstant(
+ Instant.now(),
+ ZoneId.systemDefault()
+ ));
+ this.exception = exception;
+ val profile = GuiProfileViewer.getProfile();
+ crashReport = new CrashReport("NEU Profile Viewer crashed", exception);
+ val parameters = crashReport.makeCategory("Profile Viewer Parameters");
+
+ parameters.addCrashSection("Viewed Player", (profile == null ? "null" : profile.getUuid()));
+ parameters.addCrashSection("Viewed Profile", GuiProfileViewer.getProfileName());
+ parameters.addCrashSection("Timestamp", timestamp);
+ parameters.addCrashSection("Last Viewed Page", lastViewedPage);
+ Bootstrap.printToSYSOUT(crashReport.getCompleteReport());
+ }
+
+ @Override
+ public void drawPage(int mouseX, int mouseY, float partialTicks) {
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(
+ GuiProfileViewer.getGuiLeft() + getInstance().sizeX / 2f,
+ GuiProfileViewer.getGuiTop() + 20,
+ 0
+ );
+ offset = 20;
+
+ drawTitle();
+
+ drawString("§cLooked like your profile viewer crashed.");
+ drawString("§cPlease immediately send a screenshot of this screen into #neu-support.");
+ drawString("§cJoin our support server at §adiscord.gg/moulberry§c.");
+
+ val profile = GuiProfileViewer.getProfile();
+ drawString("Viewed Player: " + (profile == null ? "null" : profile.getUuid()));
+ drawString("Viewed Profile: " + GuiProfileViewer.getProfileName());
+ drawString("Timestamp: " + timestamp);
+
+ drawString("");
+ drawString(exception.toString());
+ for (StackTraceElement stackTraceElement : exception.getStackTrace()) {
+ if (offset >= getInstance().sizeY - 50) break;
+ drawString(stackTraceElement.toString());
+ }
+
+ GlStateManager.popMatrix();
+
+ val buttonCoords = getButtonCoordinates();
+ RenderUtils.drawFloatingRectWithAlpha(
+ buttonCoords.getX(), buttonCoords.getY(),
+ buttonCoords.getWidth(), buttonCoords.getHeight(),
+ 100, true
+ );
+ Utils.drawStringCenteredScaledMaxWidth(
+ "Copy Report",
+ buttonCoords.getCenterX(),
+ buttonCoords.getCenterY(),
+ false,
+ buttonCoords.getWidth(),
+ -1
+ );
+
+ }
+
+ @Override
+ public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
+ if (getButtonCoordinates().contains(mouseX, mouseY) && mouseButton == 0) {
+ ClipboardUtils.copyToClipboard(crashReport.getCompleteReport());
+ }
+ return super.mouseClicked(mouseX, mouseY, mouseButton);
+ }
+
+ private Rectangle getButtonCoordinates() {
+ return new Rectangle(
+ GuiProfileViewer.getGuiLeft() + getInstance().sizeX / 2 - 40,
+ GuiProfileViewer.getGuiTop() + getInstance().sizeY - 30,
+ 80, 12
+ );
+ }
+
+ private void drawString(String text) {
+ Utils.drawStringCenteredScaledMaxWidth(text, 0, 0, false, getInstance().sizeX - 20, -1);
+ val spacing = Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT + 2;
+ GlStateManager.translate(0, spacing, 0);
+ offset += spacing;
+ }
+
+ private void drawTitle() {
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(2, 2, 2);
+ Utils.drawStringCenteredScaledMaxWidth("§cKA-BOOM!", 0, 0, false, getInstance().sizeX / 2, -1);
+ GlStateManager.popMatrix();
+ val spacing = Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT * 2 + 6;
+ GlStateManager.translate(0, spacing, 0);
+ offset += spacing;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index f3c96854..6a734958 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -32,7 +32,9 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight;
import io.github.moulberry.notenoughupdates.util.AsyncDependencyLoader;
import io.github.moulberry.notenoughupdates.util.PronounDB;
+import io.github.moulberry.notenoughupdates.util.UrsaClient;
import io.github.moulberry.notenoughupdates.util.Utils;
+import lombok.val;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.gui.GuiScreen;
@@ -199,23 +201,28 @@ public class GuiProfileViewer extends GuiScreen {
playerNameTextField = new GuiElementTextField(displayname, GuiElementTextField.SCALE_TEXT);
playerNameTextField.setSize(100, 20);
- if (currentPage == ProfileViewerPage.LOADING) {
+ if (currentPage.isTransient()) {
currentPage = ProfileViewerPage.BASIC;
}
- pages.put(ProfileViewerPage.BASIC, new BasicPage(this));
- pages.put(ProfileViewerPage.DUNGEON, new DungeonPage(this));
- pages.put(ProfileViewerPage.EXTRA, new ExtraPage(this));
- pages.put(ProfileViewerPage.INVENTORIES, new InventoriesPage(this));
- pages.put(ProfileViewerPage.COLLECTIONS, new CollectionsPage(this));
- pages.put(ProfileViewerPage.PETS, new PetsPage(this));
- pages.put(ProfileViewerPage.MINING, new MiningPage(this));
- pages.put(ProfileViewerPage.BINGO, new BingoPage(this));
- pages.put(ProfileViewerPage.TROPHY_FISH, new TrophyFishPage(this));
- pages.put(ProfileViewerPage.BESTIARY, new BestiaryPage(this));
- pages.put(ProfileViewerPage.CRIMSON_ISLE, new CrimsonIslePage(this));
- pages.put(ProfileViewerPage.MUSEUM, new MuseumPage(this));
- pages.put(ProfileViewerPage.RIFT, new RiftPage(this));
+ try {
+ pages.put(ProfileViewerPage.BASIC, new BasicPage(this));
+ pages.put(ProfileViewerPage.DUNGEON, new DungeonPage(this));
+ pages.put(ProfileViewerPage.EXTRA, new ExtraPage(this));
+ pages.put(ProfileViewerPage.INVENTORIES, new InventoriesPage(this));
+ pages.put(ProfileViewerPage.COLLECTIONS, new CollectionsPage(this));
+ pages.put(ProfileViewerPage.PETS, new PetsPage(this));
+ pages.put(ProfileViewerPage.MINING, new MiningPage(this));
+ pages.put(ProfileViewerPage.BINGO, new BingoPage(this));
+ pages.put(ProfileViewerPage.TROPHY_FISH, new TrophyFishPage(this));
+ pages.put(ProfileViewerPage.BESTIARY, new BestiaryPage(this));
+ pages.put(ProfileViewerPage.CRIMSON_ISLE, new CrimsonIslePage(this));
+ pages.put(ProfileViewerPage.MUSEUM, new MuseumPage(this));
+ pages.put(ProfileViewerPage.RIFT, new RiftPage(this));
+ } catch (Exception ex) {
+ pages.put(ProfileViewerPage.CRASH_RECOVERY, new CrashRecoveryPage(this, ex, currentPage));
+ currentPage = ProfileViewerPage.CRASH_RECOVERY;
+ }
}
public static int getGuiLeft() {
@@ -244,15 +251,17 @@ public class GuiProfileViewer extends GuiScreen {
if (startTime == 0) startTime = currentTime;
ProfileViewerPage page = currentPage;
- if (profile == null) {
- page = ProfileViewerPage.INVALID_NAME;
- } else if (profile.getOrLoadSkyblockProfiles(null) == null) {
- page = ProfileViewerPage.LOADING;
- }
+ if (page == ProfileViewerPage.CRASH_RECOVERY) {
+ if (profile == null) {
+ page = ProfileViewerPage.INVALID_NAME;
+ } else if (profile.getOrLoadSkyblockProfiles(null) == null) {
+ page = ProfileViewerPage.LOADING;
+ }
- if (profile != null && profile.getLatestProfileName() == null &&
- !profile.getUpdatingSkyblockProfilesState().get()) {
- page = ProfileViewerPage.NO_SKYBLOCK;
+ if (profile != null && profile.getLatestProfileName() == null &&
+ !profile.getUpdatingSkyblockProfilesState().get()) {
+ page = ProfileViewerPage.NO_SKYBLOCK;
+ }
}
if (profile != null) {
@@ -271,7 +280,8 @@ public class GuiProfileViewer extends GuiScreen {
if (NotEnoughUpdates.INSTANCE.config.profileViewer.alwaysShowBingoTab) {
showBingoPage = true;
} else {
- showBingoPage = selectedProfile != null && selectedProfile.getGamemode() != null && selectedProfile.getGamemode().equals("bingo");
+ showBingoPage = selectedProfile != null && selectedProfile.getGamemode() != null &&
+ selectedProfile.getGamemode().equals("bingo");
}
if (!showBingoPage && currentPage == ProfileViewerPage.BINGO) {
@@ -326,7 +336,10 @@ public class GuiProfileViewer extends GuiScreen {
if (selectedProfile != null && selectedProfile.getGamemode() != null) {
GlStateManager.color(1, 1, 1, 1);
- ResourceLocation gamemodeIcon = gamemodeToIcon.getOrDefault(selectedProfile.getGamemode(), gamemodeIconUnknown);
+ ResourceLocation gamemodeIcon = gamemodeToIcon.getOrDefault(
+ selectedProfile.getGamemode(),
+ gamemodeIconUnknown
+ );
Minecraft.getMinecraft().getTextureManager().bindTexture(gamemodeIcon);
Utils.drawTexturedRect(guiLeft - 16 - 5, guiTop + sizeY + 5, 16, 16, GL11.GL_NEAREST);
}
@@ -398,7 +411,10 @@ public class GuiProfileViewer extends GuiScreen {
if (selectedProfile != null && selectedProfile.getGamemode() != null) {
GlStateManager.color(1, 1, 1, 1);
- ResourceLocation gamemodeIcon = gamemodeToIcon.getOrDefault(selectedProfile.getGamemode(), gamemodeIconUnknown);
+ ResourceLocation gamemodeIcon = gamemodeToIcon.getOrDefault(
+ selectedProfile.getGamemode(),
+ gamemodeIconUnknown
+ );
Minecraft.getMinecraft().getTextureManager().bindTexture(gamemodeIcon);
Utils.drawTexturedRect(
guiLeft - 16 - 5,
@@ -416,7 +432,14 @@ public class GuiProfileViewer extends GuiScreen {
GlStateManager.color(1, 1, 1, 1);
if (pages.containsKey(page)) {
- pages.get(page).drawPage(mouseX, mouseY, partialTicks);
+ try {
+ pages.get(page).drawPage(mouseX, mouseY, partialTicks);
+ } catch (Exception ex) {
+ if (page == ProfileViewerPage.CRASH_RECOVERY)
+ throw ex; // Rethrow if the exception handler crashes.
+ pages.put(ProfileViewerPage.CRASH_RECOVERY, new CrashRecoveryPage(this, ex, currentPage));
+ currentPage = ProfileViewerPage.CRASH_RECOVERY;
+ }
} else {
switch (page) {
case LOADING:
@@ -436,7 +459,29 @@ public class GuiProfileViewer extends GuiScreen {
//like telling them to go find a psychotherapist
long timeDiff = System.currentTimeMillis() - startTime;
- if (timeDiff > 20000) {
+ val authState = NotEnoughUpdates.INSTANCE.manager.ursaClient.getAuthenticationState();
+ if (authState == UrsaClient.AuthenticationState.FAILED_TO_JOINSERVER) {
+ Utils.drawStringCentered(
+ EnumChatFormatting.RED +
+ "Looks like we cannot authenticate with Mojang.",
+ guiLeft + sizeX / 2f, guiTop + 111, true, 0
+ );
+ Utils.drawStringCentered(
+ EnumChatFormatting.RED + "Is your game open for more than 24 hours?",
+ guiLeft + sizeX / 2f, guiTop + 121, true, 0
+ );
+ } else if (authState == UrsaClient.AuthenticationState.REJECTED) {
+ Utils.drawStringCentered(
+ EnumChatFormatting.RED +
+ "Looks like we cannot authenticate with Ursa.",
+ guiLeft + sizeX / 2f, guiTop + 111, true, 0
+ );
+ Utils.drawStringCentered(
+ EnumChatFormatting.RED + "Is your game open for more than 24 hours?",
+ guiLeft + sizeX / 2f, guiTop + 121, true, 0
+ );
+
+ } else if (timeDiff > 20000) {
Utils.drawStringCentered(
EnumChatFormatting.YELLOW + "Its taking a while...",
guiLeft + sizeX / 2f, guiTop + 111, true, 0
@@ -466,7 +511,8 @@ public class GuiProfileViewer extends GuiScreen {
guiLeft + sizeX / 2f, guiTop + 151, true, 0
);
Utils.drawStringCentered(
- EnumChatFormatting.YELLOW + String.valueOf(EnumChatFormatting.BOLD) + "What are you doing with your life?",
+ EnumChatFormatting.YELLOW + String.valueOf(EnumChatFormatting.BOLD) +
+ "What are you doing with your life?",
guiLeft + sizeX / 2f, guiTop + 161, true, 0
);
if (timeDiff > 600000) {
@@ -476,7 +522,8 @@ public class GuiProfileViewer extends GuiScreen {
);
if (timeDiff > 1200000) {
Utils.drawStringCentered(
- EnumChatFormatting.RED + String.valueOf(EnumChatFormatting.BOLD) + "You're a menace to society",
+ EnumChatFormatting.RED + String.valueOf(EnumChatFormatting.BOLD) +
+ "You're a menace to society",
guiLeft + sizeX / 2f, guiTop + 181, true, 0
);
if (timeDiff > 1800000) {
@@ -487,7 +534,8 @@ public class GuiProfileViewer extends GuiScreen {
);
if (timeDiff > 3000000) {
Utils.drawStringCentered(
- EnumChatFormatting.RED + String.valueOf(EnumChatFormatting.BOLD) + "You really want this?",
+ EnumChatFormatting.RED + String.valueOf(EnumChatFormatting.BOLD) +
+ "You really want this?",
guiLeft + sizeX / 2f, guiTop + 91, true, 0
);
if (timeDiff > 3300000) {
@@ -695,7 +743,7 @@ public class GuiProfileViewer extends GuiScreen {
}
if (selected) {
- uMin = 196 /256f;
+ uMin = 196 / 256f;
uMax = 226 / 256f;
renderBlurredBackground(width, height, x - 2, y + 2, 30 - 2, 28 - 4);
@@ -750,8 +798,14 @@ public class GuiProfileViewer extends GuiScreen {
}
if (pages.containsKey(currentPage)) {
- if (pages.get(currentPage).mouseClicked(mouseX, mouseY, mouseButton)) {
- return;
+ try {
+ if (pages.get(currentPage).mouseClicked(mouseX, mouseY, mouseButton)) {
+ return;
+ }
+ } catch (Exception ex) {
+ if (currentPage == ProfileViewerPage.CRASH_RECOVERY) throw ex;
+ pages.put(ProfileViewerPage.CRASH_RECOVERY, new CrashRecoveryPage(this, ex, currentPage));
+ currentPage = ProfileViewerPage.CRASH_RECOVERY;
}
}
@@ -869,7 +923,13 @@ public class GuiProfileViewer extends GuiScreen {
super.keyTyped(typedChar, keyCode);
if (pages.containsKey(currentPage)) {
- pages.get(currentPage).keyTyped(typedChar, keyCode);
+ try {
+ pages.get(currentPage).keyTyped(typedChar, keyCode);
+ } catch (Exception ex) {
+ if (currentPage == ProfileViewerPage.CRASH_RECOVERY) throw ex;
+ pages.put(ProfileViewerPage.CRASH_RECOVERY, new CrashRecoveryPage(this, ex, currentPage));
+ currentPage = ProfileViewerPage.CRASH_RECOVERY;
+ }
}
if (playerNameTextField.getFocus()) {
@@ -917,7 +977,9 @@ public class GuiProfileViewer extends GuiScreen {
if (levelObj.maxed) {
renderGoldBar(x, y + 6, xSize);
} else {
- if ((skillName.contains("Catacombs") || Weight.DUNGEON_CLASS_NAMES.stream().anyMatch(e -> skillName.toLowerCase().contains(e))) && levelObj.level >= 50) {
+ if ((skillName.contains("Catacombs") || Weight.DUNGEON_CLASS_NAMES.stream().anyMatch(e -> skillName
+ .toLowerCase()
+ .contains(e))) && levelObj.level >= 50) {
renderGoldBar(x, y + 6, xSize);
} else {
renderBar(x, y + 6, xSize, level % 1);
@@ -1202,6 +1264,7 @@ public class GuiProfileViewer extends GuiScreen {
LOADING(),
INVALID_NAME(),
NO_SKYBLOCK(),
+ CRASH_RECOVERY(),
BASIC(0, Items.paper, "§9Skills"),
DUNGEON(1, Item.getItemFromBlock(Blocks.deadbush), "§eDungeoneering"),
EXTRA(2, Items.book, "§7Profile Stats"),
@@ -1246,6 +1309,10 @@ public class GuiProfileViewer extends GuiScreen {
return null;
}
+ public boolean isTransient() {
+ return this == LOADING || this == NO_SKYBLOCK || this == INVALID_NAME || this == CRASH_RECOVERY;
+ }
+
public Optional<ItemStack> getItem() {
return Optional.ofNullable(stack);
}