chore(release): update to version 0.2.1

### Added
- Updated the `/suicide` command to ensure instant death via maximum magic damage.
- Introduced a 120-second cooldown for the `/suicide confirm` command.
- Added the `/silenceKill` command for administrators to silently kill players by setting their health to 0.
- Added tab-completion support for selecting online players in the `/silenceKill` command.
This commit is contained in:
itqop 2024-11-14 02:21:56 +03:00
parent 7e622a5761
commit 9d68d51e95
5 changed files with 95 additions and 14 deletions

View File

@ -4,6 +4,19 @@
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/), и проект соответствует [Семантическому Версионированию](https://semver.org/lang/ru/).
### [0.2.1] - 2024-11-14
#### Добавлено
- **PlayerActions**:
- **Команда Suicide**:
- Обновлен метод выполнения команды `/suicide` для мгновенной смерти через максимальный магический урон.
- Добавлено ограничение в 120 секунд на выполнение команды `/suicide confirm`, чтобы предотвратить спам и случайные повторные действия.
- **Команда SilenceKill**:
- Добавлена новая команда `/silenceKill <player>`, доступная администраторам.
- Команда позволяет администраторам тихо убивать выбранного игрока, устанавливая его здоровье на 0.
- Реализовано автодополнение через таб для выбора онлайн-игроков в качестве цели.
## [0.2] - 2024-11-13
### Добавлено

View File

@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/).
### [0.2.1] - 2024-11-14
#### Added
- **PlayerActions**:
- **Suicide Command**:
- Updated the method of execution for the `/suicide` command to ensure instant death via maximum magic damage.
- Introduced a 120-second cooldown for the `/suicide confirm` command to prevent spam and accidental multiple executions.
- **SilenceKill Command**:
- Added a new `/silenceKill <player>` command for administrators.
- The command allows administrators to silently kill a specified player by setting their health to 0.
- Added tab-completion support for selecting online players as targets.
## [0.2] - 2024-11-13
### Added

View File

@ -38,7 +38,7 @@ mod_name=HubMcUtils
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=All Rights Reserved
# The mod version. See https://semver.org/
mod_version=0.2.0-BETA
mod_version=0.2.1-BETA
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View File

@ -2,7 +2,6 @@ package org.itqop.hubmcutils;
import com.mojang.logging.LogUtils;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

View File

@ -2,20 +2,31 @@ package org.itqop.hubmcutils.command.list;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSources;
import java.time.Instant;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class PlayerActions {
private static final Set<String> pendingConfirmation = new HashSet<>();
private static DamageSources damageSources;
private static final Map<String, Instant> lastConfirmTime = new HashMap<>();
private static final long CONFIRM_COOLDOWN_SECONDS = 120;
public static void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("suicide")
@ -26,8 +37,8 @@ public class PlayerActions {
pendingConfirmation.add(playerName);
Component confirmMessage = Component.literal("[Нажмите здесь, чтобы подтвердить]")
.withStyle(Style.EMPTY
.withColor(0xFF5555) // Красный цвет
.withStyle(style -> style
.withColor(ChatFormatting.RED) // Красный цвет
.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/suicide confirm"))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("Подтвердите команду /suicide confirm"))));
@ -39,18 +50,63 @@ public class PlayerActions {
ServerPlayer player = context.getSource().getPlayerOrException();
String playerName = player.getName().getString();
if (pendingConfirmation.contains(playerName)) {
pendingConfirmation.remove(playerName);
player.sendSystemMessage(Component.literal("Вы приняли решение покончить с собой.").withStyle(Style.EMPTY.withColor(0xFF5555)));
player.setHealth(0.0F); // Устанавливаем здоровье игрока на 0 для мгновенной смерти
player.closeContainer(); // Закрываем окно чата или инвентаря
return Command.SINGLE_SUCCESS;
} else {
player.sendSystemMessage(Component.literal("Сначала используйте команду /suicide, чтобы запросить подтверждение.").withStyle(Style.EMPTY.withColor(0xFFFF55))); // Желтый цвет
Instant now = Instant.now();
if (lastConfirmTime.containsKey(playerName)) {
Instant lastTime = lastConfirmTime.get(playerName);
long secondsSinceLastConfirm = now.getEpochSecond() - lastTime.getEpochSecond();
if (secondsSinceLastConfirm < CONFIRM_COOLDOWN_SECONDS) {
long secondsLeft = CONFIRM_COOLDOWN_SECONDS - secondsSinceLastConfirm;
player.sendSystemMessage(Component.literal("Вы не можете использовать команду /suicide confirm прямо сейчас. Подождите еще " + secondsLeft + " секунд.")
.withStyle(ChatFormatting.YELLOW));
return Command.SINGLE_SUCCESS;
}
}
if (pendingConfirmation.contains(playerName)) {
if (damageSources == null) {
damageSources = new DamageSources(player.server.registryAccess());
}
pendingConfirmation.remove(playerName);
player.sendSystemMessage(Component.literal("Вы приняли решение покончить с собой.").withStyle(ChatFormatting.RED));
player.hurt(damageSources.indirectMagic(player, null), Float.MAX_VALUE);
player.closeContainer();
lastConfirmTime.put(playerName, now);
} else {
player.sendSystemMessage(Component.literal("Сначала используйте команду /suicide, чтобы запросить подтверждение.")
.withStyle(ChatFormatting.YELLOW));
}
return Command.SINGLE_SUCCESS;
})
)
);
dispatcher.register(Commands.literal("silenceKill")
.requires(source -> source.hasPermission(2))
.then(Commands.argument("target", StringArgumentType.string())
.suggests((context, builder) -> suggestOnlinePlayers(context.getSource(), builder)) // Автодополнение игроков
.executes(context -> {
String targetName = StringArgumentType.getString(context, "target");
ServerPlayer targetPlayer = context.getSource().getServer().getPlayerList().getPlayerByName(targetName);
if (targetPlayer != null) {
targetPlayer.setHealth(0);
context.getSource().sendSuccess(
() -> Component.literal("Игрок " + targetName + " беззвучно исчез.").withStyle(ChatFormatting.GREEN), true);
} else {
context.getSource().sendFailure(
Component.literal("Игрок с ником " + targetName + " не найден.").withStyle(ChatFormatting.RED));
}
return Command.SINGLE_SUCCESS;
})
)
);
}
private static CompletableFuture<Suggestions> suggestOnlinePlayers(CommandSourceStack source, SuggestionsBuilder builder) {
source.getServer().getPlayerList().getPlayers().forEach(player ->
builder.suggest(player.getName().getString())
);
return builder.buildFuture();
}
}