diff options
| author | syeyoung <cyong06@naver.com> | 2021-05-15 17:34:01 +0900 | 
|---|---|---|
| committer | syeyoung <cyong06@naver.com> | 2021-05-15 17:34:01 +0900 | 
| commit | e330634ad3a79cb6c010762509dbecfc2c587bce (patch) | |
| tree | 976a17a4cdee88e2be9255f490f6116d24458e51 /src/main/java | |
| parent | 241e11397ba26ad337633fbd9a9e096795605f47 (diff) | |
| download | Skyblock-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.
Diffstat (limited to 'src/main/java')
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);      } | 
