Files
TiedUp-/src/main/java/com/tiedup/remake/events/system/ChatEventHandler.java
NotEvil 9b2c5dec8e chore(P2): V1 zombie comments cleanup + i18n events/network/items
Zombie comments (14 files):
- Replace references to deleted V1 classes (ItemBind, ItemCollar, IBondageItem,
  BindVariant, etc.) with V2 equivalents or past-tense historical notes
- "V1 path" → "legacy slot-index path" for still-active legacy codepaths
- Clean misleading javadoc that implied V1 code was still present

i18n (13 files, 31 new keys):
- Events: 12 Component.literal() → translatable (labor tools, gag eat,
  death escape, debt, punishment, grace, camp protection, chest, maid)
- Network: 12 Component.literal() → translatable (trader messages,
  lockpick jam, slave freedom warnings)
- Items: 2 Component.literal() → translatable (ItemOwnerTarget tooltips)
2026-04-16 11:20:17 +02:00

210 lines
7.7 KiB
Java

package com.tiedup.remake.events.system;
import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.GagTalkManager;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.GagMaterial;
import com.tiedup.remake.v2.bondage.component.ComponentType;
import com.tiedup.remake.v2.bondage.component.GaggingComponent;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.util.TiedUpUtils;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import java.util.List;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
/**
* ChatEventHandler - Intercepts chat messages to apply gag effects.
* Evolution: Implements proximity-based chat for gagged players.
*
*
* Security fix: Now blocks communication commands (/msg, /tell, etc.) when gagged
* to prevent gag bypass exploit
*/
@Mod.EventBusSubscriber(modid = TiedUpMod.MOD_ID)
public class ChatEventHandler {
/** List of communication commands that should be blocked when gagged */
private static final String[] BLOCKED_COMMANDS = {
"msg",
"tell",
"w",
"whisper",
"r",
"reply",
"me",
};
@SubscribeEvent
public static void onPlayerChat(ServerChatEvent event) {
ServerPlayer player = event.getPlayer();
IBondageState state = KidnappedHelper.getKidnappedState(player);
if (state != null && state.isGagged()) {
ItemStack gagStack = V2EquipmentHelper.getInRegion(
player,
BodyRegionV2.MOUTH
);
// V2: check gagging component
GaggingComponent gaggingComp = DataDrivenBondageItem.getComponent(
gagStack, ComponentType.GAGGING, GaggingComponent.class);
boolean isGagItem = gaggingComp != null;
if (!gagStack.isEmpty() && isGagItem) {
String originalMessage = event.getRawText();
// V2: get material from GaggingComponent
GagMaterial material = null;
if (gaggingComp != null) {
material = gaggingComp.getMaterial();
}
// material stays null if no component; GagTalkManager handles null → CLOTH fallback
// 1. Process the message through our GagTalkManager V2
Component muffledMessage = GagTalkManager.processGagMessage(
state,
gagStack,
originalMessage
);
// 2. Proximity Chat Logic
boolean useProximity =
SettingsAccessor.isGagTalkProximityEnabled(
player.level().getGameRules()
);
if (useProximity) {
// Cancel global and send to nearby
event.setCanceled(true);
Component finalChat = Component.literal("<")
.append(player.getDisplayName())
.append("> ")
.append(muffledMessage);
double range = material != null
? material.getTalkRange()
: (gaggingComp != null ? gaggingComp.getRange() : 10.0);
List<ServerPlayer> nearbyPlayers =
TiedUpUtils.getPlayersAround(
player.level(),
player.blockPosition(),
range
);
int listeners = 0;
for (ServerPlayer other : nearbyPlayers) {
// Check if receiver has earplugs (they can't hear)
IBondageState receiverState =
KidnappedHelper.getKidnappedState(other);
if (
receiverState != null && receiverState.hasEarplugs()
) {
// Can't hear - skip this player
continue;
}
other.sendSystemMessage(finalChat);
if (other != player) listeners++;
}
if (listeners == 0) {
player.displayClientMessage(
Component.translatable(
"chat.tiedup.gag.no_one_heard"
).withStyle(
net.minecraft.ChatFormatting.ITALIC,
net.minecraft.ChatFormatting.GRAY
),
true
);
}
} else {
// Just replace message but keep it global
event.setMessage(muffledMessage);
}
TiedUpMod.LOGGER.debug(
"[Chat] {} muffled message processed (Proximity: {})",
player.getName().getString(),
useProximity
);
}
}
}
/**
* Intercept commands to prevent gagged players from using communication commands.
* Blocks /msg, /tell, /w, /whisper, /r, /reply, /me when player is gagged.
*
* Security fix: Prevents gag bypass exploit via private messages
*/
@SubscribeEvent(priority = EventPriority.HIGHEST)
public static void onCommand(CommandEvent event) {
// Only check if sender is a ServerPlayer
if (
!(event
.getParseResults()
.getContext()
.getSource()
.getEntity() instanceof
ServerPlayer player)
) {
return;
}
// Check if player is gagged
IBondageState state = KidnappedHelper.getKidnappedState(player);
if (state == null || !state.isGagged()) {
return; // Not gagged, allow all commands
}
// Get the command name (first part of the command string)
String commandInput = event.getParseResults().getReader().getString();
if (commandInput.isEmpty()) {
return;
}
// Remove leading slash if present
String commandName = commandInput.startsWith("/")
? commandInput.substring(1)
: commandInput;
// Get only the first word (command name)
commandName = commandName.split(" ")[0].toLowerCase();
// Check if this is a blocked communication command
for (String blockedCmd : BLOCKED_COMMANDS) {
if (commandName.equals(blockedCmd)) {
// Block the command
event.setCanceled(true);
// Send muffled message to player
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"Mmmph! You can't use that command while gagged!"
);
TiedUpMod.LOGGER.debug(
"[Chat] Blocked command '{}' from gagged player {}",
commandName,
player.getName().getString()
);
return;
}
}
}
}