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();
}
}
}