added more info to the overlay and changed many things

This commit is contained in:
Lee 2023-03-07 23:28:48 +00:00
parent 3ce1b6cc3a
commit 576d86408c
20 changed files with 382 additions and 38 deletions

@ -1,20 +1,15 @@
package cc.fascinated.wildaddons; package cc.fascinated.wildaddons;
import cc.fascinated.wildaddons.utils.Config; import cc.fascinated.wildaddons.utils.Config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter; import lombok.Getter;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
import org.spongepowered.configurate.loader.ConfigurationLoader;
import org.spongepowered.configurate.serialize.SerializationException;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -23,6 +18,7 @@ public class Main implements ModInitializer {
public static final Logger LOGGER = LogManager.getLogger(Main.class); public static final Logger LOGGER = LogManager.getLogger(Main.class);
@Getter private static final ExecutorService executorService = Executors.newCachedThreadPool(); @Getter private static final ExecutorService executorService = Executors.newCachedThreadPool();
@Getter private static final MinecraftClient minecraftClient = MinecraftClient.getInstance(); @Getter private static final MinecraftClient minecraftClient = MinecraftClient.getInstance();
@Getter private static final Gson gson = new GsonBuilder().create();
@Getter private static final Config statisticsConfig; @Getter private static final Config statisticsConfig;
static { static {

@ -16,6 +16,8 @@ public class AutoWelcomerAddon extends Addon {
"Automatically sends the welcome command when a new player joins.", "Automatically sends the welcome command when a new player joins.",
Category.CHAT Category.CHAT
); );
// TODO: actually check if we got the gem for welcoming
} }
@Override @Override

@ -2,12 +2,24 @@ package cc.fascinated.wildaddons.addon.impl.ui;
import cc.fascinated.wildaddons.Main; import cc.fascinated.wildaddons.Main;
import cc.fascinated.wildaddons.addon.Addon; import cc.fascinated.wildaddons.addon.Addon;
import cc.fascinated.wildaddons.listener.ActivePotionsListener;
import cc.fascinated.wildaddons.listener.ArmorListener;
import cc.fascinated.wildaddons.listener.PlayerListener;
import cc.fascinated.wildaddons.listener.ResearchTasksListener;
import cc.fascinated.wildaddons.statistic.Statistic; import cc.fascinated.wildaddons.statistic.Statistic;
import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor; import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor;
import cc.fascinated.wildaddons.utils.GameUtils;
import cc.fascinated.wildaddons.utils.NumberUtils;
import cc.fascinated.wildaddons.utils.PlayerUtils;
import lombok.Getter;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class OverlayAddon extends Addon { public class OverlayAddon extends Addon {
public OverlayAddon() { public OverlayAddon() {
@ -20,18 +32,58 @@ public class OverlayAddon extends Addon {
if (!this.isEnabled()) { if (!this.isEnabled()) {
return; return;
} }
int lastY = 5;
MinecraftClient minecraftClient = Main.getMinecraftClient(); MinecraftClient minecraftClient = Main.getMinecraftClient();
TextRenderer renderer = minecraftClient.textRenderer; TextRenderer renderer = minecraftClient.textRenderer;
renderer.drawWithShadow(matrixStack, "FPS: " + minecraftClient.getCurrentFps(), 5, 5, 0xffffff); renderer.drawWithShadow(matrixStack, "FPS: " + GameUtils.getFpsFormatted(), 5, lastY, 0xffffff);
renderer.drawWithShadow(matrixStack, "TPS: " + TpsMonitor.getFormattedTPS(), 5, 16, 0xffffff); lastY += 11;
renderer.drawWithShadow(matrixStack, "TPS: " + TpsMonitor.getFormattedTPS(), 5, lastY, 0xffffff);
if (!PlayerUtils.isOnWild()) {
return;
}
lastY += 11;
renderer.drawWithShadow(matrixStack, "IP: " + PlayerUtils.getCurrentServerIp(), 5, lastY, 0xffffff);
lastY += 11;
renderer.drawWithShadow(matrixStack, "Is Afk: " + !PlayerListener.isMoving(), 5, lastY, 0xffffff);
lastY += 13;
renderer.drawWithShadow(matrixStack, "Statistics:", 5, 30, 0xffffff); renderer.drawWithShadow(matrixStack, "§7§nStatistics:", 5, lastY, 0xffffff);
int lastY = 41; lastY += 11;
for (Statistic statistic : Statistic.values()) { for (Statistic statistic : Statistic.values()) {
renderer.drawWithShadow(matrixStack, statistic.name() + " - " + statistic.get(), 5, lastY, 0xffffff); renderer.drawWithShadow(matrixStack, "§e" + statistic.getName() + " §f- §a" + NumberUtils.format(statistic.get(), true), 5, lastY, 0xffffff);
lastY += 11; lastY += 11;
} }
if (ResearchTasksListener.getResearchTasks().size() > 0) {
lastY += 3;
renderer.drawWithShadow(matrixStack, "§7§nResearch Tasks:", 5, lastY, 0xffffff);
lastY += 11;
for (String task : ResearchTasksListener.getResearchTasks()) {
renderer.drawWithShadow(matrixStack, task, 5, lastY, 0xffffff);
lastY += 11;
}
}
if (ActivePotionsListener.getActivePotions().size() > 0) {
lastY += 3;
renderer.drawWithShadow(matrixStack, "§7§nActive Potions:", 5, lastY, 0xffffff);
lastY += 11;
for (String task : ActivePotionsListener.getActivePotions()) {
renderer.drawWithShadow(matrixStack, task, 5, lastY, 0xffffff);
lastY += 11;
}
}
if (ActivePotionsListener.getActivePotions().size() > 0) {
lastY += 3;
renderer.drawWithShadow(matrixStack, "§7§nArmor Multipliers:", 5, lastY, 0xffffff);
lastY += 11;
for (Map.Entry<String, Double> entry : ArmorListener.getArmorMultipliers().entrySet()) {
renderer.drawWithShadow(matrixStack, "§e" + entry.getKey() + " §f- §a" + entry.getValue() + "x", 5, lastY, 0xffffff);
lastY += 11;
}
}
}); });
} }
} }

