Clean repo for open source release
Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
This commit is contained in:
176
src/main/java/com/tiedup/remake/commands/BountyCommand.java
Normal file
176
src/main/java/com/tiedup/remake/commands/BountyCommand.java
Normal file
@@ -0,0 +1,176 @@
|
||||
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.TiedUpMod;
|
||||
import com.tiedup.remake.state.IBondageState;
|
||||
import com.tiedup.remake.util.KidnappedHelper;
|
||||
import com.tiedup.remake.core.SettingsAccessor;
|
||||
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>
|
||||
*
|
||||
* Phase 17: Bounty System
|
||||
*
|
||||
* 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.literal(
|
||||
"You cannot put a bounty on yourself!"
|
||||
).withStyle(ChatFormatting.RED)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if player is tied up
|
||||
IBondageState playerState = KidnappedHelper.getKidnappedState(player);
|
||||
if (playerState != null && playerState.isTiedUp()) {
|
||||
source.sendFailure(
|
||||
Component.literal(
|
||||
"You cannot create bounties while 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.literal(
|
||||
"Maximum number (" + max + ") of active bounties reached!"
|
||||
).withStyle(ChatFormatting.RED)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Must hold an item as reward
|
||||
ItemStack heldItem = player.getMainHandItem();
|
||||
if (heldItem.isEmpty()) {
|
||||
source.sendFailure(
|
||||
Component.literal(
|
||||
"You must hold an item as the reward!"
|
||||
).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.literal(
|
||||
"Bounty created on " + target.getName().getString() + "!"
|
||||
).withStyle(ChatFormatting.GREEN),
|
||||
false
|
||||
);
|
||||
|
||||
// Broadcast to all players
|
||||
player.server
|
||||
.getPlayerList()
|
||||
.broadcastSystemMessage(
|
||||
Component.literal(
|
||||
"[Bounty] " +
|
||||
player.getName().getString() +
|
||||
" has put a bounty on " +
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user