Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.

Commit 485097d

Browse files
committed
add server icon option to IPHud
1 parent 8750ad3 commit 485097d

File tree

12 files changed

+763
-348
lines changed

12 files changed

+763
-348
lines changed

1.16_combat-6/src/main/java/io/github/axolotlclient/mixin/InputUtilTypeMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@Mixin(InputUtil.Type.class)
1212
public class InputUtilTypeMixin {
1313

14-
@Inject(method = "method_27450", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwGetKeyName(II)Ljava/lang/String;"), cancellable = true)
14+
@Inject(method = "method_27450", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwGetKeyName(II)Ljava/lang/String;", remap = false), cancellable = true)
1515
private static void fixScancodeError(Integer i, String string, CallbackInfoReturnable<Text> cir) {
1616
if (i == -1) {
1717
cir.setReturnValue(new TranslatableText(string));
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright © 2024 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.modules.hud.gui.hud;
24+
25+
import java.io.IOException;
26+
import java.util.List;
27+
28+
import com.google.common.hash.Hashing;
29+
import io.github.axolotlclient.AxolotlClientConfig.api.options.Option;
30+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.BooleanOption;
31+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.EnumOption;
32+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.IntegerOption;
33+
import io.github.axolotlclient.modules.hud.gui.component.DynamicallyPositionable;
34+
import io.github.axolotlclient.modules.hud.gui.entry.TextHudEntry;
35+
import io.github.axolotlclient.modules.hud.gui.layout.AnchorPoint;
36+
import io.github.axolotlclient.modules.hud.util.DrawPosition;
37+
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
38+
import net.minecraft.client.texture.NativeImage;
39+
import net.minecraft.client.texture.NativeImageBackedTexture;
40+
import net.minecraft.client.util.math.MatrixStack;
41+
import net.minecraft.util.Identifier;
42+
43+
/**
44+
* This implementation of Hud modules is based on KronHUD.
45+
* <a href="https://github.com/DarkKronicle/KronHUD">Github Link.</a>
46+
*
47+
* @license GPL-3.0
48+
*/
49+
50+
public class IPHud extends TextHudEntry implements DynamicallyPositionable {
51+
52+
public static final Identifier ID = new Identifier("kronhud", "iphud");
53+
private final BooleanOption showIcon = new BooleanOption("iphud.show_icon", false);
54+
private NativeImageBackedTexture icon;
55+
private Identifier iconId;
56+
private final IntegerOption height = new IntegerOption("iphud.height", 13, 9, 64);
57+
private final EnumOption<AnchorPoint> anchor = new EnumOption<>("anchorpoint", AnchorPoint.class,
58+
AnchorPoint.TOP_LEFT);
59+
60+
@SuppressWarnings("UnstableApiUsage")
61+
public IPHud() {
62+
super(115, 13, true);
63+
ClientPlayConnectionEvents.DISCONNECT.register((clientPacketListener, minecraft) -> {
64+
if (icon != null) {
65+
minecraft.getTextureManager().destroyTexture(iconId);
66+
icon.close();
67+
icon = null;
68+
iconId = null;
69+
}
70+
});
71+
ClientPlayConnectionEvents.JOIN.register((clientPacketListener, packetSender, minecraft) -> {
72+
if (showIcon.get()) {
73+
if (!minecraft.isInSingleplayer() && minecraft.getCurrentServerEntry() != null) {
74+
iconId = new Identifier("servers/" + Hashing.sha1().hashUnencodedChars(minecraft.getCurrentServerEntry().address) + "/icon");
75+
try {
76+
var img = NativeImage.read(minecraft.getCurrentServerEntry().getIcon());
77+
icon = new NativeImageBackedTexture(img);
78+
icon.upload();
79+
minecraft.getTextureManager().registerTexture(iconId, icon);
80+
} catch (IOException e) {
81+
if (icon != null) {
82+
icon.close();
83+
icon = null;
84+
}
85+
}
86+
}
87+
}
88+
});
89+
}
90+
91+
@Override
92+
public Identifier getId() {
93+
return ID;
94+
}
95+
96+
public String getValue() {
97+
if (client.isInSingleplayer() || client.getCurrentServerEntry() == null) {
98+
return "Singleplayer";
99+
}
100+
return client.getCurrentServerEntry().address;
101+
}
102+
103+
private void updateSize() {
104+
int w = getWidth();
105+
int h = getHeight();
106+
int hNew = height.get();
107+
boolean updated = false;
108+
if (h != hNew) {
109+
setHeight(hNew);
110+
updated = true;
111+
}
112+
int req = client.textRenderer.getWidth(getValue()) + 4;
113+
if (showIcon.get()) {
114+
req += getHeight() + 1;
115+
}
116+
if (w != req) {
117+
setWidth(req);
118+
updated = true;
119+
}
120+
if (updated) {
121+
onBoundsUpdate();
122+
}
123+
}
124+
125+
@Override
126+
public List<Option<?>> getConfigurationOptions() {
127+
var options = super.getConfigurationOptions();
128+
options.add(showIcon);
129+
options.add(height);
130+
options.add(anchor);
131+
return options;
132+
}
133+
134+
@Override
135+
public void renderComponent(MatrixStack graphics, float delta) {
136+
updateSize();
137+
DrawPosition pos = getPos();
138+
int textX = pos.x() + getWidth() / 2;
139+
if (showIcon.get() && icon != null) {
140+
int imageSize = getHeight() - 2 + 1;
141+
textX += imageSize / 2;
142+
client.getTextureManager().bindTexture(iconId);
143+
drawTexture(graphics, pos.x() + 1, pos.y() + 1, 0, 0, imageSize, imageSize, imageSize, imageSize);
144+
}
145+
146+
drawCenteredString(graphics, client.textRenderer, getValue(), textX, pos.y() + getHeight() / 2 - client.textRenderer.fontHeight / 2, textColor.get().toInt(), shadow.get());
147+
}
148+
149+
@Override
150+
public void renderPlaceholderComponent(MatrixStack graphics, float delta) {
151+
renderComponent(graphics, delta);
152+
}
153+
154+
@Override
155+
public AnchorPoint getAnchor() {
156+
return anchor.get();
157+
}
158+
}

1.16_combat-6/src/main/java/io/github/axolotlclient/modules/hud/gui/hud/simple/IPHud.java

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright © 2024 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.modules.hud.gui.hud;
24+
25+
import java.io.IOException;
26+
import java.util.List;
27+
28+
import com.mojang.blaze3d.texture.NativeImage;
29+
import io.github.axolotlclient.AxolotlClientConfig.api.options.Option;
30+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.BooleanOption;
31+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.EnumOption;
32+
import io.github.axolotlclient.AxolotlClientConfig.impl.options.IntegerOption;
33+
import io.github.axolotlclient.modules.hud.gui.component.DynamicallyPositionable;
34+
import io.github.axolotlclient.modules.hud.gui.entry.TextHudEntry;
35+
import io.github.axolotlclient.modules.hud.gui.layout.AnchorPoint;
36+
import io.github.axolotlclient.modules.hud.util.DrawPosition;
37+
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
38+
import net.minecraft.client.gui.GuiGraphics;
39+
import net.minecraft.client.texture.FaviconTexture;
40+
import net.minecraft.util.Identifier;
41+
42+
/**
43+
* This implementation of Hud modules is based on KronHUD.
44+
* <a href="https://github.com/DarkKronicle/KronHUD">Github Link.</a>
45+
*
46+
* @license GPL-3.0
47+
*/
48+
49+
public class IPHud extends TextHudEntry implements DynamicallyPositionable {
50+
51+
public static final Identifier ID = new Identifier("kronhud", "iphud");
52+
private final BooleanOption showIcon = new BooleanOption("iphud.show_icon", false);
53+
private FaviconTexture icon;
54+
private final IntegerOption height = new IntegerOption("iphud.height", 13, 9, 64);
55+
private final EnumOption<AnchorPoint> anchor = new EnumOption<>("anchorpoint", AnchorPoint.class,
56+
AnchorPoint.TOP_LEFT);
57+
58+
public IPHud() {
59+
super(115, 13, true);
60+
ClientPlayConnectionEvents.DISCONNECT.register((clientPacketListener, minecraft) -> {
61+
if (icon != null) {
62+
icon.close();
63+
icon = null;
64+
}
65+
});
66+
ClientPlayConnectionEvents.JOIN.register((clientPacketListener, packetSender, minecraft) -> {
67+
if (showIcon.get()) {
68+
if (!minecraft.isInSingleplayer() && minecraft.getCurrentServerEntry() != null) {
69+
icon = FaviconTexture.createServerFaviconTexture(minecraft.getTextureManager(), minecraft.getCurrentServerEntry().address);
70+
try {
71+
icon.upload(NativeImage.read(minecraft.getCurrentServerEntry().getFavicon()));
72+
} catch (IOException e) {
73+
if (icon != null) {
74+
icon.close();
75+
icon = null;
76+
}
77+
}
78+
}
79+
}
80+
updateSize();
81+
});
82+
}
83+
84+
private void updateSize() {
85+
int w = getWidth();
86+
int h = getHeight();
87+
int hNew = height.get();
88+
boolean updated = false;
89+
if (h != hNew) {
90+
setHeight(hNew);
91+
updated = true;
92+
}
93+
int req = client.textRenderer.getWidth(getValue()) + 4;
94+
if (showIcon.get()) {
95+
req += getHeight() + 1;
96+
}
97+
if (w != req) {
98+
setWidth(req);
99+
updated = true;
100+
}
101+
if (updated) {
102+
onBoundsUpdate();
103+
}
104+
}
105+
106+
@Override
107+
public Identifier getId() {
108+
return ID;
109+
}
110+
111+
public String getValue() {
112+
if (client.isInSingleplayer() || client.getCurrentServerEntry() == null) {
113+
return "Singleplayer";
114+
}
115+
return client.getCurrentServerEntry().address;
116+
}
117+
118+
@Override
119+
public List<Option<?>> getConfigurationOptions() {
120+
var options = super.getConfigurationOptions();
121+
options.add(showIcon);
122+
options.add(height);
123+
options.add(anchor);
124+
return options;
125+
}
126+
127+
@Override
128+
public void renderComponent(GuiGraphics graphics, float delta) {
129+
updateSize();
130+
DrawPosition pos = getPos();
131+
int textX = pos.x() + getWidth() / 2;
132+
if (showIcon.get() && icon != null) {
133+
int imageSize = getHeight() - 2 + 1;
134+
textX += imageSize / 2;
135+
graphics.drawTexture(icon.getTextureId(), pos.x() + 1, pos.y() + 1, 0, 0, imageSize, imageSize, imageSize, imageSize);
136+
}
137+
138+
drawCenteredString(graphics, client.textRenderer, getValue(), textX, pos.y() + getHeight() / 2 - client.textRenderer.fontHeight / 2, textColor.get().toInt(), shadow.get());
139+
}
140+
141+
@Override
142+
public void renderPlaceholderComponent(GuiGraphics graphics, float delta) {
143+
renderComponent(graphics, delta);
144+
}
145+
146+
@Override
147+
public AnchorPoint getAnchor() {
148+
return anchor.get();
149+
}
150+
}

0 commit comments

Comments
 (0)