Files
TiedUp-/src/main/java/com/tiedup/remake/commands/BountyCommand.java
NotEvil fa5cfb913c feat(C-01): i18n main commands — 148 translatable keys
Phase 3: Migrate Component.literal() in all remaining command files.
- NPCCommand (34), CellCommand (33), SocialCommand (16), CollarCommand (25),
  KeyCommand (18), BountyCommand (6), KidnapSetCommand (2), CaptivityDebugCommand (7),
  InventorySubCommand (3), TestAnimSubCommand (2), MasterTestSubCommand (7), DebtSubCommand (8)
- Strip all section sign color codes, use .withStyle(ChatFormatting)
- 148 new keys in en_us.json (command.tiedup.*)
- Debug/dynamic strings intentionally kept as literal
2026-04-15 13:54:26 +02:00

174 lines
5.5 KiB
Java

package com.tiedup.remake.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.tiedup.remake.bounty.Bounty;
import com.tiedup.remake.bounty.BountyManager;
import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import java.util.Optional;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
/**
* Command: /bounty <player>
*
*
* Creates a bounty on a target player using the held item as reward.
*
* Requirements:
* - Must hold an item (the reward)
* - Cannot put bounty on yourself
* - Respects max bounties limit
* - Cannot be tied up when creating bounty
*/
public class BountyCommand {
public static void register(
CommandDispatcher<CommandSourceStack> dispatcher
) {
dispatcher.register(createBountyCommand());
TiedUpMod.LOGGER.info("Registered /bounty command");
}
/**
* Create the bounty command builder (for use as subcommand of /tiedup).
* @return The command builder
*/
public static com.mojang.brigadier.builder.LiteralArgumentBuilder<
CommandSourceStack
> createBountyCommand() {
return Commands.literal("bounty").then(
Commands.argument("target", EntityArgument.player()).executes(
BountyCommand::execute
)
);
}
private static int execute(CommandContext<CommandSourceStack> context)
throws CommandSyntaxException {
CommandSourceStack source = context.getSource();
// Must be a player
Optional<ServerPlayer> playerOpt = CommandHelper.getPlayerOrFail(
source
);
if (playerOpt.isEmpty()) return 0;
ServerPlayer player = playerOpt.get();
ServerPlayer target = EntityArgument.getPlayer(context, "target");
// Cannot bounty yourself
if (player.getUUID().equals(target.getUUID())) {
source.sendFailure(
Component.translatable(
"command.tiedup.bounty.cannot_self"
).withStyle(ChatFormatting.RED)
);
return 0;
}
// Check if player is tied up
IBondageState playerState = KidnappedHelper.getKidnappedState(player);
if (playerState != null && playerState.isTiedUp()) {
source.sendFailure(
Component.translatable(
"command.tiedup.bounty.tied_up"
).withStyle(ChatFormatting.RED)
);
return 0;
}
// Get bounty manager
BountyManager manager = BountyManager.get(player.serverLevel());
// Check bounty limit
if (!manager.canCreateBounty(player, player.serverLevel())) {
int max = SettingsAccessor.getMaxBounties(
player.serverLevel().getGameRules()
);
source.sendFailure(
Component.translatable(
"command.tiedup.bounty.max_reached", max
).withStyle(ChatFormatting.RED)
);
return 0;
}
// Must hold an item as reward
ItemStack heldItem = player.getMainHandItem();
if (heldItem.isEmpty()) {
source.sendFailure(
Component.translatable(
"command.tiedup.bounty.must_hold_item"
).withStyle(ChatFormatting.RED)
);
return 0;
}
// Get bounty duration
int duration = SettingsAccessor.getBountyDuration(
player.serverLevel().getGameRules()
);
// SECURITY FIX: Create reward with count=1 to prevent item duplication
// Bug: If player held 64 diamonds, bounty would be 64 diamonds but only cost 1
ItemStack rewardItem = heldItem.copy();
rewardItem.setCount(1);
// Create the bounty
Bounty bounty = new Bounty(
player.getUUID(),
player.getName().getString(),
target.getUUID(),
target.getName().getString(),
rewardItem,
duration
);
// Consume one item from the stack (not the entire stack!)
player.getMainHandItem().shrink(1);
// Add bounty
manager.addBounty(bounty);
// Notify player
source.sendSuccess(
() ->
Component.translatable(
"command.tiedup.bounty.created", target.getName().getString()
).withStyle(ChatFormatting.GREEN),
false
);
// Broadcast to all players
player.server
.getPlayerList()
.broadcastSystemMessage(
Component.translatable(
"command.tiedup.bounty.broadcast",
player.getName().getString(),
target.getName().getString()
).withStyle(ChatFormatting.GOLD),
false
);
TiedUpMod.LOGGER.info(
"[BOUNTY] {} created bounty on {} with reward {}",
player.getName().getString(),
target.getName().getString(),
bounty.getRewardDescription()
);
return 1;
}
}