@ -3,20 +3,13 @@ package cc.fascinated.wildaddons.client;
import cc.fascinated.wildaddons.Main; import cc.fascinated.wildaddons.Main;
import cc.fascinated.wildaddons.addon.AddonManager; import cc.fascinated.wildaddons.addon.AddonManager;
import cc.fascinated.wildaddons.event.EventManager; import cc.fascinated.wildaddons.event.EventManager;
import cc.fascinated.wildaddons.listener.ActivePotionsListener;
import cc.fascinated.wildaddons.listener.ArmorListener;
import cc.fascinated.wildaddons.listener.PlayerListener; import cc.fascinated.wildaddons.listener.PlayerListener;
import cc.fascinated.wildaddons.listener.ResearchTasksListener;
import cc.fascinated.wildaddons.statistic.Statistic; import cc.fascinated.wildaddons.statistic.Statistic;
import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor; import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
import org.spongepowered.configurate.loader.ConfigurationLoader;
import org.spongepowered.configurate.serialize.SerializationException;
import java.io.File;
import java.io.IOException;
public class WildAddonsClient implements ClientModInitializer { public class WildAddonsClient implements ClientModInitializer {
@ -32,5 +25,8 @@ public class WildAddonsClient implements ClientModInitializer {
EventManager.registerListener(new PlayerListener()); EventManager.registerListener(new PlayerListener());
EventManager.registerListener(new TpsMonitor()); EventManager.registerListener(new TpsMonitor());
EventManager.registerListener(new ArmorListener());
EventManager.registerListener(new ResearchTasksListener());
EventManager.registerListener(new ActivePotionsListener());
} }
} }

