From a98db8e188208f8b31583cb61cb695ee5a9ed249 Mon Sep 17 00:00:00 2001 From: Draycia Date: Tue, 28 May 2024 20:56:06 -0700 Subject: [PATCH] Add cooldown channel setting --- .../carbon/api/channels/ChatChannel.java | 6 +++ .../carbon/common/CarbonCommonModule.java | 3 ++ .../common/channels/ConfigChatChannel.java | 27 +++++++++++ .../listeners/ChatListenerInternal.java | 14 ++++++ .../common/messages/CarbonMessages.java | 3 ++ .../placeholders/LongPlaceholderResolver.java | 46 +++++++++++++++++++ .../locale/messages-en_US.properties | 1 + paper/build.gradle.kts | 2 +- 8 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java diff --git a/api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java b/api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java index 9e0e048ff..03be66feb 100644 --- a/api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java +++ b/api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java @@ -124,4 +124,10 @@ public interface ChatChannel extends Keyed, ChatComponentRenderer { */ boolean emptyRadiusRecipientsMessage(); + long cooldown(); + + long playerCooldown(CarbonPlayer player); + + long startCooldown(CarbonPlayer player); + } diff --git a/common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java b/common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java index 8415f3306..602920b64 100644 --- a/common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java +++ b/common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java @@ -86,6 +86,7 @@ import net.draycia.carbon.common.messages.placeholders.ComponentPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.IntPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.KeyPlaceholderResolver; +import net.draycia.carbon.common.messages.placeholders.LongPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.OptionPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.StringPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.UUIDPlaceholderResolver; @@ -166,6 +167,7 @@ public CarbonMessages carbonMessages( final UUIDPlaceholderResolver uuidPlaceholderResolver, final StringPlaceholderResolver stringPlaceholderResolver, final IntPlaceholderResolver intPlaceholderResolver, + final LongPlaceholderResolver longPlaceholderResolver, final KeyPlaceholderResolver keyPlaceholderResolver, final BooleanPlaceholderResolver booleanPlaceholderResolver, final CarbonMessageSource carbonMessageSource, @@ -182,6 +184,7 @@ public CarbonMessages carbonMessages( .weightedPlaceholderResolver(UUID.class, uuidPlaceholderResolver, 0) .weightedPlaceholderResolver(String.class, stringPlaceholderResolver, 0) .weightedPlaceholderResolver(Integer.class, intPlaceholderResolver, 0) + .weightedPlaceholderResolver(Long.class, longPlaceholderResolver, 0) .weightedPlaceholderResolver(Key.class, keyPlaceholderResolver, 0) .weightedPlaceholderResolver(Boolean.class, booleanPlaceholderResolver, 0) .weightedPlaceholderResolver(Option.class, new OptionPlaceholderResolver<>(), 0) diff --git a/common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java b/common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java index a2ceb4930..13c24a9ee 100644 --- a/common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java +++ b/common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java @@ -23,7 +23,9 @@ import io.leangen.geantyref.TypeToken; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; import net.draycia.carbon.api.CarbonServer; @@ -41,6 +43,7 @@ import net.draycia.carbon.common.messages.placeholders.ComponentPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.IntPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.KeyPlaceholderResolver; +import net.draycia.carbon.common.messages.placeholders.LongPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.StringPlaceholderResolver; import net.draycia.carbon.common.messages.placeholders.UUIDPlaceholderResolver; import net.draycia.carbon.common.util.Exceptions; @@ -111,6 +114,10 @@ public class ConfigChatChannel implements ChatChannel { because they're out of range from the radius.""") private boolean emptyRadiusRecipientsMessage = true; + private Map cooldowns = new HashMap<>(); + + private long cooldown = -1; + @Override public @Nullable String quickPrefix() { if (this.quickPrefix == null || this.quickPrefix.isBlank()) { @@ -185,6 +192,25 @@ public List recipients(final CarbonPlayer sender) { return recipients; } + @Override + public long cooldown() { + return this.cooldown * 1000; // Seconds to millis + } + + @Override + public long playerCooldown(final CarbonPlayer player) { + if (this.cooldown() <= 0) { + return 0; + } + + return Objects.requireNonNullElse(this.cooldowns.get(player.uuid()), 0L); + } + + public long startCooldown(final CarbonPlayer player) { + final long expiresAt = System.currentTimeMillis() + this.cooldown(); + return Objects.requireNonNullElse(this.cooldowns.put(player.uuid(), expiresAt), 0L); + } + @Override public @NonNull Key key() { return Objects.requireNonNull(this.key); @@ -214,6 +240,7 @@ private ConfigChannelMessages loadMessages() { .weightedPlaceholderResolver(UUID.class, uuidPlaceholderResolver, 0) .weightedPlaceholderResolver(String.class, stringPlaceholderResolver, 0) .weightedPlaceholderResolver(Integer.class, new IntPlaceholderResolver<>(), 0) + .weightedPlaceholderResolver(Long.class, new LongPlaceholderResolver<>(), 0) .weightedPlaceholderResolver(Key.class, keyPlaceholderResolver, 0) .weightedPlaceholderResolver(Boolean.class, booleanPlaceholderResolver, 0) .create(this.getClass().getClassLoader()); diff --git a/common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java b/common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java index bdea2881c..13fef23cc 100644 --- a/common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java +++ b/common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java @@ -75,6 +75,20 @@ protected ChatListenerInternal( sender.sendMessage(permitted.reason()); return null; } + + if (channel.cooldown() > 0) { + final long currentMillis = System.currentTimeMillis(); + final long expiresAt = channel.playerCooldown(sender); + + if (currentMillis < expiresAt) { + // Round up, or the player can be told they have 0 seconds remaining + final long remaining = (long) Math.ceil((double) (expiresAt - currentMillis) / 1000); + this.carbonMessages.channelCooldown(sender, remaining); + return null; + } + + channel.startCooldown(sender); + } String content = this.configManager.primaryConfig().applyChatPlaceholders(messageContent); content = this.configManager.primaryConfig().applyChatFilters(content); diff --git a/common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java b/common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java index 1784cac98..7c1528798 100644 --- a/common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java +++ b/common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java @@ -56,6 +56,9 @@ public interface CarbonMessages { @Message("channel.joined") void channelJoined(final Audience audience); + @Message("channel.cooldown") + void channelCooldown(final Audience audience, long remaining); + /* * ============================================================= * =========================== Mutes =========================== diff --git a/common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java b/common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java new file mode 100644 index 000000000..3d5d06d1f --- /dev/null +++ b/common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java @@ -0,0 +1,46 @@ +/* + * CarbonChat + * + * Copyright (c) 2024 Josua Parks (Vicarious) + * Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.draycia.carbon.common.messages.placeholders; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Map; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.moonshine.placeholder.ConclusionValue; +import net.kyori.moonshine.placeholder.ContinuanceValue; +import net.kyori.moonshine.placeholder.IPlaceholderResolver; +import net.kyori.moonshine.util.Either; +import org.checkerframework.checker.nullness.qual.Nullable; + +public class LongPlaceholderResolver implements IPlaceholderResolver { + + @Override + public @Nullable Map, ContinuanceValue>> resolve( + final String placeholderName, + final Long value, + final R receiver, + final Type owner, + final Method method, + final @Nullable Object[] parameters + ) { + return Map.of(placeholderName, Either.left(ConclusionValue.conclusionValue(Tag.preProcessParsed(String.valueOf(value))))); + } + +} diff --git a/common/src/main/resources/locale/messages-en_US.properties b/common/src/main/resources/locale/messages-en_US.properties index db3895dba..1d8435b8d 100644 --- a/common/src/main/resources/locale/messages-en_US.properties +++ b/common/src/main/resources/locale/messages-en_US.properties @@ -140,6 +140,7 @@ whisper.ignoring_all=You cannot send messages while they are ignored! whisper.to= '>'>[You] -> [] whisper.toggled.on=Now receiving private messages. whisper.toggled.off=No longer receiving private messages. +channel.cooldown=You may use chat again in seconds! channel.radius.empty_recipients=You're not close enough to anyone to send a message channel.joined=You have rejoined the channel channel.left=You have left the channel diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index 4c867f739..d81384388 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -62,7 +62,7 @@ tasks { withType(RunServer::class).configureEach { version.set(libs.versions.minecraft) downloadPlugins { - url("https://download.luckperms.net/1533/bukkit/loader/LuckPerms-Bukkit-5.4.120.jar") + url("https://download.luckperms.net/1543/bukkit/loader/LuckPerms-Bukkit-5.4.130.jar") github("MiniPlaceholders", "MiniPlaceholders", libs.versions.miniplaceholders.get(), "MiniPlaceholders-Paper-${libs.versions.miniplaceholders.get()}.jar") github("MiniPlaceholders", "PlaceholderAPI-Expansion", "1.2.0", "PlaceholderAPI-Expansion-1.2.0.jar") hangar("PlaceholderAPI", libs.versions.placeholderapi.get())