aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyeyoung <cyong06@naver.com>2021-05-15 17:34:01 +0900
committersyeyoung <cyong06@naver.com>2021-05-15 17:34:01 +0900
commite330634ad3a79cb6c010762509dbecfc2c587bce (patch)
tree976a17a4cdee88e2be9255f490f6116d24458e51
parent241e11397ba26ad337633fbd9a9e096795605f47 (diff)
downloadSkyblock-Dungeons-Guide-e330634ad3a79cb6c010762509dbecfc2c587bce.tar.gz
Skyblock-Dungeons-Guide-e330634ad3a79cb6c010762509dbecfc2c587bce.tar.bz2
Skyblock-Dungeons-Guide-e330634ad3a79cb6c010762509dbecfc2c587bce.zip
heartbeats! and make it so that player can play even if server isn't loaded.
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/GuiLoadingError.java87
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/Main.java101
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java22
3 files changed, 153 insertions, 57 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/GuiLoadingError.java b/src/main/java/kr/syeyoung/dungeonsguide/GuiLoadingError.java
new file mode 100644
index 00000000..6df0b911
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/GuiLoadingError.java
@@ -0,0 +1,87 @@
+/*
+ * 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;
+
+import kr.syeyoung.dungeonsguide.gui.MPanel;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.*;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraftforge.fml.client.FMLClientHandler;
+import net.minecraftforge.fml.common.FMLCommonHandler;
+import org.lwjgl.opengl.GL11;
+
+import java.io.IOException;
+
+public class GuiLoadingError extends GuiScreen {
+ private String stacktrace;
+ private Throwable throwable;
+ private GuiScreen originalGUI;
+ public GuiLoadingError(Throwable t, String stacktrace, GuiScreen originalGUI) {
+ this.throwable = t;
+ this.stacktrace = stacktrace;
+ this.originalGUI = originalGUI;
+ }
+
+ @Override
+ public void 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"));
+ }
+
+ @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) {
+ Minecraft.getMinecraft().displayGuiScreen(originalGUI);
+ }
+ }
+
+ @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 developer 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/src/main/java/kr/syeyoung/dungeonsguide/Main.java b/src/main/java/kr/syeyoung/dungeonsguide/Main.java
index 4983acba..873cb6e0 100755
--- a/src/main/java/kr/syeyoung/dungeonsguide/Main.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/Main.java
@@ -19,19 +19,22 @@
package kr.syeyoung.dungeonsguide;
import com.mojang.authlib.exceptions.AuthenticationException;
+import kr.syeyoung.dungeonsguide.eventlistener.DungeonListener;
import kr.syeyoung.dungeonsguide.url.DGStreamHandlerFactory;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.GuiErrorScreen;
-import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.*;
import net.minecraft.launchwrapper.LaunchClassLoader;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException;
+import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.ProgressManager;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
@@ -52,12 +55,29 @@ public class Main
private DGInterface dgInterface;
+ private boolean isLoaded = false;
+ private Throwable cause;
+ private String stacktrace;
+ private boolean showedError = false;
+
+
+
@EventHandler
public void initEvent(FMLInitializationEvent initializationEvent)
{
+ MinecraftForge.EVENT_BUS.register(this);
+ if (dgInterface != null) {
+ main = this;
+ dgInterface.init(initializationEvent);
+ }
+ }
- main = this;
- dgInterface.init(initializationEvent);
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onGuiOpen(GuiOpenEvent guiOpenEvent) {
+ if (!showedError && !isLoaded && guiOpenEvent.gui instanceof GuiMainMenu) {
+ guiOpenEvent.gui = new GuiLoadingError(cause, stacktrace, guiOpenEvent.gui);
+ showedError = true;
+ }
}
@EventHandler
@@ -80,65 +100,32 @@ public class Main
while (progressBar.getStep() < progressBar.getSteps())
progressBar.step("random-"+progressBar.getStep());
ProgressManager.pop(progressBar);
+ isLoaded = true;
} catch (Throwable e) {
- e.printStackTrace();
+ cause = e;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(byteArrayOutputStream);
+ e.printStackTrace(printStream);
+ stacktrace = new String(byteArrayOutputStream.toByteArray());
- throwError(new String[]{
- "Couldn't load Dungeons Guide",
- "Please contact developer if this problem persists after restart"
- });
+ while (progressBar.getStep() < progressBar.getSteps())
+ progressBar.step("random-"+progressBar.getStep());
+ ProgressManager.pop(progressBar);
}
- return;
}
} catch (IOException | AuthenticationException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | InvalidKeySpecException | SignatureException e) {
- e.printStackTrace();
+ cause = e;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(byteArrayOutputStream);
+ e.printStackTrace(printStream);
+ stacktrace = new String(byteArrayOutputStream.toByteArray());
+
+ while (progressBar.getStep() < progressBar.getSteps())
+ progressBar.step("random-"+progressBar.getStep());
+ ProgressManager.pop(progressBar);
}
-
- throwError(new String[]{
- "Can't authenticate session",
- "Steps to fix",
- "1. check if other people can't join minecraft servers.",
- "2. physically click on logout button, then login again",
- "3. make sure you're on the right account",
- "If the problem persists after following these steps, please contact developer"
- });
}
- public void throwError(final String[] a) {
- final GuiScreen b = new GuiErrorScreen(null, null) {
- @Override
- public void drawScreen(int par1, int par2, float par3) {
- super.drawScreen(par1, par2, par3);
- for (int i = 0; i < a.length; ++i) {
- drawCenteredString(fontRendererObj, a[i], width / 2, height / 3 + 12 * i, 0xFFFFFFFF);
- }
- }
-
- @Override
- public void initGui() {
- super.initGui();
- this.buttonList.clear();
- this.buttonList.add(new GuiButton(0, width / 2 - 50, height - 50, 100,20, "close"));
- }
-
- @Override
- protected void actionPerformed(GuiButton button) throws IOException {
- System.exit(-1);
- }
- };
- @SuppressWarnings("serial") CustomModLoadingErrorDisplayException e = new CustomModLoadingErrorDisplayException() {
-
- @Override
- public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) {
- Minecraft.getMinecraft().displayGuiScreen(b);
- }
-
- @Override
- public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime) {
- }
- };
- throw e;
- }
public static Main a() {
return main;
}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java
index 1381a2c3..16943607 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java
@@ -38,6 +38,10 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
public class StompClient extends WebSocketClient implements StompInterface {
public StompClient(URI serverUri, final String token, CloseListener closeListener) throws Exception {
@@ -61,11 +65,15 @@ public class StompClient extends WebSocketClient implements StompInterface {
@Getter
private StompPayload errorPayload;
+ private ScheduledFuture heartbeat = null;
+
+ private static final ScheduledExecutorService ex = Executors.newScheduledThreadPool(1);
@Override
public void onOpen(ServerHandshake handshakedata) {
send(new StompPayload().method(StompHeader.CONNECT)
.header("accept-version","1.2")
+ .header("heart-beat", "30000,30000")
.header("host",uri.getHost()).getBuilt()
);
}
@@ -76,6 +84,19 @@ public class StompClient extends WebSocketClient implements StompInterface {
StompPayload payload = StompPayload.parse(message);
if (payload.method() == StompHeader.CONNECTED) {
stompClientStatus = StompClientStatus.CONNECTED;
+
+ String heartbeat = payload.headers().get("heart-beat");
+ if (heartbeat != null) {
+ int sx = Integer.parseInt(heartbeat.split(",")[0]);
+ int sy = Integer.parseInt(heartbeat.split(",")[1]);
+
+ if (sy == 0) return;
+ int heartbeatMS = Integer.max(30000, sy);
+ this.heartbeat = ex.scheduleAtFixedRate(() -> {
+ send("\n");
+ }, heartbeatMS-1000, heartbeatMS-1000, TimeUnit.MILLISECONDS);
+ }
+
} else if (payload.method() == StompHeader.ERROR) {
errorPayload = payload;
stompClientStatus = StompClientStatus.ERROR;
@@ -113,6 +134,7 @@ public class StompClient extends WebSocketClient implements StompInterface {
@Override
public void onClose(int code, String reason, boolean remote) {
+ if (heartbeat != null) heartbeat.cancel(true);
closeListener.onClose(code, reason, remote);
}