diff --git a/README.md b/README.md index 268201e..3466bd0 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,14 @@ As a challenge I'm trying to make it as user-friendly as possible. (It ain't the - /spectator | Essentially server-side free-cam, you get put in spectator and are able to fly around, once you use the command again you get put back to where you were. - /slimechunk (/sc) | See if you're currently in a slimechunk +# Currently working on 1.3.2 + +## Server Side +- [x] Chat Calculator + ## Client Side -- Teleportation Angle Viewer +- [x] Teleportation Angle Viewer ![Teleportation Keybindings](https://i.imgur.com/gjO1H3d.png) # Features to come diff --git a/src/main/java/wtf/hak/survivalfabric/config/Config.java b/src/main/java/wtf/hak/survivalfabric/config/Config.java index 9456ee0..3ab7c72 100644 --- a/src/main/java/wtf/hak/survivalfabric/config/Config.java +++ b/src/main/java/wtf/hak/survivalfabric/config/Config.java @@ -38,6 +38,8 @@ public class Config { public boolean veinMinerEnabled = true; public int maxVeinSize = 99999; + public boolean chatCalcEnabled = true; + public ScreenHandlerType screenHandlerType() { return switch (sharedEnderChestRows) { case 1 -> ScreenHandlerType.GENERIC_9X1; diff --git a/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java b/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java index bd88e19..e97cc76 100644 --- a/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java +++ b/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java @@ -18,6 +18,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import wtf.hak.survivalfabric.commands.SpectatorCommand; import wtf.hak.survivalfabric.config.ConfigManager; +import java.awt.*; +import java.beans.Expression; import java.util.Objects; import java.util.Set; @@ -53,9 +55,74 @@ public abstract class PlayerManagerMixin { @Inject(method = {"broadcast(Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/network/message/MessageType$Parameters;)V"}, at = {@At("HEAD")}, cancellable = true) private void onBroadcast(SignedMessage message, ServerPlayerEntity sender, MessageType.Parameters parameters, CallbackInfo ci) { if(sender != null && ConfigManager.getConfig().chatMessageEnabled) { - Text text = Text.literal(String.format(ConfigManager.getConfig().chatMessage, sender.getName().getString(), message.getContent().getString())); - Objects.requireNonNull(sender.getServer()).getPlayerManager().broadcast(text, false); + String rawMessage = message.getContent().getString().trim(); + if(sender != null && ConfigManager.getConfig().chatCalcEnabled && rawMessage.endsWith("=")) { + String expression = rawMessage.substring(0, rawMessage.length() - 1).trim(); + try { + String result = String.valueOf(evaluateExpression(expression)); + if(rawMessage.contains(" ")) rawMessage += " "; + rawMessage += (result.endsWith(".0")) ? result.substring(0, result.length() - 2) : result; + } catch (Exception e) {} + } + Text text = Text.literal(String.format(ConfigManager.getConfig().chatMessage, sender.getName().getString(), rawMessage)); + sender.getServer().getPlayerManager().broadcast(text, false); ci.cancel(); + } else if (sender != null && ConfigManager.getConfig().chatCalcEnabled) { + String rawMessage = message.getContent().getString().trim(); + if (rawMessage.endsWith("=")) { + String expression = rawMessage.substring(0, rawMessage.length() - 1).trim(); + try { + String result = String.valueOf(evaluateExpression(expression)); + if(rawMessage.contains(" ")) rawMessage += " "; + rawMessage += (result.endsWith(".0")) ? result.substring(0, result.length() - 2) : result; + Text formattedMessage = Text.literal("<" + sender.getName().getString() + "> " + rawMessage); + sender.getServer().getPlayerManager().broadcast(formattedMessage, false); + ci.cancel(); + } catch (Exception e) {} + } } } + + private double evaluateExpression(String expression) { + return evaluate(expression.replaceAll("\\s", ""), new int[]{0}); + } + + private double evaluate(String expr, int[] index) { + double value = parseTerm(expr, index); + while (index[0] < expr.length()) { + char op = expr.charAt(index[0]); + if (op != '+' && op != '-') break; + index[0]++; + double nextTerm = parseTerm(expr, index); + value = (op == '+') ? value + nextTerm : value - nextTerm; + } + return value; + } + + private double parseTerm(String expr, int[] index) { + double value = parseFactor(expr, index); + while (index[0] < expr.length()) { + char op = expr.charAt(index[0]); + if (op != '*' && op != '/') break; + index[0]++; + double nextFactor = parseFactor(expr, index); + value = (op == '*') ? value * nextFactor : value / nextFactor; + } + return value; + } + + private double parseFactor(String expr, int[] index) { + if (expr.charAt(index[0]) == '(') { + index[0]++; + double value = evaluate(expr, index); + index[0]++; // Skip closing ')' + return value; + } + + int start = index[0]; + while (index[0] < expr.length() && (Character.isDigit(expr.charAt(index[0])) || expr.charAt(index[0]) == '.')) { + index[0]++; + } + return Double.parseDouble(expr.substring(start, index[0])); + } }