Skip to content

Commit

Permalink
Prevent sending messages when placeholders fail
Browse files Browse the repository at this point in the history
  • Loading branch information
NotRyken committed Nov 18, 2024
1 parent 4f41f98 commit bbde2ca
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 37 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Add activation ratelimiter
- Add reversal key for cycling macros
- Add placeholder for targeted block
- Prevent sending messages when placeholders fail
46 changes: 33 additions & 13 deletions common/src/main/java/dev/terminalmc/commandkeys/CommandKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package dev.terminalmc.commandkeys;

import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.datafixers.util.Pair;
import dev.terminalmc.commandkeys.config.Config;
import dev.terminalmc.commandkeys.config.Macro;
import dev.terminalmc.commandkeys.config.Profile;
Expand All @@ -30,6 +31,7 @@
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -119,22 +121,40 @@ public static boolean canTrigger(InputConstants.Key key) {
}

public static void send(String message, boolean addToHistory, boolean showHudMsg) {
send(false, message, addToHistory, showHudMsg);
}

public static void type(String message) {
send(true, message, false, false);
}

public static void send(boolean type, String message, boolean addToHistory, boolean showHudMsg) {
Minecraft mc = Minecraft.getInstance();
if (mc.player == null) return;
message = PlaceholderUtil.replace(message);
// new ChatScreen("").handleChatInput(message, addToHistory)
// could be slightly better for compat but costs performance.
if (message.startsWith("/")) {
mc.player.connection.sendCommand(message.substring(1));
Pair<String,Integer> result = PlaceholderUtil.replace(message);
message = result.getFirst();
int faults = result.getSecond();
if (faults == 0) {
if (type) {
mc.setScreen(new ChatScreen(message));
} else {
// new ChatScreen("").handleChatInput(message, addToHistory)
// could be slightly better for compat but costs performance.
if (message.startsWith("/")) {
mc.player.connection.sendCommand(message.substring(1));
} else {
mc.player.connection.sendChat(message);
}
if (addToHistory) mc.gui.getChat().addRecentChat(message);
if (showHudMsg) mc.gui.setOverlayMessage(Component.literal(message)
.withStyle(ChatFormatting.GRAY), false);
}
} else {
mc.player.connection.sendChat(message);
MutableComponent msg = PREFIX.copy();
msg.append(localized("message", "placeholderFault",
Component.literal(message).withStyle(ChatFormatting.GRAY))
.withStyle(ChatFormatting.RED));
mc.gui.getChat().addMessage(msg);
}
if (addToHistory) mc.gui.getChat().addRecentChat(message);
if (showHudMsg) mc.gui.setOverlayMessage(Component.literal(message)
.withStyle(ChatFormatting.GRAY), false);
}

public static void type(String message) {
Minecraft.getInstance().setScreen(new ChatScreen(PlaceholderUtil.replace(message)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package dev.terminalmc.commandkeys.util;

import com.mojang.datafixers.util.Pair;
import dev.terminalmc.commandkeys.CommandKeys;
import dev.terminalmc.commandkeys.mixin.accessor.ChatComponentAccessor;
import net.minecraft.client.GuiMessage;
Expand All @@ -40,9 +41,7 @@

public class PlaceholderUtil {

// Entity.pick for blocks
// ProjectileUtil.getEntityHitResult for entities

private static int faults;
private static @Nullable BlockPos playerBlockPos;
private static @Nullable BlockPos lookBlockPos;
private static @Nullable Vec3 lookAngle;
Expand Down Expand Up @@ -81,21 +80,27 @@ public class PlaceholderUtil {
* Breaks if player is not in-game. Does not self-check for performance
* reasons, but expects caller to validate.
*/
public static String replace(String message) {
if (!message.contains("%")) return message;
clearCache();
public static Pair<String,Integer> replace(String message) {
if (!message.contains("%")) return new Pair<>(message, 0);
reset();
for (SimplePlaceholder p : SIMPLE_PLACEHOLDERS) message = p.process(message);
for (Placeholder p : REGEX_PLACEHOLDERS) message = p.process(message);

return message;
return new Pair<>(message, faults);
}

private static void clearCache() {
private static void reset() {
faults = 0;
playerBlockPos = null;
lookBlockPos = null;
lookAngle = null;
pmSenderName = null;
}

private static String fault() {
faults++;
return "?";
}

private record SimplePlaceholder(String string, Supplier<String> supplier) {
public String process(String message) {
Expand Down Expand Up @@ -134,7 +139,7 @@ private static String getRecentChat(@NotNull String[] pattern) {
return matcher.group(1);
} catch (IndexOutOfBoundsException e) {
CommandKeys.LOG.error("Recent chat placeholder failed: Group 1 not available: " + e);
return "?";
return fault();
}
}
}
Expand All @@ -144,7 +149,7 @@ private static String getRecentChat(@NotNull String[] pattern) {
CommandKeys.LOG.error("Recent chat placeholder failed: Invalid regex: " + e);
}

return "?";
return fault();
}

// Clipboard
Expand All @@ -153,17 +158,17 @@ private static String getClipboard(@Nullable String[] pattern) {
String clipboard = Minecraft.getInstance().keyboardHandler.getClipboard();
if (clipboard.isEmpty()) {
CommandKeys.LOG.warn("Clipboard placeholder failed: No data");
return "?";
return fault();
}
if (pattern != null) {
try {
if (!Pattern.compile(pattern[0]).matcher(clipboard).find()) {
CommandKeys.LOG.warn("Clipboard placeholder failed: Non-matching regex");
return "?";
return fault();
}
} catch (PatternSyntaxException e) {
CommandKeys.LOG.warn("Clipboard placeholder failed: Invalid regex: " + e);
return "?";
return fault();
}
}
return clipboard;
Expand All @@ -173,7 +178,7 @@ private static String getClipboard(@Nullable String[] pattern) {

private static String getLastMessage() {
String lastMsg = Minecraft.getInstance().gui.getChat().getRecentChat().peekLast();
if (lastMsg == null) return "?";
if (lastMsg == null) return fault();
return lastMsg;
}

Expand All @@ -184,7 +189,7 @@ private static String getLastCommand() {
} else {
CommandKeys.LOG.error("Command history not ArrayListDeque");
}
return "?";
return fault();
}

// Player name
Expand All @@ -210,7 +215,7 @@ private static String getPmSenderName() {
}
if (pmSenderName == null) {
CommandKeys.LOG.warn("PmSenderName placeholder failed: No message found: Checked " + i);
return "?";
return fault();
}
return pmSenderName;
}
Expand All @@ -224,6 +229,7 @@ private static BlockPos updatePlayerBlockPos() {
}

private static BlockPos updateLookBlockPos() {
// Note: ProjectileUtil.getEntityHitResult for entities
if (lookBlockPos == null) {
Minecraft mc = Minecraft.getInstance();
// Distance is arbitrary but will do for now
Expand All @@ -243,7 +249,7 @@ private static Vec3 updateLookAngle() {
}

private static String getPlayerBlockPos(String[] args) {
if (updatePlayerBlockPos() == null || updateLookAngle() == null) return "? ? ?";
if (updatePlayerBlockPos() == null || updateLookAngle() == null) return fault();
int offset = Integer.parseInt(args[1]);
Vec3 playerPos = playerBlockPos.getBottomCenter();
if (offset != 0) playerPos = offsetCardinalDirection(
Expand All @@ -253,22 +259,22 @@ private static String getPlayerBlockPos(String[] args) {
}

private static String getPlayerBlockX(String[] offset) {
if (updatePlayerBlockPos() == null) return "?";
if (updatePlayerBlockPos() == null) return fault();
return String.valueOf(Mth.floor(playerBlockPos.getX()) + Integer.parseInt(offset[0]));
}

private static String getPlayerBlockY(String[] offset) {
if (updatePlayerBlockPos() == null) return "?";
if (updatePlayerBlockPos() == null) return fault();
return String.valueOf(Mth.floor(playerBlockPos.getY()) + Integer.parseInt(offset[0]));
}

private static String getPlayerBlockZ(String[] offset) {
if (updatePlayerBlockPos() == null) return "?";
if (updatePlayerBlockPos() == null) return fault();
return String.valueOf(Mth.floor(playerBlockPos.getZ()) + Integer.parseInt(offset[0]));
}

private static String getLookBlockPos(String[] args) {
if (updateLookBlockPos() == null || updateLookAngle() == null) return "? ? ?";
if (updateLookBlockPos() == null || updateLookAngle() == null) return fault();
int offset = Integer.parseInt(args[1]);
Vec3 playerPos = lookBlockPos.getBottomCenter();
if (offset != 0) playerPos = offsetCardinalDirection(
Expand All @@ -278,17 +284,17 @@ private static String getLookBlockPos(String[] args) {
}

private static String getLookBlockX(String[] offset) {
if (updateLookBlockPos() == null) return "?";
if (updateLookBlockPos() == null) return fault();
return String.valueOf(Mth.floor(lookBlockPos.getX()) + Integer.parseInt(offset[0]));
}

private static String getLookBlockY(String[] offset) {
if (updateLookBlockPos() == null) return "?";
if (updateLookBlockPos() == null) return fault();
return String.valueOf(Mth.floor(lookBlockPos.getY()) + Integer.parseInt(offset[0]));
}

private static String getLookBlockZ(String[] offset) {
if (updateLookBlockPos() == null) return "?";
if (updateLookBlockPos() == null) return fault();
return String.valueOf(Mth.floor(lookBlockPos.getZ()) + Integer.parseInt(offset[0]));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"key.commandkeys.main": "CommandKeys",
"key.commandkeys.main.edit": "Aktives Profil bearbeiten",
"message.commandkeys.placeholderFault": "Message \"%s\" could not be sent because one or more placeholders failed to apply.",
"message.commandkeys.sendBlocked": "Ratelimit exceeded by key %s. Ratelimit is set to %s activations in %s ticks.",
"option.commandkeys.key": "Makro Optionen",
"option.commandkeys.key.alt.tooltip": "This key, if pressed when the macro is activated, will reverse the cycle order.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"key.commandkeys.main": "CommandKeys",
"key.commandkeys.main.edit": "Edit Active Profile",
"message.commandkeys.placeholderFault": "Message \"%s\" could not be sent because one or more placeholders failed to apply.",
"message.commandkeys.sendBlocked": "Ratelimit exceeded by key %s. Ratelimit is set to %s activations in %s ticks.",
"option.commandkeys.key": "Macro Options",
"option.commandkeys.key.alt.tooltip": "This key, if pressed when the macro is activated, will reverse the cycle order.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"key.commandkeys.main": "命令按键(CommandKeys)",
"key.commandkeys.main.edit": "编辑活动配置文件",
"message.commandkeys.placeholderFault": "Message \"%s\" could not be sent because one or more placeholders failed to apply.",
"message.commandkeys.sendBlocked": "Ratelimit exceeded by key %s. Ratelimit is set to %s activations in %s ticks.",
"option.commandkeys.key": "宏选项",
"option.commandkeys.key.alt.tooltip": "This key, if pressed when the macro is activated, will reverse the cycle order.",
Expand Down

0 comments on commit bbde2ca

Please sign in to comment.