Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mcp_mappings=stable_39
mod_id=modflared
mod_name=Modflared
mod_license=MIT
mod_version=1.12.2-legacy.1
mod_version=1.12.2-1
mod_group_id=dev.httxrafa.modflared
mod_authors=HttpRafa, Contributors
mod_description=Automatically connects you to a Cloudflare tunnel without having to install cloudflared separately.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package dev.httxrafa.modflared.mixin.client;

import dev.httxrafa.modflared.Modflared;
import dev.httxrafa.modflared.interfaces.mixin.IServerData;
import dev.httxrafa.modflared.tunnel.TunnelStatus;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiMultiplayer;
import net.minecraft.client.gui.ServerListEntryNormal;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ServerListEntryNormal.class)
public abstract class ServerListEntryNormalMixin {

@Shadow
@Final
private GuiMultiplayer owner;

@Shadow
@Final
private ServerData server;

@Unique
private static final ResourceLocation MODFLARED_INDICATOR_TEXTURE = new ResourceLocation(
Modflared.MOD_ID,
"textures/gui/sprites/icon/indicator.png"
);

@Unique
private static final int MODFLARED_INDICATOR_SIZE = 10;

@Unique
private static final int MODFLARED_INDICATOR_RIGHT_OFFSET = 28;

@Unique
private static final String MODFLARED_INDICATOR_TOOLTIP_KEY = "gui.multiplayer.tunnel.status.0";

@Unique
private static final String MODFLARED_INDICATOR_TOOLTIP_FALLBACK = "Modflared in use";

@Inject(method = "drawEntry", at = @At("TAIL"))
private void modflared$drawTunnelIndicator(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks, CallbackInfo callbackInfo) {
TunnelStatus tunnelStatus = ((IServerData) this.server).getTunnelStatus();
if (tunnelStatus == null || tunnelStatus.getState() != TunnelStatus.State.USE) {
return;
}

int indicatorX = x + listWidth - MODFLARED_INDICATOR_RIGHT_OFFSET;
int indicatorY = y + 11;

GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(MODFLARED_INDICATOR_TEXTURE);
Comment thread
hattapauzi marked this conversation as resolved.
Gui.drawModalRectWithCustomSizedTexture(
indicatorX,
indicatorY,
0.0F,
0.0F,
MODFLARED_INDICATOR_SIZE,
MODFLARED_INDICATOR_SIZE,
MODFLARED_INDICATOR_SIZE,
MODFLARED_INDICATOR_SIZE
);

if (mouseX >= indicatorX && mouseX <= indicatorX + MODFLARED_INDICATOR_SIZE && mouseY >= indicatorY && mouseY <= indicatorY + MODFLARED_INDICATOR_SIZE) {
this.owner.setHoveringText(modflared$translate(MODFLARED_INDICATOR_TOOLTIP_KEY, MODFLARED_INDICATOR_TOOLTIP_FALLBACK));
}
}

@Unique
private static String modflared$translate(String key, String fallback) {
String translated = I18n.format(key);
if (translated == null || translated.equals(key)) {
return fallback;
}
Comment thread
hattapauzi marked this conversation as resolved.
return translated;
}
}
19 changes: 14 additions & 5 deletions src/main/java/dev/httxrafa/modflared/tunnel/TunnelStatus.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package dev.httxrafa.modflared.tunnel;

import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.ITextComponent;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -29,15 +30,23 @@ public State getState() {
public List<ITextComponent> generateFeedback() {
List<ITextComponent> feedback = new ArrayList<ITextComponent>();
if (state == State.USE) {
feedback.add(new TextComponentTranslation("gui.tunnel.status.use").setStyle(new net.minecraft.util.text.Style().setColor(TextFormatting.AQUA)));
feedback.add(translate("gui.tunnel.status.use", "Using Cloudflare tunnel", TextFormatting.AQUA));
} else if (state == State.FAILED_TO_DETERMINE) {
feedback.add(new TextComponentTranslation("gui.tunnel.status.failed.0").setStyle(new net.minecraft.util.text.Style().setColor(TextFormatting.RED)));
feedback.add(new TextComponentTranslation("gui.tunnel.status.failed.1").setStyle(new net.minecraft.util.text.Style().setColor(TextFormatting.RED)));
feedback.add(new TextComponentTranslation("gui.tunnel.status.failed.2").setStyle(new net.minecraft.util.text.Style().setColor(TextFormatting.RED)));
feedback.add(translate("gui.tunnel.status.failed.0", "Modflared could not determine if a tunnel is required.", TextFormatting.RED));
feedback.add(translate("gui.tunnel.status.failed.1", "The connection will continue without a tunnel.", TextFormatting.RED));
feedback.add(translate("gui.tunnel.status.failed.2", "Add this server to forced_tunnels.json if it must use a tunnel.", TextFormatting.RED));
}
Comment thread
hattapauzi marked this conversation as resolved.
return Collections.unmodifiableList(feedback);
}

private static ITextComponent translate(String key, String fallback, TextFormatting formatting) {
ITextComponent component = new TextComponentTranslation(key);
if (component.getUnformattedText().equals(key)) {
component = new TextComponentString(fallback);
}
return component.setStyle(new net.minecraft.util.text.Style().setColor(formatting));
}

public enum State {
USE,
DONT_USE,
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/modflared/lang/en_us.lang
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
gui.tunnel.status.use=Using Cloudflare tunnel
gui.multiplayer.tunnel.status.0=Modflared in use
gui.tunnel.status.failed.0=Modflared could not determine if a tunnel is required.
gui.tunnel.status.failed.1=The connection will continue without a tunnel.
gui.tunnel.status.failed.2=Add this server to forced_tunnels.json if it must use a tunnel.
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/modflared.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"client.GuiConnectingMixin",
"client.GuiConnectingThreadMixin",
"client.ServerDataMixin",
"client.ServerListEntryNormalMixin",
"client.ServerPingerMixin"
],
"client": [],
Expand Down
Loading