summary refs log tree commit diff stats
path: root/src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java')
-rw-r--r--src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java b/src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java
new file mode 100644
index 0000000..748801c
--- /dev/null
+++ b/src/main/java/ganarchy/friendcode/client/FriendConnectingScreen.java
@@ -0,0 +1,110 @@
+package ganarchy.friendcode.client;
+
+import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
+import net.minecraft.client.gui.screen.LoadingDisplay;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.client.network.ServerInfo;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.screen.ScreenTexts;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import net.minecraft.util.Util;
+import org.apache.commons.codec.binary.Base32;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Locale;
+
+public class FriendConnectingScreen extends Screen {
+    private static final Text PATIENCE_TEXT = Text.translatable("friendcode.patience");
+    private final ServerInfo serverEntry;
+    private final BooleanConsumer callback;
+    private final SamProxyThread proxyThread;
+    private long startTimeMs;
+    private Text renderText = null;
+
+    public FriendConnectingScreen(ServerInfo serverEntry, BooleanConsumer callback, String text) {
+        super(Text.translatable("friendcode.connecting"));
+        this.serverEntry = serverEntry;
+        this.callback = callback;
+        this.startTimeMs = Util.getMeasuringTimeMs();
+        this.proxyThread = new SamProxyThread(text);
+    }
+
+    @Override
+    protected void init() {
+        try {
+            this.proxyThread.start();
+        } catch (IllegalThreadStateException ignored) {
+        }
+        // cancel friend code.
+        this.addDrawableChild(new ButtonWidget(
+                this.width / 2 - 155,
+                this.height - 28,
+                310,
+                20,
+                ScreenTexts.CANCEL,
+                button -> this.close()
+        ));
+    }
+
+
+    @Override
+    public void close() {
+        super.close();
+        if (this.proxyThread.status() != SamProxyThread.Status.RUNNING) {
+            this.proxyThread.stopProxy();
+        }
+    }
+
+    @Override
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        this.renderBackground(matrices);
+        FriendConnectingScreen.drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 50, 0xFFFFFF);
+        if (this.renderText != null) {
+            FriendConnectingScreen.drawCenteredText(matrices, this.textRenderer, this.renderText, this.width / 2, 82, 0xFFFFFF);
+        } else {
+            FriendConnectingScreen.drawCenteredText(matrices, this.textRenderer, PATIENCE_TEXT, this.width / 2, 82, 0xFFFFFF);
+            final String string = LoadingDisplay.get(Util.getMeasuringTimeMs());
+            this.client.textRenderer.draw(matrices, string, (float) (this.client.currentScreen.width / 2 - this.client.textRenderer.getWidth(string) / 2), (float) (this.client.currentScreen.height / 2 + this.client.textRenderer.fontHeight), 0x808080);
+        }
+        super.render(matrices, mouseX, mouseY, delta);
+    }
+
+    @Override
+    public void tick() {
+        super.tick();
+        if (proxyThread.status() != SamProxyThread.Status.IDLE) {
+            switch (proxyThread.status()) {
+                case CONNECTION_FAILED -> {
+                    this.renderText = Text.translatable("friendcode.connect.no_i2p");
+                    break;
+                }
+                case SETUP_FAILED -> {
+                    this.renderText = Text.translatable("friendcode.connect.failed");
+                    break;
+                }
+                case RESOLUTION_FAILED -> {
+                    this.renderText = Text.translatable("friendcode.connect.no_such_code");
+                    break;
+                }
+                case RUNNING -> {
+                    this.serverEntry.address = "[::1]:" + this.proxyThread.port();
+                    this.callback.accept(true);
+                    break;
+                }
+            }
+        }
+        if (!this.proxyThread.isConnecting()) {
+            startTimeMs = Util.getMeasuringTimeMs();
+        }
+        if (Util.getMeasuringTimeMs() - startTimeMs > 20 * 1000) {
+            // keep it from getting stuck.
+            // FIXME this is wrong.
+            //this.proxyThread.interrupt();
+        }
+    }
+}