@ -1,11 +1,17 @@
package cc.fascinated.wildaddons.event; package cc.fascinated.wildaddons.event;
import net.minecraft.network.Packet; import net.minecraft.network.Packet;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public interface EventListener { public interface EventListener {
default void onTick() {} /**
* Gets called every game tick
*
* @param ticksPassed the total amount of ticks passed
*/
default void onTick(int ticksPassed) {}
/** /**
* Gets called when a chat message is received * Gets called when a chat message is received
@ -28,4 +34,12 @@ public interface EventListener {
* @param packet the packet * @param packet the packet
*/ */
default void onPacketSend(Packet<?> packet) {} default void onPacketSend(Packet<?> packet) {}
/**
* Gets called every time the tab-list updates.
*
* @param header the header
* @param footer the footer
*/
default void onTabListUpdate(Text header, Text footer) {}
} }

@ -0,0 +1,37 @@
package cc.fascinated.wildaddons.listener;
import cc.fascinated.wildaddons.event.EventListener;
import cc.fascinated.wildaddons.utils.TextUtils;
import lombok.Getter;
import net.minecraft.text.Text;
import java.util.LinkedHashSet;
import java.util.Set;
public class ActivePotionsListener implements EventListener {
@Getter private static final Set<String> activePotions = new LinkedHashSet<>();
@Override
public void onTabListUpdate(Text header, Text footer) {
String footerString = footer.getString();
String[] lines = footerString.split("\n");
activePotions.clear();
boolean found = false;
for (String part : lines) {
String partStripped = TextUtils.stripColors(part);
if (partStripped.contains("POTION BUFFS")) {
found = true;
continue;
}
if (!found) {
continue;
}
if (partStripped.isEmpty()) { // Don't overflow into other data
break;
}
activePotions.add(TextUtils.removeColorCode(part, "§o"));
}
}
}

@ -0,0 +1,73 @@
package cc.fascinated.wildaddons.listener;
import cc.fascinated.wildaddons.Main;
import cc.fascinated.wildaddons.event.EventListener;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.text.Text;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ArmorListener implements EventListener {
/**
* The current multipliers from armor
*/
@Getter private static Map<String, Double> armorMultipliers = new HashMap<>();
@Override
public void onTick(int ticksPassed) { // TODO: move to its own thread
if (ticksPassed % 20 != 0) {
return;
}
MinecraftClient client = Main.getMinecraftClient();
ClientPlayerEntity player = client.player;
if (player == null) {
return;
}
armorMultipliers.clear();
PlayerInventory inventory = player.getInventory();
for (ItemStack stack : inventory.armor) {
if (stack == null) {
continue;
}
Text name = stack.getName();
if (name == null) {
return;
}
NbtCompound nbt = stack.getNbt();
if (nbt == null) {
continue;
}
NbtElement armourTypeNbt = nbt.get("armor-piece");
if (armourTypeNbt == null) {
continue;
}
List<Text> tooltip = stack.getTooltip(player, TooltipContext.ADVANCED);
for (int i = 10; i < tooltip.size(); i++) {
Text text = tooltip.get(i);
String string = text.getString();
if (string.isEmpty()) {
break;
}
String[] parts = string.split(" ");
double amount = Double.parseDouble(parts[0].replace("x", ""));
String boostName = parts[3];
double oldAmount = armorMultipliers.computeIfAbsent(boostName, (e) -> 0.0D);
oldAmount+=amount;
armorMultipliers.put(boostName, oldAmount);
}
}
}
}

