diff --git a/gradle.properties b/gradle.properties index ebe4978..0c962ea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ org.gradle.jvmargs=-Xmx1G # Mod Properties mod_version = 1.0.0 maven_group = com.vladmarica - archives_base_name = better-ping-display + archives_base_name = BetterPingDisplay # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api diff --git a/src/main/java/com/vladmarica/betterpingdisplay/BetterPingDisplayMod.java b/src/main/java/com/vladmarica/betterpingdisplay/BetterPingDisplayMod.java index 16a497f..0a2e622 100644 --- a/src/main/java/com/vladmarica/betterpingdisplay/BetterPingDisplayMod.java +++ b/src/main/java/com/vladmarica/betterpingdisplay/BetterPingDisplayMod.java @@ -1,15 +1,51 @@ package com.vladmarica.betterpingdisplay; +import com.vladmarica.betterpingdisplay.Config.ConfigData; +import java.io.File; +import java.nio.file.Path; import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class BetterPingDisplayMod implements ModInitializer { public static final String MODID = "betterpingdisplay"; public static final Logger LOGGER = LogManager.getLogger(MODID); + private static final String CONFIG_FILE_NAME = MODID + ".json"; + private static BetterPingDisplayMod INSTANCE; + + private Config config = new Config(); @Override public void onInitialize() { + INSTANCE = this; + + Path configFilePath = FabricLoader.getInstance().getConfigDir().resolve(CONFIG_FILE_NAME); + File configFile = configFilePath.toFile(); + if (configFile.exists()) { + try { + ConfigData data = Config.loadConfigFile(configFile); + config = new Config(data); + } catch (Exception ex) { + LOGGER.error("Failed to load config file, using default. Error: {}", ex.getMessage()); + } + } else { + try { + LOGGER.warn("Could not find config file, creating a default one"); + Config.writeConfigFile(configFile, new ConfigData()); + } catch (Exception ex) { + LOGGER.error("Failed to write default config file. Error: {}", ex.getMessage()); + } + } + LOGGER.info("BetterPingDisplay mod loaded"); } + + public Config getConfig() { + return this.config; + } + + public static BetterPingDisplayMod instance() { + return INSTANCE; + } } diff --git a/src/main/java/com/vladmarica/betterpingdisplay/Config.java b/src/main/java/com/vladmarica/betterpingdisplay/Config.java new file mode 100644 index 0000000..0fba95b --- /dev/null +++ b/src/main/java/com/vladmarica/betterpingdisplay/Config.java @@ -0,0 +1,86 @@ +package com.vladmarica.betterpingdisplay; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Serializable; + +public class Config { + private static final int DEFAULT_PING_TEXT_COLOR = 0xA0A0A0; + private static final String DEFAULT_PING_TEXT_FORMAT = "%dms"; + + private int textColor = DEFAULT_PING_TEXT_COLOR; + private String textFormatString = DEFAULT_PING_TEXT_FORMAT; + + public Config(ConfigData confileFileFormat) { + if (confileFileFormat.textColor.startsWith("#")) { + try { + textColor = Integer.parseInt(confileFileFormat.textColor.substring(1), 16); + } + catch (NumberFormatException ex) { + BetterPingDisplayMod.LOGGER.error("Config option 'textColor' is invalid - it must be a hex color code"); + } + } + else { + BetterPingDisplayMod.LOGGER.error("Config option 'textColor' is invalid - it must be a hex color code"); + } + + if (confileFileFormat.textFormatString.contains("%d")) { + textFormatString = confileFileFormat.textFormatString; + } + else { + BetterPingDisplayMod.LOGGER.error("Config option 'textFormatString' is invalid - it needs to contain %d"); + } + } + + public Config() { + this(new ConfigData()); + } + + public int getTextColor() { + return this.textColor; + } + + public String getTextFormatString() { + return this.textFormatString; + } + + public static ConfigData loadConfigFile(File configFile) throws IOException { + FileReader reader = null; + try { + Gson gson = new Gson(); + reader = new FileReader(configFile); + return gson.fromJson(reader, ConfigData.class); + } + finally { + if (reader != null) { + reader.close(); + } + } + } + + public static void writeConfigFile(File configFile, ConfigData data) throws IOException { + FileWriter writer = null; + try { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + writer = new FileWriter(configFile); + writer.write(gson.toJson(data)); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + public static class ConfigData implements Serializable { + @Expose + private String textColor = "#A0A0A0"; + + @Expose + private String textFormatString = "%dms"; + } +} diff --git a/src/main/java/com/vladmarica/betterpingdisplay/hud/CustomPlayerListHud.java b/src/main/java/com/vladmarica/betterpingdisplay/hud/CustomPlayerListHud.java index c7c5975..f68749e 100644 --- a/src/main/java/com/vladmarica/betterpingdisplay/hud/CustomPlayerListHud.java +++ b/src/main/java/com/vladmarica/betterpingdisplay/hud/CustomPlayerListHud.java @@ -4,7 +4,8 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.Ordering; import com.mojang.authlib.GameProfile; import com.mojang.blaze3d.systems.RenderSystem; -import com.vladmarica.betterpingdisplay.mixin.PlayerListHudAccessor; +import com.vladmarica.betterpingdisplay.Config; +import com.vladmarica.betterpingdisplay.BetterPingDisplayMod; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -27,13 +28,18 @@ import net.minecraft.util.Formatting; import net.minecraft.world.GameMode; public final class CustomPlayerListHud { - private static final Ordering ENTRY_ORDERING = Ordering.from(new EntryOrderComparator()); + + private static final Ordering ENTRY_ORDERING = Ordering.from(new EntryOrderComparator()); + private static final int PING_TEXT_RENDER_OFFSET = -13; + private static final int PLAYER_SLOT_EXTRA_WIDTH = 45; + private static final int PLAYER_ICON_WIDTH = 9; public static void render(PlayerListHud hud, int width, Scoreboard scoreboard, ScoreboardObjective obj) { MinecraftClient mc = MinecraftClient.getInstance(); TextRenderer textRenderer = mc.textRenderer; Text header = PlayerListHudUtil.getHeader(hud); Text footer = PlayerListHudUtil.getFooter(hud); + Config config = BetterPingDisplayMod.instance().getConfig(); ClientPlayNetworkHandler clientPlayNetworkHandler = mc.player.networkHandler; List playerList = ENTRY_ORDERING.sortedCopy(clientPlayNetworkHandler.getPlayerList()); @@ -60,7 +66,7 @@ public final class CustomPlayerListHud { ++n; } - boolean bl = mc.isInSingleplayer() || mc.getNetworkHandler().getConnection().isEncrypted(); + boolean displayPlayerIcons = mc.isInSingleplayer() || mc.getNetworkHandler().getConnection().isEncrypted(); int q; if (obj != null) { if (obj.getRenderType() == ScoreboardCriterion.RenderType.HEARTS) { @@ -71,7 +77,7 @@ public final class CustomPlayerListHud { } else { q = 0; } - int r = Math.min(n * ((bl ? 9 : 0) + i + q + 13), width - 50) / n; + int r = Math.min(n * ((displayPlayerIcons ? PLAYER_ICON_WIDTH : 0) + i + q + 13 + PLAYER_SLOT_EXTRA_WIDTH), width - 50) / n; int s = width / 2 - (r * n + (n - 1) * 5) / 2; int t = 10; int u = r * n + (n - 1) * 5; @@ -135,7 +141,7 @@ public final class CustomPlayerListHud { PlayerListEntry player = playerList.get(x); GameProfile gameProfile = player.getProfile(); int ah; - if (bl) { + if (displayPlayerIcons) { PlayerEntity playerEntity = mc.world.getPlayerByUuid(gameProfile.getId()); boolean bl2 = playerEntity != null && playerEntity.isPartVisible(PlayerModelPart.CAPE) && ("Dinnerbone".equals(gameProfile.getName()) || "Grumm".equals(gameProfile.getName())); mc.getTextureManager().bindTexture(player.getSkinTexture()); @@ -166,7 +172,16 @@ public final class CustomPlayerListHud { } } - PlayerListHudUtil.renderLatencyIcon(hud, r, aa - (bl ? 9 : 0), ab, player); + // Here is the magic, rendering the ping text + String pingString = String.format(config.getTextFormatString(), player.getLatency()); + int pingStringWidth = textRenderer.getStringWidth(pingString); + textRenderer.drawWithShadow( + pingString, + (float) r + aa - pingStringWidth + PING_TEXT_RENDER_OFFSET - (displayPlayerIcons ? PLAYER_ICON_WIDTH : 0), + (float) ab, + config.getTextColor()); + + PlayerListHudUtil.renderLatencyIcon(hud, r, aa - (displayPlayerIcons ? PLAYER_ICON_WIDTH : 0), ab, player); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 49130ad..2c32f27 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,10 +1,10 @@ { "schemaVersion": 1, "id": "modid", - "version": "${version}", + "version": "1.0", "name": "Better Ping Display", - "description": "This is an example description! Tell everyone what your mod is about!", + "description": "Shows the actual ping number instead of just bars in the player list.!", "authors": [ "Quintinity" ], @@ -28,7 +28,6 @@ "depends": { "fabricloader": ">=0.7.4", - "fabric": "*", "minecraft": "1.15.x" }, "suggests": {