diff --git a/src/main/java/cc/fascinated/wildaddons/addon/Addon.java b/src/main/java/cc/fascinated/wildaddons/addon/Addon.java index 030623e..78a7595 100644 --- a/src/main/java/cc/fascinated/wildaddons/addon/Addon.java +++ b/src/main/java/cc/fascinated/wildaddons/addon/Addon.java @@ -16,13 +16,15 @@ public abstract class Addon implements EventListener { this.name = name; this.description = description; this.category = category; + this.enabled = true; EventManager.registerListener(this); onEnable(); } public enum Category { - CHAT + CHAT, + UI } /** diff --git a/src/main/java/cc/fascinated/wildaddons/addon/AddonManager.java b/src/main/java/cc/fascinated/wildaddons/addon/AddonManager.java index 2cc2173..1cbcdbc 100644 --- a/src/main/java/cc/fascinated/wildaddons/addon/AddonManager.java +++ b/src/main/java/cc/fascinated/wildaddons/addon/AddonManager.java @@ -1,6 +1,7 @@ package cc.fascinated.wildaddons.addon; -import cc.fascinated.wildaddons.addon.impl.chat.AutoWelcomer; +import cc.fascinated.wildaddons.addon.impl.chat.AutoWelcomerAddon; +import cc.fascinated.wildaddons.addon.impl.ui.OverlayAddon; import java.util.HashSet; import java.util.Set; @@ -13,7 +14,8 @@ public class AddonManager { public static final Set ADDONS = new HashSet<>(); public AddonManager() { - registerAddon(new AutoWelcomer()); + registerAddon(new AutoWelcomerAddon()); + registerAddon(new OverlayAddon()); } /** diff --git a/src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomer.java b/src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomerAddon.java similarity index 90% rename from src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomer.java rename to src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomerAddon.java index 4a60a07..389e808 100644 --- a/src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomer.java +++ b/src/main/java/cc/fascinated/wildaddons/addon/impl/chat/AutoWelcomerAddon.java @@ -8,9 +8,9 @@ import cc.fascinated.wildaddons.utils.PlayerUtils; import java.util.concurrent.ThreadLocalRandom; -public class AutoWelcomer extends Addon { +public class AutoWelcomerAddon extends Addon { - public AutoWelcomer() { + public AutoWelcomerAddon() { super("Auto Welcomer", "Automatically sends the welcome command when a new player joins.", Category.CHAT @@ -19,6 +19,9 @@ public class AutoWelcomer extends Addon { @Override public void onChat(String message, String messageStripped) { + if (!this.isEnabled()) { // This addon is disabled + return; + } if (!PlayerListener.isMoving()) { // To prevent bans lol return; } diff --git a/src/main/java/cc/fascinated/wildaddons/addon/impl/ui/OverlayAddon.java b/src/main/java/cc/fascinated/wildaddons/addon/impl/ui/OverlayAddon.java new file mode 100644 index 0000000..1536b16 --- /dev/null +++ b/src/main/java/cc/fascinated/wildaddons/addon/impl/ui/OverlayAddon.java @@ -0,0 +1,32 @@ +package cc.fascinated.wildaddons.addon.impl.ui; + +import cc.fascinated.wildaddons.Main; +import cc.fascinated.wildaddons.addon.Addon; +import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor; +import cc.fascinated.wildaddons.utils.NumberUtils; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.network.Packet; +import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; + +public class OverlayAddon extends Addon { + + public OverlayAddon() { + super("Overlay", "Adds basic client and server info to the overlay", Category.UI); + } + + @Override + public void onEnable() { + HudRenderCallback.EVENT.register((matrixStack, somefloatidkwhatitdoes) -> { + if (!this.isEnabled()) { + return; + } + + MinecraftClient minecraftClient = Main.getMinecraftClient(); + TextRenderer renderer = minecraftClient.textRenderer; + renderer.drawWithShadow(matrixStack, "FPS: " + minecraftClient.getCurrentFps(), 5, 5, 0xffffff); + renderer.drawWithShadow(matrixStack, "TPS: " + TpsMonitor.getFormattedTPS(), 5, 16, 0xffffff); + }); + } +} diff --git a/src/main/java/cc/fascinated/wildaddons/client/WildAddonsClient.java b/src/main/java/cc/fascinated/wildaddons/client/WildAddonsClient.java index 5fea1e7..afc7b99 100644 --- a/src/main/java/cc/fascinated/wildaddons/client/WildAddonsClient.java +++ b/src/main/java/cc/fascinated/wildaddons/client/WildAddonsClient.java @@ -3,6 +3,7 @@ package cc.fascinated.wildaddons.client; import cc.fascinated.wildaddons.addon.AddonManager; import cc.fascinated.wildaddons.event.EventManager; import cc.fascinated.wildaddons.listener.PlayerListener; +import cc.fascinated.wildaddons.tpsmonitor.TpsMonitor; import net.fabricmc.api.ClientModInitializer; public class WildAddonsClient implements ClientModInitializer { @@ -15,5 +16,6 @@ public class WildAddonsClient implements ClientModInitializer { new AddonManager(); EventManager.registerListener(new PlayerListener()); + EventManager.registerListener(new TpsMonitor()); } } diff --git a/src/main/java/cc/fascinated/wildaddons/event/EventListener.java b/src/main/java/cc/fascinated/wildaddons/event/EventListener.java index 28e0821..8a9fd30 100644 --- a/src/main/java/cc/fascinated/wildaddons/event/EventListener.java +++ b/src/main/java/cc/fascinated/wildaddons/event/EventListener.java @@ -1,5 +1,7 @@ package cc.fascinated.wildaddons.event; +import net.minecraft.network.Packet; + public interface EventListener { default void onTick() {} @@ -11,4 +13,18 @@ public interface EventListener { * @param messageStripped the message without colors */ default void onChat(String message, String messageStripped) {} + + /** + * Gets called when the client receives a packet. + * + * @param packet the packet + */ + default void onPacketReceive(Packet packet) {} + + /** + * Gets called when the client sends a packet. + * + * @param packet the packet + */ + default void onPacketSend(Packet packet) {} } diff --git a/src/main/java/cc/fascinated/wildaddons/mixin/PlayerMixin.java b/src/main/java/cc/fascinated/wildaddons/mixin/ChatHudMixin.java similarity index 98% rename from src/main/java/cc/fascinated/wildaddons/mixin/PlayerMixin.java rename to src/main/java/cc/fascinated/wildaddons/mixin/ChatHudMixin.java index ca5e1ac..97a5de9 100644 --- a/src/main/java/cc/fascinated/wildaddons/mixin/PlayerMixin.java +++ b/src/main/java/cc/fascinated/wildaddons/mixin/ChatHudMixin.java @@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ChatHud.class) -public class PlayerMixin { +public class ChatHudMixin { @Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;ILnet/minecraft/client/gui/hud/MessageIndicator;Z)V", at = @At("HEAD")) public void onChat(Text text, MessageSignatureData signature, int ticks, MessageIndicator indicator, boolean refresh, CallbackInfo ci) { diff --git a/src/main/java/cc/fascinated/wildaddons/mixin/ClientConnectionMixin.java b/src/main/java/cc/fascinated/wildaddons/mixin/ClientConnectionMixin.java new file mode 100644 index 0000000..6827787 --- /dev/null +++ b/src/main/java/cc/fascinated/wildaddons/mixin/ClientConnectionMixin.java @@ -0,0 +1,29 @@ +package cc.fascinated.wildaddons.mixin; + +import cc.fascinated.wildaddons.event.EventListener; +import cc.fascinated.wildaddons.event.EventManager; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.network.ClientConnection; +import net.minecraft.network.Packet; +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(ClientConnection.class) +public class ClientConnectionMixin { + + @Inject(method = "send(Lnet/minecraft/network/Packet;)V", at = @At("HEAD")) + public void send(Packet packet, CallbackInfo ci) { + for (EventListener listener : EventManager.getListeners()) { + listener.onPacketSend(packet); + } + } + + @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/Packet;)V", at = @At("HEAD")) + public void channelRead0(ChannelHandlerContext channelHandlerContext, Packet packet, CallbackInfo ci) { + for (EventListener listener : EventManager.getListeners()) { + listener.onPacketReceive(packet); + } + } +} diff --git a/src/main/java/cc/fascinated/wildaddons/mixin/MinecraftClientMixin.java b/src/main/java/cc/fascinated/wildaddons/mixin/MinecraftClientMixin.java index 679bc65..435eae3 100644 --- a/src/main/java/cc/fascinated/wildaddons/mixin/MinecraftClientMixin.java +++ b/src/main/java/cc/fascinated/wildaddons/mixin/MinecraftClientMixin.java @@ -5,6 +5,7 @@ import cc.fascinated.wildaddons.event.EventListener; import cc.fascinated.wildaddons.event.EventManager; import cc.fascinated.wildaddons.utils.PlayerUtils; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/cc/fascinated/wildaddons/tpsmonitor/TpsMonitor.java b/src/main/java/cc/fascinated/wildaddons/tpsmonitor/TpsMonitor.java new file mode 100644 index 0000000..bd302c6 --- /dev/null +++ b/src/main/java/cc/fascinated/wildaddons/tpsmonitor/TpsMonitor.java @@ -0,0 +1,57 @@ +package cc.fascinated.wildaddons.tpsmonitor; + +import cc.fascinated.wildaddons.event.EventListener; +import cc.fascinated.wildaddons.utils.NumberUtils; +import com.google.common.collect.EvictingQueue; +import lombok.Getter; +import net.minecraft.network.Packet; +import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; + +public class TpsMonitor implements EventListener { + + private static final EvictingQueue serverTPS = EvictingQueue.create(3); + private static long systemTime = 0; + private static long worldTicks = 0; + + @Override + public void onPacketReceive(Packet packet) { + if (!(packet instanceof WorldTimeUpdateS2CPacket)) { + return; + } + WorldTimeUpdateS2CPacket updatePacket = (WorldTimeUpdateS2CPacket) packet; + long currentWorldTicks = updatePacket.getTime(); + + if (systemTime == 0) { + systemTime = System.currentTimeMillis(); + } + long currentSystemTime = System.currentTimeMillis(); + serverTPS.add((((float) (currentWorldTicks - worldTicks)) / (((float) (currentSystemTime - systemTime)) / 50.0f)) * 20.0f); + systemTime = System.currentTimeMillis(); + worldTicks = currentWorldTicks; + } + + /** + * Gets the average server TPS + * of the last 3 seconds. + * + * @return the tps + */ + public static float calculateServerTPS() { + float sum = 0.0f; + for (Float f : serverTPS) { + sum += f; + } + return sum / (float) serverTPS.size(); + } + + /** + * Get the TPS formatted + * + * @return the formatted tps + */ + public static String getFormattedTPS() { + float tps = calculateServerTPS(); + + return tps > 20.00 ? "20.00*" : NumberUtils.format(tps); + } +} diff --git a/src/main/java/cc/fascinated/wildaddons/utils/NumberUtils.java b/src/main/java/cc/fascinated/wildaddons/utils/NumberUtils.java new file mode 100644 index 0000000..b79fd06 --- /dev/null +++ b/src/main/java/cc/fascinated/wildaddons/utils/NumberUtils.java @@ -0,0 +1,22 @@ +package cc.fascinated.wildaddons.utils; + +import java.text.DecimalFormat; + +public class NumberUtils { + + private static final DecimalFormat formatter = new DecimalFormat("##.##"); + static { + formatter.setMinimumFractionDigits(2); + formatter.setMaximumFractionDigits(2); + } + + /** + * Formats the given number. + * + * @param number the number to format + * @return the formatted number + */ + public static String format(Object number) { + return formatter.format(number); + } +} diff --git a/src/main/resources/WildAddons.mixins.json b/src/main/resources/WildAddons.mixins.json index 4787f13..de81d2b 100644 --- a/src/main/resources/WildAddons.mixins.json +++ b/src/main/resources/WildAddons.mixins.json @@ -4,7 +4,8 @@ "package": "cc.fascinated.wildaddons.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "PlayerMixin", + "ChatHudMixin", + "ClientConnectionMixin", "MinecraftClientMixin" ], "client": [