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
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)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The null check translated == null is redundant. In Minecraft 1.12.2, I18n.format always returns a string; if a translation key is missing, it returns the key itself.

Suggested change
if (translated == null || translated.equals(key)) {
if (translated.equals(key)) {

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",
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

This mixin targets ServerListEntryNormal, which is a client-only class. Adding it to the main mixins list in a common mixin configuration will cause a ClassNotFoundException when the mod is loaded on a dedicated server. It should be moved to the client array (line 15) to ensure it only loads on the client side. Note that other client-side mixins in this list (lines 9-13) likely share this issue.

"client.ServerPingerMixin"
],
"client": [],
Expand Down
Loading