diff --git a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java index d9f7168..c64e4a8 100644 --- a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java +++ b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java @@ -10,12 +10,12 @@ import de.shiewk.smoderation.paper.punishments.Kick; import de.shiewk.smoderation.paper.punishments.Mute; import de.shiewk.smoderation.paper.punishments.PunishmentManager; import de.shiewk.smoderation.paper.translation.TranslatorManager; +import de.shiewk.smoderation.paper.util.ColorPalette; import de.shiewk.smoderation.paper.util.SModLegacy; import de.shiewk.smoderation.paper.util.SchedulerUtil; import io.papermc.paper.command.brigadier.Commands; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.logger.slf4j.ComponentLogger; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -42,14 +42,11 @@ import static org.bukkit.Bukkit.getPluginManager; @SuppressWarnings("UnstableApiUsage") // Paper Brigadier API public final class SModerationPaper extends JavaPlugin { - public static final TextColor PRIMARY_COLOR = TextColor.color(212, 0, 255); - public static final TextColor SECONDARY_COLOR = TextColor.color(52, 143, 255); - public static final TextColor INACTIVE_COLOR = NamedTextColor.GRAY; - public static final Gson gson = new Gson(); public static ComponentLogger LOGGER = null; public static SModerationPaper PLUGIN = null; private static SkinTextureProvider textureProvider = null; + private ColorPalette colors; private final TranslatorManager translatorManager = new TranslatorManager( Key.key("smoderation", "translations"), @@ -67,6 +64,10 @@ public final class SModerationPaper extends JavaPlugin { return PLUGIN.getConfig(); } + public static ColorPalette colors() { + return PLUGIN.colors; + } + @Override public void onLoad() { LOGGER = getComponentLogger(); @@ -81,6 +82,12 @@ public final class SModerationPaper extends JavaPlugin { this.punishmentManager.registerType("ban", new Ban.Factory()); this.punishmentManager.registerType("kick", new Kick.Factory()); + this.colors = new ColorPalette( + parseColor(config().getString("colors.primary")), + parseColor(config().getString("colors.secondary")), + parseColor(config().getString("colors.detail")) + ); + SModLegacy.migrateV1PunishmentsFile( this.punishmentManager, getDataPath().resolve("container.gz"), @@ -88,6 +95,17 @@ public final class SModerationPaper extends JavaPlugin { ); } + private TextColor parseColor(String string) { + if (string == null || string.length() != 7) { + throw new IllegalArgumentException("Color not formatted correctly: " + string); + } + TextColor color = TextColor.fromHexString(string); + if (color == null) { + throw new IllegalArgumentException("Color not formatted correctly: " + string); + } + return color; + } + public boolean isFeatureEnabled(String feature){ return getConfig().getBoolean("features."+feature, true); } @@ -170,8 +188,9 @@ public final class SModerationPaper extends JavaPlugin { private MiniMessage createMiniMessage() { return MiniMessage.builder() .tags(TagResolver.builder() - .resolver(TagResolver.resolver("primary", Tag.styling(style -> style.color(PRIMARY_COLOR)))) - .resolver(TagResolver.resolver("secondary", Tag.styling(style -> style.color(SECONDARY_COLOR)))) + .resolver(TagResolver.resolver("primary", Tag.styling(style -> style.color(colors().primary())))) + .resolver(TagResolver.resolver("secondary", Tag.styling(style -> style.color(colors().secondary())))) + .resolver(TagResolver.resolver("detail", Tag.styling(style -> style.color(colors().detail())))) .resolver(TagResolver.standard()) .build() ) diff --git a/src/main/java/de/shiewk/smoderation/paper/command/VanishCommand.java b/src/main/java/de/shiewk/smoderation/paper/command/VanishCommand.java index f3298d1..bb83f61 100644 --- a/src/main/java/de/shiewk/smoderation/paper/command/VanishCommand.java +++ b/src/main/java/de/shiewk/smoderation/paper/command/VanishCommand.java @@ -4,6 +4,7 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.tree.LiteralCommandNode; +import de.shiewk.smoderation.paper.SModerationPaper; import de.shiewk.smoderation.paper.event.VanishToggleEvent; import de.shiewk.smoderation.paper.punishments.Punishment; import de.shiewk.smoderation.paper.util.CommandUtil; @@ -150,11 +151,11 @@ public final class VanishCommand implements CommandProvider { for (ObjectListIterator iterator = vanishedPlayers.iterator(); iterator.hasNext(); ) { Player vanishedPlayer = iterator.next(); vanishList = vanishList.append( - vanishedPlayer.teamDisplayName().colorIfAbsent(SECONDARY_COLOR) + vanishedPlayer.teamDisplayName().colorIfAbsent(SModerationPaper.colors().secondary()) ); if (iterator.hasNext()){ vanishList = vanishList.append( - text().content(", ").color(PRIMARY_COLOR) + text().content(", ").color(SModerationPaper.colors().primary()) ); } } diff --git a/src/main/java/de/shiewk/smoderation/paper/input/ChatInput.java b/src/main/java/de/shiewk/smoderation/paper/input/ChatInput.java index e172cdb..cdb34ea 100644 --- a/src/main/java/de/shiewk/smoderation/paper/input/ChatInput.java +++ b/src/main/java/de/shiewk/smoderation/paper/input/ChatInput.java @@ -1,5 +1,6 @@ package de.shiewk.smoderation.paper.input; +import de.shiewk.smoderation.paper.SModerationPaper; import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; import org.bukkit.entity.Player; @@ -10,7 +11,6 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; -import static de.shiewk.smoderation.paper.SModerationPaper.PRIMARY_COLOR; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -53,7 +53,7 @@ public class ChatInput { public static void prompt(Player player, Consumer consumer, Component prompt, int timeSeconds){ runningInputs.put(player, new ChatInput(player, prompt, consumer, timeSeconds)); - player.sendMessage(prompt.colorIfAbsent(PRIMARY_COLOR)); + player.sendMessage(prompt.colorIfAbsent(SModerationPaper.colors().primary())); } public Component getPrompt() { diff --git a/src/main/java/de/shiewk/smoderation/paper/inventory/SModMenu.java b/src/main/java/de/shiewk/smoderation/paper/inventory/SModMenu.java index bfde1fb..fafb61c 100644 --- a/src/main/java/de/shiewk/smoderation/paper/inventory/SModMenu.java +++ b/src/main/java/de/shiewk/smoderation/paper/inventory/SModMenu.java @@ -2,6 +2,7 @@ package de.shiewk.smoderation.paper.inventory; import com.destroystokyo.paper.profile.PlayerProfile; import com.destroystokyo.paper.profile.ProfileProperty; +import de.shiewk.smoderation.paper.SModerationPaper; import de.shiewk.smoderation.paper.SkinTextureProvider; import de.shiewk.smoderation.paper.input.ChatInput; import de.shiewk.smoderation.paper.punishments.Punishment; @@ -126,7 +127,7 @@ public class SModMenu extends PageableCustomInventory { // chat event is async SchedulerUtil.scheduleForEntity(PLUGIN, player, this::open); } - }, translatable("smod.menu.search.query").color(SECONDARY_COLOR), 30); + }, translatable("smod.menu.search.query").color(SModerationPaper.colors().secondary()), 30); } @Override @@ -199,13 +200,13 @@ public class SModMenu extends PageableCustomInventory { private ItemStack createFilterItem(){ final Filter filter = getFilter(); final ItemStack stack = new ItemStack(Filter.ICON); - stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.filter", filter.name).color(PRIMARY_COLOR))); + stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.filter", filter.name).color(SModerationPaper.colors().primary()))); ItemLore.Builder loreBuilder = ItemLore.lore(); loreBuilder.addLine(empty()); for (Filter value : Filter.values()) { final boolean selected = filter == value; - Component filterText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SECONDARY_COLOR : INACTIVE_COLOR).append(value.name))); + Component filterText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SModerationPaper.colors().secondary() : SModerationPaper.colors().detail()).append(value.name))); loreBuilder.addLine(filterText); } loreBuilder.addLine(empty()); @@ -218,13 +219,13 @@ public class SModMenu extends PageableCustomInventory { private ItemStack createTypeItem(){ final String type = getType(); final ItemStack stack = new ItemStack(Material.CHEST); - stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.type", (type == null ? translatable("smod.menu.type.all") : translatable("smod.punishment.name." + type)))).color(PRIMARY_COLOR)); + stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.type", (type == null ? translatable("smod.menu.type.all") : translatable("smod.punishment.name." + type)))).color(SModerationPaper.colors().primary())); ItemLore.Builder loreBuilder = ItemLore.lore(); loreBuilder.addLine(empty()); final Consumer addToLore = value -> { final boolean selected = Objects.equals(type, value); - Component typeText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SECONDARY_COLOR : INACTIVE_COLOR).append(value == null ? translatable("smod.menu.type.all") : translatable("smod.punishment.name." + value)))); + Component typeText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SModerationPaper.colors().secondary() : SModerationPaper.colors().detail()).append(value == null ? translatable("smod.menu.type.all") : translatable("smod.punishment.name." + value)))); loreBuilder.addLine(typeText); }; addToLore.accept(null); @@ -242,14 +243,14 @@ public class SModMenu extends PageableCustomInventory { private ItemStack createSortItem(){ final Sort sort = getSort(); final ItemStack stack = new ItemStack(Sort.ICON); - stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.sort", sort.name).color(PRIMARY_COLOR))); + stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.sort", sort.name).color(SModerationPaper.colors().primary()))); ItemLore.Builder loreBuilder = ItemLore.lore(); loreBuilder.addLine(empty()); for (Sort value : Sort.values()) { final boolean selected = sort == value; - Component sortText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SECONDARY_COLOR : INACTIVE_COLOR).append(value.name))); + Component sortText = renderComponent(player, applyFormatting(text((selected ? "\u00BB " : ""), selected ? SModerationPaper.colors().secondary() : SModerationPaper.colors().detail()).append(value.name))); loreBuilder.addLine(sortText); } @@ -270,12 +271,12 @@ public class SModMenu extends PageableCustomInventory { // we just create the stack without it instead of throwing } - stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.search", PRIMARY_COLOR))); + stack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, translatable("smod.menu.search", SModerationPaper.colors().primary()))); ItemLore.Builder loreBuilder = ItemLore.lore(); loreBuilder.addLines(List.of( empty(), - renderComponent(player, applyFormatting(translatable("smod.menu.search.current", searchQuery == null ? translatable("smod.menu.search.none") : text('"' + searchQuery + '"'))).color(SECONDARY_COLOR)), + renderComponent(player, applyFormatting(translatable("smod.menu.search.current", searchQuery == null ? translatable("smod.menu.search.none") : text('"' + searchQuery + '"'))).color(SModerationPaper.colors().secondary())), empty(), renderComponent(player, applyFormatting(translatable("smod.menu.search.new", NamedTextColor.GOLD))) )); diff --git a/src/main/java/de/shiewk/smoderation/paper/listener/PunishmentListener.java b/src/main/java/de/shiewk/smoderation/paper/listener/PunishmentListener.java index 140f818..c7d3313 100644 --- a/src/main/java/de/shiewk/smoderation/paper/listener/PunishmentListener.java +++ b/src/main/java/de/shiewk/smoderation/paper/listener/PunishmentListener.java @@ -16,7 +16,6 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import java.util.List; -import static de.shiewk.smoderation.paper.SModerationPaper.PRIMARY_COLOR; import static net.kyori.adventure.text.Component.translatable; public class PunishmentListener implements Listener { @@ -41,7 +40,7 @@ public class PunishmentListener implements Listener { List list = punishmentManager.byTargetUUID(player.getUniqueId(), p -> p instanceof Mute mute && mute.isActive()); if (!list.isEmpty()) { event.setCancelled(true); - player.sendMessage(list.getFirst().infoMessage().colorIfAbsent(PRIMARY_COLOR)); + player.sendMessage(list.getFirst().infoMessage().colorIfAbsent(SModerationPaper.colors().primary())); } } @@ -57,7 +56,7 @@ public class PunishmentListener implements Listener { || message.toLowerCase().startsWith(str.toLowerCase()+" ") )){ Bukkit.getConsoleSender().sendMessage(player.getName() + " tried to run forbidden command while muted"); - player.sendMessage(translatable("smod.punishment.playerMessage.mute.chat", PRIMARY_COLOR)); + player.sendMessage(translatable("smod.punishment.playerMessage.mute.chat", SModerationPaper.colors().primary())); event.setCancelled(true); } } diff --git a/src/main/java/de/shiewk/smoderation/paper/listener/VanishListener.java b/src/main/java/de/shiewk/smoderation/paper/listener/VanishListener.java index b624dc4..645e233 100644 --- a/src/main/java/de/shiewk/smoderation/paper/listener/VanishListener.java +++ b/src/main/java/de/shiewk/smoderation/paper/listener/VanishListener.java @@ -19,13 +19,12 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.persistence.PersistentDataType; -import static de.shiewk.smoderation.paper.SModerationPaper.SECONDARY_COLOR; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; public class VanishListener implements Listener { - public static final Component PREFIX = text("[VANISH] ").color(SECONDARY_COLOR); + public static final Component PREFIX = text("[VANISH] ").color(SModerationPaper.colors().secondary()); @EventHandler(priority = EventPriority.HIGH) public void onPlayerQuit(PlayerQuitEvent event){ final Player player = event.getPlayer(); diff --git a/src/main/java/de/shiewk/smoderation/paper/util/ColorPalette.java b/src/main/java/de/shiewk/smoderation/paper/util/ColorPalette.java new file mode 100644 index 0000000..f809967 --- /dev/null +++ b/src/main/java/de/shiewk/smoderation/paper/util/ColorPalette.java @@ -0,0 +1,7 @@ +package de.shiewk.smoderation.paper.util; + +import net.kyori.adventure.text.format.TextColor; + +public record ColorPalette(TextColor primary, TextColor secondary, TextColor detail) { + +} diff --git a/src/main/resources/default-config.yml b/src/main/resources/default-config.yml index 26399db..f998b76 100644 --- a/src/main/resources/default-config.yml +++ b/src/main/resources/default-config.yml @@ -9,7 +9,7 @@ default-reason: No reason provided. features: # Should punishments be tracked and executed? # Note that disabling this will also disable the SMod menu and - # /modlogs command since their only use is viewing punishments + # /modlogs command since their only use is viewing punishments. punishments: true # Should commands for opening the SMod menu be registered? smodmenu: true @@ -24,6 +24,13 @@ features: # Should players be able to enable vanish mode? vanish: true +# Allows you to customize plugin colors. +# Colors have to be formatted #rrggbb. +colors: + primary: '#e26c04' + secondary: '#fc9e07' + detail: '#ababab' + # A list of commands which will be captured and broadcast # to players which have SocialSpy enabled (/socialspy). socialspy-commands: diff --git a/src/main/resources/smoderation/translations/de_de.json b/src/main/resources/smoderation/translations/de_de.json index 79aa35e..2c5b7ab 100644 --- a/src/main/resources/smoderation/translations/de_de.json +++ b/src/main/resources/smoderation/translations/de_de.json @@ -3,7 +3,7 @@ "smod.argument.duration.fail.pattern": "Bitte gib eine gültige Zeit an, z.B. '1d6h30min'", "smod.argument.offlinePlayer.fail.notCached": "Die Daten des Spielers sind nicht gespeichert.", "smod.argument.uuid.fail.notCached": "Die Daten des Spielers sind nicht gespeichert. Versuche, stattdessen seine UUID anzugeben.", - "smod.chatInput.remainingTime": " Sekunden", + "smod.chatInput.remainingTime": " Sekunden", "smod.command.ban.fail.alreadyBanned": "Dieser Spieler ist schon gebannt.", "smod.command.ban.fail.forceReason": "Bitte gib einen Grund an.", "smod.command.ban.fail.protect": "Dieser Spieler kann nicht gebannt werden.", @@ -18,10 +18,10 @@ "smod.command.kick.fail.forceReason": "Bitte gib einen Grund an.", "smod.command.kick.fail.protect": "Dieser Spieler kann nicht gekickt werden.", "smod.command.kick.fail.self": "Du kannst dich nicht selbst kicken.", - "smod.command.modlogs.ban": "- ist bis (in ) gebannt. Grund: ", + "smod.command.modlogs.ban": "- ist bis (in ) gebannt. Grund: ", "smod.command.modlogs.ban.permanent": "- ist permanent gebannt. Grund: ", - "smod.command.modlogs.heading": "Spieler ()", - "smod.command.modlogs.mute": "- ist bis (in ) stummgeschaltet. Grund: ", + "smod.command.modlogs.heading": "Spieler ()", + "smod.command.modlogs.mute": "- ist bis (in ) stummgeschaltet. Grund: ", "smod.command.modlogs.mute.permanent": "- ist permanent stummgeschaltet. Grund: ", "smod.command.modlogs.none": "- ist momentan nicht gebannt oder stummgeschaltet.", "smod.command.mute.fail.alreadyMuted": "Dieser Spieler ist schon stummgeschaltet.", diff --git a/src/main/resources/smoderation/translations/en_us.json b/src/main/resources/smoderation/translations/en_us.json index 728feb5..1da397a 100644 --- a/src/main/resources/smoderation/translations/en_us.json +++ b/src/main/resources/smoderation/translations/en_us.json @@ -3,7 +3,7 @@ "smod.argument.duration.fail.pattern": "Please provide a valid duration, e.g. '1d6h30min'", "smod.argument.offlinePlayer.fail.notCached": "That player's data is not saved.", "smod.argument.uuid.fail.notCached": "That player's data is not saved. Try providing an UUID instead.", - "smod.chatInput.remainingTime": " seconds", + "smod.chatInput.remainingTime": " seconds", "smod.command.ban.fail.alreadyBanned": "This player is already banned.", "smod.command.ban.fail.forceReason": "Please provide a reason.", "smod.command.ban.fail.protect": "This player can't be banned.", @@ -18,10 +18,10 @@ "smod.command.kick.fail.forceReason": "Please provide a reason.", "smod.command.kick.fail.protect": "This player can't be kicked.", "smod.command.kick.fail.self": "You can't kick yourself.", - "smod.command.modlogs.ban": "- is banned until (in ). Reason: ", + "smod.command.modlogs.ban": "- is banned until (in ). Reason: ", "smod.command.modlogs.ban.permanent": "- is banned permanently. Reason: ", - "smod.command.modlogs.heading": "Player ()", - "smod.command.modlogs.mute": "- is muted until (in ). Reason: ", + "smod.command.modlogs.heading": "Player ()", + "smod.command.modlogs.mute": "- is muted until (in ). Reason: ", "smod.command.modlogs.mute.permanent": "- is muted permanently. Reason: ", "smod.command.modlogs.none": "- is not currently muted or banned.", "smod.command.mute.fail.alreadyMuted": "This player is already muted.",