@ -13,7 +13,7 @@ public class PlayerListener implements EventListener {
private static long lastMovement; private static long lastMovement;
@Override @Override
public void onTick() { public void onTick(int ticksPassed) {
if (!PlayerUtils.isOnWild()) { // Ignore if the player isn't on Wild if (!PlayerUtils.isOnWild()) { // Ignore if the player isn't on Wild
return; return;
} }

@ -0,0 +1,40 @@
package cc.fascinated.wildaddons.listener;
import cc.fascinated.wildaddons.Main;
import cc.fascinated.wildaddons.event.EventListener;
import cc.fascinated.wildaddons.utils.PlayerUtils;
import cc.fascinated.wildaddons.utils.TextUtils;
import lombok.Getter;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.text.Text;
import java.util.LinkedHashSet;
import java.util.Set;
public class ResearchTasksListener implements EventListener {
@Getter private static final Set<String> researchTasks = new LinkedHashSet<>();
@Override
public void onTabListUpdate(Text header, Text footer) {
String footerString = footer.getString();
String[] lines = footerString.split("\n");
researchTasks.clear();
boolean found = false;
for (String part : lines) {
String partStripped = TextUtils.stripColors(part);
if (partStripped.contains("RESEARCH TASKS")) {
found = true;
continue;
}
if (!found) {
continue;
}
if (partStripped.isEmpty()) { // Don't overflow into other data
break;
}
researchTasks.add(TextUtils.removeColorCode(part, "§o"));
}
}
}

@ -13,8 +13,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftClient.class) @Mixin(MinecraftClient.class)
public class MinecraftClientMixin { public class MinecraftClientMixin {
/**
* The total amount of ticks since mod initialization
*/
private int ticksPassed = 0;
@Inject(method = "tick", at = @At("HEAD")) @Inject(method = "tick", at = @At("HEAD"))
public void onTick(CallbackInfo ci) { public void onTick(CallbackInfo ci) {
ticksPassed++;
if (!PlayerUtils.isOnWild()) { // Ignore if the player isn't on Wild if (!PlayerUtils.isOnWild()) { // Ignore if the player isn't on Wild
return; return;
} }
@ -22,7 +28,7 @@ public class MinecraftClientMixin {
return; return;
} }
for (EventListener listener : EventManager.getListeners()) { for (EventListener listener : EventManager.getListeners()) {
listener.onTick(); listener.onTick(ticksPassed);
} }
} }
} }

@ -0,0 +1,46 @@
package cc.fascinated.wildaddons.mixin;
import cc.fascinated.wildaddons.addon.impl.ui.OverlayAddon;
import cc.fascinated.wildaddons.event.EventListener;
import cc.fascinated.wildaddons.event.EventManager;
import cc.fascinated.wildaddons.utils.TextUtils;
import net.minecraft.client.gui.hud.PlayerListHud;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerListHud.class)
public class PlayerListGuiMixin {
private Text header;
private Text footer;
@Inject(method = "setHeader", at = @At(value = "HEAD"))
public void setHeader(Text header, CallbackInfo ci) {
this.header = header;
update();
}
@Inject(method = "setFooter", at = @At(value = "HEAD"))
public void setFooter(Text footer, CallbackInfo ci) {
this.footer = footer;
update();
}
/**
* Send out to listeners that the tab-list has changed.
*/
private void update() {
if (header == null || footer == null) {
return;
}
for (EventListener listener : EventManager.getListeners()) {
listener.onTabListUpdate(header, footer);
}
}
}

