Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The version has been updated to 1.12.2-1 here, but the Modflared.java file (line 25) still contains the old version string 1.12.2-legacy.1. Since the @Mod annotation in Modflared.java relies on that constant, the mod will still report the old version to Forge. Please ensure both are synchronized.

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);
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)) {
Comment thread
HttpRafa marked this conversation as resolved.
return fallback;
}
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));
}
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",
Comment thread
HttpRafa marked this conversation as resolved.
"client.ServerPingerMixin"
],
"client": [],
Expand Down
Loading