1
mirror of https://github.com/Shiewk/SModeration.git synced 2026-04-29 06:34:17 +02:00

Internationalization support

This commit is contained in:
Shy
2025-07-30 13:37:30 +02:00
parent a17086b059
commit 2be16da939
31 changed files with 470 additions and 483 deletions
@@ -40,7 +40,7 @@ public final class BanCommand implements CommandProvider {
private int banWithoutReason(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
if (SModerationPaper.CONFIG.shouldForceReason()){
CommandUtil.error("Please provide a reason.");
CommandUtil.errorTranslatable("smod.command.ban.fail.forceReason");
}
UUID sender = CommandUtil.getSenderUUID(context.getSource());
UUID target = context.getArgument("player", UUID.class);
@@ -62,17 +62,17 @@ public final class BanCommand implements CommandProvider {
Player targetPlayer = Bukkit.getPlayer(target);
if (duration == 0){
if (targetPlayer == null){
CommandUtil.error("You can't ban an offline player for less than 1ms.");
CommandUtil.errorTranslatable("smod.command.ban.fail.tooShort");
} else {
KickCommand.executeKick(sender, targetPlayer, reason);
}
return;
}
if (sender.equals(target)) {
CommandUtil.error("You can't ban yourself.");
CommandUtil.errorTranslatable("smod.command.ban.fail.self");
} else {
if (targetPlayer != null && targetPlayer.hasPermission("smod.preventban")){
CommandUtil.error("This player can't be banned.");
CommandUtil.errorTranslatable("smod.command.ban.fail.protect");
} else {
final Punishment punishment = Punishment.ban(
System.currentTimeMillis(),
@@ -7,15 +7,14 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
import de.shiewk.smoderation.paper.util.CommandUtil;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.List;
import static de.shiewk.smoderation.paper.SModerationPaper.*;
import static io.papermc.paper.command.brigadier.Commands.argument;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.translatable;
public final class EnderchestSeeCommand implements CommandProvider {
@@ -32,11 +31,7 @@ public final class EnderchestSeeCommand implements CommandProvider {
private int openEnderChest(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
Player sender = CommandUtil.getExecutingPlayer(context.getSource());
Player target = CommandUtil.getPlayerSingle(context, "player");
sender.sendMessage(CHAT_PREFIX.append(
Component.text("Opening ender chest of ").color(PRIMARY_COLOR)
.append(target.teamDisplayName().colorIfAbsent(SECONDARY_COLOR))
.append(Component.text("."))
));
sender.sendMessage(translatable("smod.command.ecsee.opening", target.teamDisplayName()));
sender.openInventory(target.getEnderChest());
return Command.SINGLE_SUCCESS;
}
@@ -14,10 +14,9 @@ import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.List;
import static de.shiewk.smoderation.paper.SModerationPaper.*;
import static io.papermc.paper.command.brigadier.Commands.argument;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
public final class InvseeCommand implements CommandProvider {
@@ -44,13 +43,9 @@ public final class InvseeCommand implements CommandProvider {
Player sender = CommandUtil.getExecutingPlayer(context.getSource());
Player target = CommandUtil.getPlayerSingle(context, "player");
if (sender.equals(target)){
CommandUtil.error("You can't open your own inventory.");
CommandUtil.errorTranslatable("smod.command.invsee.fail.self");
}
sender.sendMessage(CHAT_PREFIX.append(
text("Opening inventory of ").color(PRIMARY_COLOR)
.append(target.teamDisplayName().colorIfAbsent(SECONDARY_COLOR))
.append(text("."))
));
sender.sendMessage(translatable("smod.command.invsee.opening", target.teamDisplayName()));
new InvSeeInventory(sender, target).open();
return Command.SINGLE_SUCCESS;
}
@@ -59,13 +54,9 @@ public final class InvseeCommand implements CommandProvider {
Player sender = CommandUtil.getExecutingPlayer(context.getSource());
Player target = CommandUtil.getPlayerSingle(context, "player");
if (sender.equals(target)){
CommandUtil.error("You can't open your own inventory.");
CommandUtil.errorTranslatable("smod.command.invsee.fail.self");
}
sender.sendMessage(CHAT_PREFIX.append(
text("Opening inventory of ").color(PRIMARY_COLOR)
.append(target.teamDisplayName().colorIfAbsent(SECONDARY_COLOR))
.append(text("."))
));
sender.sendMessage(translatable("smod.command.invsee.opening", target.teamDisplayName()));
new InvSeeEquipmentInventory(sender, target).open();
return Command.SINGLE_SUCCESS;
}
@@ -44,7 +44,7 @@ public final class KickCommand implements CommandProvider {
private int kickWithoutReason(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
if (SModerationPaper.CONFIG.shouldForceReason()){
CommandUtil.error("Please provide a reason.");
CommandUtil.errorTranslatable("smod.command.kick.fail.forceReason");
}
UUID sender = CommandUtil.getSenderUUID(context.getSource());
Player target = CommandUtil.getPlayerSingle(context, "player");
@@ -55,9 +55,9 @@ public final class KickCommand implements CommandProvider {
public static void executeKick(UUID sender, Player target, String reason) throws CommandSyntaxException {
UUID targetId = target.getUniqueId();
if (sender.equals(targetId)) {
CommandUtil.error("You can't kick yourself.");
CommandUtil.errorTranslatable("smod.command.kick.fail.self");
} else if (target.hasPermission("smod.preventkick")){
CommandUtil.error("This player can't be kicked.");
CommandUtil.errorTranslatable("smod.command.kick.fail.protect");
}
final Punishment punishment = Punishment.kick(
System.currentTimeMillis(),
@@ -3,24 +3,23 @@ package de.shiewk.smoderation.paper.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.LiteralCommandNode;
import de.shiewk.smoderation.paper.SModerationPaper;
import de.shiewk.smoderation.paper.command.argument.PlayerUUIDArgument;
import de.shiewk.smoderation.paper.punishments.Punishment;
import de.shiewk.smoderation.paper.punishments.PunishmentType;
import de.shiewk.smoderation.paper.util.CommandUtil;
import de.shiewk.smoderation.paper.util.PlayerUtil;
import de.shiewk.smoderation.paper.util.TimeUtil;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import static de.shiewk.smoderation.paper.SModerationPaper.*;
import static de.shiewk.smoderation.paper.SModerationPaper.container;
import static io.papermc.paper.command.brigadier.Commands.argument;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
public final class ModLogsCommand implements CommandProvider {
@@ -38,21 +37,17 @@ public final class ModLogsCommand implements CommandProvider {
CommandSender sender = context.getSource().getSender();
UUID uuid = context.getArgument("player", UUID.class);
String name = PlayerUtil.offlinePlayerName(uuid);
sender.sendMessage(CHAT_PREFIX.append(Component.text("Player ").color(PRIMARY_COLOR)
.append(Component.text(name).color(SECONDARY_COLOR))
.append(Component.text(" (%s)".formatted(uuid)).color(INACTIVE_COLOR))));
final List<Punishment> punishments = SModerationPaper.container.findAll(p -> p.to.equals(uuid) && p.isActive());
sender.sendMessage(translatable("smod.command.modlogs.heading", text(name), text(uuid.toString())));
final List<Punishment> punishments = container.findAll(p -> p.to.equals(uuid) && p.isActive());
for (Punishment punishment : punishments) {
sender.sendMessage(Component.text("- is currently ").color(PRIMARY_COLOR)
.append(Component.text(punishment.type == PunishmentType.BAN ? "banned" : "muted").color(SECONDARY_COLOR))
.append(Component.text(" until ").color(PRIMARY_COLOR))
.append(Component.text(TimeUtil.calendarTimestamp(punishment.until)).color(SECONDARY_COLOR))
.append(Component.text(" (in %s)".formatted(TimeUtil.formatTimeLong(punishment.until - System.currentTimeMillis()))).color(INACTIVE_COLOR))
.append(Component.text(". Reason: ").color(PRIMARY_COLOR))
.append(Component.text(punishment.reason).color(SECONDARY_COLOR)));
sender.sendMessage(translatable("smod.command.modlogs." + punishment.type.name().toLowerCase(),
TimeUtil.calendarTimestamp(punishment.until),
TimeUtil.formatTimeLong(punishment.until - System.currentTimeMillis()),
text(punishment.reason)
));
}
if (punishments.isEmpty()){
sender.sendMessage(Component.text("- has no punishments.").color(PRIMARY_COLOR));
sender.sendMessage(translatable("smod.command.modlogs.none"));
}
return Command.SINGLE_SUCCESS;
}
@@ -40,7 +40,7 @@ public final class MuteCommand implements CommandProvider {
private int muteWithoutReason(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
if (SModerationPaper.CONFIG.shouldForceReason()){
CommandUtil.error("Please provide a reason.");
CommandUtil.errorTranslatable("smod.command.mute.fail.forceReason");
}
UUID sender = CommandUtil.getSenderUUID(context.getSource());
UUID target = context.getArgument("player", UUID.class);
@@ -60,11 +60,11 @@ public final class MuteCommand implements CommandProvider {
public static void executeMute(UUID sender, UUID target, long duration, String reason) throws CommandSyntaxException {
if (sender.equals(target)) {
CommandUtil.error("You can't mute yourself.");
CommandUtil.errorTranslatable("smod.command.mute.fail.self");
} else {
Player targetPlayer = Bukkit.getPlayer(target);
if (targetPlayer != null && targetPlayer.hasPermission("smod.preventmute")){
CommandUtil.error("This player can't be muted.");
CommandUtil.errorTranslatable("smod.command.mute.fail.protect");
} else {
final Punishment punishment = Punishment.mute(
System.currentTimeMillis(),
@@ -16,10 +16,10 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Collection;
import java.util.List;
import static de.shiewk.smoderation.paper.SModerationPaper.*;
import static io.papermc.paper.command.brigadier.Commands.argument;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
public final class OfflineTPCommand implements CommandProvider {
@@ -40,15 +40,11 @@ public final class OfflineTPCommand implements CommandProvider {
Location location = player.getLocation();
if (location == null) {
CommandUtil.error("This player's location is unknown.");
CommandUtil.errorTranslatable("smod.command.offlinetp.fail.unknown");
}
sender.teleportAsync(location, PlayerTeleportEvent.TeleportCause.COMMAND);
sender.sendMessage(CHAT_PREFIX.append(
text("Teleporting you to ").color(PRIMARY_COLOR)
.append(text(PlayerUtil.offlinePlayerName(player.getUniqueId())).colorIfAbsent(SECONDARY_COLOR))
.append(text("."))
));
sender.sendMessage(translatable("smod.command.offlinetp.teleporting", text(PlayerUtil.offlinePlayerName(player.getUniqueId()))));
return Command.SINGLE_SUCCESS;
}
@@ -6,15 +6,13 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
import de.shiewk.smoderation.paper.listener.SocialSpyListener;
import de.shiewk.smoderation.paper.util.CommandUtil;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.CommandSender;
import java.util.Collection;
import java.util.List;
import static de.shiewk.smoderation.paper.SModerationPaper.CHAT_PREFIX;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
public final class SocialSpyCommand implements CommandProvider {
@@ -29,17 +27,17 @@ public final class SocialSpyCommand implements CommandProvider {
private int toggleSocialSpy(CommandContext<CommandSourceStack> context) {
CommandSender sender = context.getSource().getSender();
final boolean enabled = SocialSpyListener.toggle(sender);
sender.sendMessage(CHAT_PREFIX.append(text("SocialSpy ").append(
enabled ?
text("enabled").color(NamedTextColor.GREEN) :
text("disabled").color(NamedTextColor.RED)
).append(text("."))));
if (enabled){
sender.sendMessage(translatable("smod.command.socialspy.enabled"));
} else {
sender.sendMessage(translatable("smod.command.socialspy.disabled"));
}
return Command.SINGLE_SUCCESS;
}
@Override
public String getCommandDescription() {
return "Enables socialspy mode (you can see private messages of other players)";
return "Enables SocialSpy mode (allows you to see private messages of other players)";
}
@Override
@@ -1,5 +1,6 @@
package de.shiewk.smoderation.paper.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.LiteralCommandNode;
@@ -39,9 +40,9 @@ public final class UnbanCommand implements CommandProvider {
punishment.undo(senderUUID);
punishment.broadcastUndo(SModerationPaper.container);
} else {
CommandUtil.error("This player is not banned.");
CommandUtil.errorTranslatable("smod.command.unban.fail.notBanned");
}
return com.mojang.brigadier.Command.SINGLE_SUCCESS;
return Command.SINGLE_SUCCESS;
}
@Override
@@ -40,7 +40,7 @@ public final class UnmuteCommand implements CommandProvider {
punishment.undo(senderUUID);
punishment.broadcastUndo(SModerationPaper.container);
} else {
CommandUtil.error("This player is not muted.");
CommandUtil.errorTranslatable("smod.command.unmute.fail.notMuted");
}
return Command.SINGLE_SUCCESS;
}
@@ -24,7 +24,7 @@ import java.util.List;
import static de.shiewk.smoderation.paper.SModerationPaper.*;
import static io.papermc.paper.command.brigadier.Commands.argument;
import static io.papermc.paper.command.brigadier.Commands.literal;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.*;
public final class VanishCommand implements CommandProvider {
@@ -51,7 +51,7 @@ public final class VanishCommand implements CommandProvider {
private int toggleVanishForTargets(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
List<Player> targets = context.getArgument("targets", PlayerSelectorArgumentResolver.class).resolve(context.getSource());
if (targets.isEmpty()){
CommandUtil.error("No player was found.");
CommandUtil.errorTranslatable("smod.command.vanish.fail.noPlayersFound");
} else {
for (Player target : targets) {
toggleVanish(target);
@@ -72,7 +72,7 @@ public final class VanishCommand implements CommandProvider {
@Override
public String getCommandDescription() {
return "Toggles vanish mode which prevents other players from seeing you're online";
return "Toggles vanish mode which prevents other players from seeing you're online.";
}
@Override
@@ -80,7 +80,7 @@ public final class VanishCommand implements CommandProvider {
return List.of("smvanish", "smodvanish", "v", "smv");
}
private static final ObjectArrayList<Player> vanishedPlayers = new ObjectArrayList<>(1);
private static final ObjectArrayList<Player> vanishedPlayers = new ObjectArrayList<>(0);
public static void toggleVanish(Player player){
final boolean newStatus = !isVanished(player);
@@ -92,14 +92,9 @@ public final class VanishCommand implements CommandProvider {
if (newStatus){
vanishedPlayers.add(player);
for (CommandSender sender : SModerationPaper.container.collectBroadcastTargets()) {
sender.sendMessage(CHAT_PREFIX.append(
player.displayName().colorIfAbsent(SECONDARY_COLOR)
).append(text()
.content(" vanished.")
.color(PRIMARY_COLOR)
));
sender.sendMessage(translatable("smod.command.vanish.broadcast.on", player.teamDisplayName()));
}
player.sendMessage(CHAT_PREFIX.append(text("You are now vanished.").color(PRIMARY_COLOR)));
player.sendMessage(translatable("smod.command.vanish.toggle.on"));
player.setVisibleByDefault(false);
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.hasPermission("smod.vanish.see")){
@@ -109,14 +104,9 @@ public final class VanishCommand implements CommandProvider {
} else {
vanishedPlayers.remove(player);
for (CommandSender sender : container.collectBroadcastTargets()) {
sender.sendMessage(CHAT_PREFIX.append(
player.displayName().colorIfAbsent(SECONDARY_COLOR)
).append(text()
.content(" re-appeared.")
.color(PRIMARY_COLOR)
));
sender.sendMessage(translatable("smod.command.vanish.broadcast.off", player.teamDisplayName()));
}
player.sendMessage(CHAT_PREFIX.append(text("You are no longer vanished.").color(PRIMARY_COLOR)));
player.sendMessage(translatable("smod.command.vanish.toggle.off"));
player.setVisibleByDefault(true);
}
}
@@ -153,17 +143,13 @@ public final class VanishCommand implements CommandProvider {
public static void listVanishedPlayersTo(CommandSender receiver){
if (vanishedPlayers.isEmpty()){
receiver.sendMessage(CHAT_PREFIX.append(
text().content("No players are currently vanished.").color(PRIMARY_COLOR)
));
receiver.sendMessage(translatable("smod.command.vanish.list.none"));
} else {
Component vanishList = CHAT_PREFIX.append(
text().content("The following players are currently vanished: ").color(PRIMARY_COLOR)
);
Component vanishList = empty();
for (ObjectListIterator<Player> iterator = vanishedPlayers.iterator(); iterator.hasNext(); ) {
Player vanishedPlayer = iterator.next();
vanishList = vanishList.append(
vanishedPlayer.displayName().colorIfAbsent(SECONDARY_COLOR)
vanishedPlayer.teamDisplayName().colorIfAbsent(SECONDARY_COLOR)
);
if (iterator.hasNext()){
vanishList = vanishList.append(
@@ -171,7 +157,7 @@ public final class VanishCommand implements CommandProvider {
);
}
}
receiver.sendMessage(vanishList);
receiver.sendMessage(translatable("smod.command.vanish.list", vanishList));
}
}
}
@@ -24,7 +24,7 @@ public final class DurationArgument implements CustomArgumentType.Converted<Long
@Override
public @NotNull Long convert(@NotNull String nativeType) throws CommandSyntaxException {
if (!VALIDATION_PATTERN.matcher(nativeType).matches()){
CommandUtil.error("Please provide a valid duration, e.g. '1d6h30min'");
CommandUtil.errorTranslatable("smod.argument.duration.fail.pattern");
}
AtomicLong totalDuration = new AtomicLong();
for (MatchResult result : DURATION_PATTERN.matcher(nativeType).results().toList()) {
@@ -39,7 +39,7 @@ public final class DurationArgument implements CustomArgumentType.Converted<Long
case "mo" -> 2_592_000_000L;
case "y" -> 31_536_000_000L;
default -> {
CommandUtil.error("Invalid time span '%s'".formatted(result.group(2)));
CommandUtil.errorTranslatable("smod.argument.duration.fail.invalid", result.group(2));
throw new UnknownError(); // can't happen
}
};
@@ -22,7 +22,7 @@ public final class OfflinePlayerArgument implements CustomArgumentType.Converted
if (player != null){
return player;
} else {
CommandUtil.error("That player is not cached.");
CommandUtil.errorTranslatable("smod.argument.offlinePlayer.fail.notCached");
throw new AssertionError(); // can't happen
}
}
@@ -27,7 +27,7 @@ public final class PlayerUUIDArgument implements CustomArgumentType.Converted<UU
if (player != null){
return player.getUniqueId();
} else {
CommandUtil.error("This player is not cached. Try providing an UUID instead.");
CommandUtil.errorTranslatable("smod.argument.uuid.fail.notCached");
throw new UnknownError(); // can't happen
}
}