@ -8,13 +8,16 @@ import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.SerializationException;
import java.util.*; import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
@Getter @RequiredArgsConstructor @Getter @RequiredArgsConstructor
public enum Statistic { public enum Statistic {
PLAYERS_WELCOMED("players-welcomed"), PLAYERS_WELCOMED("Players Welcomed", "players-welcomed"),
FILTERED_MESSAGES("filtered-messages"); FILTERED_MESSAGES("Filtered Messages","filtered-messages");
/** /**
* The in memory storage for all statistics * The in memory storage for all statistics
@ -26,6 +29,11 @@ public enum Statistic {
*/ */
private static boolean dirty; private static boolean dirty;
/**
* The display name for the statistic
*/
private final String name;
/** /**
* The key used in the storage * The key used in the storage
*/ */

@ -13,7 +13,7 @@ public class TpsMonitor implements EventListener {
private static long worldTicks = 0; private static long worldTicks = 0;
@Override @Override
public void onPacketReceive(Packet<?> packet) { public void onPacketReceive(Packet<?> packet) { // TODO: move to its own thread?
if (!(packet instanceof WorldTimeUpdateS2CPacket)) { if (!(packet instanceof WorldTimeUpdateS2CPacket)) {
return; return;
} }
@ -51,6 +51,16 @@ public class TpsMonitor implements EventListener {
public static String getFormattedTPS() { public static String getFormattedTPS() {
float tps = Math.max(calculateServerTPS(), 0); float tps = Math.max(calculateServerTPS(), 0);
return tps > 20.00 ? "20.00*" : NumberUtils.format(tps); String tpsFormatted = tps > 20.00 ? "20.00*" : NumberUtils.format(tps);
if (tps > 18) {
tpsFormatted = "§a" + tpsFormatted;
} else if (tps > 15) {
tpsFormatted = "§e" + tpsFormatted;
} else if (tps > 10) {
tpsFormatted = "§c" + tpsFormatted;
} else {
tpsFormatted = "§4" + tpsFormatted;
}
return tpsFormatted;
} }
} }

@ -1,11 +1,9 @@
package cc.fascinated.wildaddons.utils; package cc.fascinated.wildaddons.utils;
import cc.fascinated.wildaddons.Main;
import lombok.Getter; import lombok.Getter;
import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.hocon.HoconConfigurationLoader; import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
import org.spongepowered.configurate.loader.ConfigurationLoader; import org.spongepowered.configurate.loader.ConfigurationLoader;

@ -0,0 +1,31 @@
package cc.fascinated.wildaddons.utils;
import cc.fascinated.wildaddons.Main;
public class GameUtils {
/**
* Gets the current fps
*
* @return the fps
*/
public static int getFps() {
return Main.getMinecraftClient().getCurrentFps();
}
/**
* Gets the current fps formatted with colors
*
* @return the fps
*/
public static String getFpsFormatted() {
int fps = getFps();
if (fps > 60) {
return "§a" + fps;
}
if (fps > 30) {
return "§e" + fps;
}
return "§c" + fps;
}
}

@ -5,11 +5,23 @@ import java.text.DecimalFormat;
public class NumberUtils { public class NumberUtils {
private static final DecimalFormat formatter = new DecimalFormat("##.##"); private static final DecimalFormat formatter = new DecimalFormat("##.##");
private static final DecimalFormat commaFormatter = new DecimalFormat("#,###");
static { static {
formatter.setMinimumFractionDigits(2); formatter.setMinimumFractionDigits(2);
formatter.setMaximumFractionDigits(2); formatter.setMaximumFractionDigits(2);
} }
/**
* Formats the given number.
*
* @param number the number to format
* @param withCommas use commas
* @return the formatted number
*/
public static String format(Object number, boolean withCommas) {
return withCommas ? commaFormatter.format(number) : formatter.format(number);
}
/** /**
* Formats the given number. * Formats the given number.
* *
@ -17,6 +29,6 @@ public class NumberUtils {
* @return the formatted number * @return the formatted number
*/ */
public static String format(Object number) { public static String format(Object number) {
return formatter.format(number); return format(number, false);
} }
} }

@ -42,4 +42,17 @@ public class PlayerUtils {
public static boolean isOnWild() { public static boolean isOnWild() {
return onServer("wildprison.net", "wildnetwork.net"); return onServer("wildprison.net", "wildnetwork.net");
} }
/**
* Gets the current servers ip
*
* @return the ip
*/
public static String getCurrentServerIp() {
ServerInfo currentServerEntry = Main.getMinecraftClient().getCurrentServerEntry();
if (currentServerEntry == null) {
return null;
}
return currentServerEntry.address;
}
} }

@ -9,6 +9,16 @@ public class TextUtils {
* @return the stripped string * @return the stripped string
*/ */
public static String stripColors(String message) { public static String stripColors(String message) {
return message.replaceAll("(?i)§[0-9A-FK-OR]/g", ""); return message.replaceAll("§.", "");
}
/**
* Removes the given color code from the message
*
* @param message the message to modify
* @return the changed message
*/
public static String removeColorCode(String message, String colorCode) {
return message.replaceAll(colorCode, "");
} }
} }

@ -19,7 +19,7 @@
] ]
}, },
"mixins": [ "mixins": [
"WildAddons.mixins.json" "wildaddons.mixins.json"
], ],
"depends": { "depends": {
"fabricloader": ">=0.14.17", "fabricloader": ">=0.14.17",

@ -6,10 +6,10 @@
"mixins": [ "mixins": [
"ChatHudMixin", "ChatHudMixin",
"ClientConnectionMixin", "ClientConnectionMixin",
"MinecraftClientMixin" "MinecraftClientMixin",
], "PlayerListGuiMixin"
"client": [
], ],
"client": [],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
} }