Refactor EndPreventListener and EndOpeningEffects for improved message handling and consistency in chat notifications

This commit is contained in:
besiece committed 2026-11-08 20:07:42 +01:00
1 parent 20616f1e02
commit 63dbefdde8
3 files changed
+15 -22

No files matched your search

@@ -32,7 +32,7 @@ effects:
```
`times` kann beliebige benannte Zeitpunkte enthalten. `messages.end-activation-denied`
enthält beliebig viele Texte für die zufällige Actionbar-Meldung.
enthält beliebig viele Texte für die zufällige private Chat-Nachricht.
Unter `effects.end-opening` können frei benannte Effekte ergänzt oder entfernt werden.
`minutes-before-opening` ist eine nicht negative ganze Zahl: Ein positiver Wert gibt den
Abstand zur End-Öffnung in Minuten an, `0` kennzeichnet einen Effekt beim tatsächlichen Öffnen.
@@ -98,9 +98,10 @@ fällig, wird sie regulär ausgeführt. Dasselbe gilt für eine in diesem Zeitra
Beim erneuten Aktivieren von EndPrevent gilt frühestens dessen Startzeitpunkt als Grenze.
Ein Rechtsklick mit Enderauge auf einen leeren, gesperrten Endportalrahmen wird für beide Hände
abgebrochen. Nur der auslösende Spieler erhält einen zufälligen konfigurierten Text in der Actionbar,
abgebrochen. Nur der auslösende Spieler erhält einen zufälligen konfigurierten Text im Chat,
höchstens einmal pro Server-Tick. Die Spieler-Zuordnung wird beim Verlassen entfernt.
Die bestehenden Meldungen beim Betreten gesperrter Portale und Gateways bleiben getrennt davon.
Alle Flavourtexte und zeitgesteuerten Chat-Effekte verwenden einheitlich End-Grün (`#80A71A`).
## Erweiterungen und Leistung
@@ -3,7 +3,7 @@ package eu.mhsl.craftattack.spawn.common.appliances.tooling.endPrevent;
import eu.mhsl.craftattack.spawn.common.appliances.tooling.dimensionScheduler.DimensionScheduler;
import eu.mhsl.craftattack.spawn.common.appliances.tooling.dimensionScheduler.DimensionScheduler.Effect;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
@@ -13,6 +13,7 @@ import java.util.concurrent.ThreadLocalRandom;
/** Presents YAML-defined End effects. Add sounds or other effects in play(). */
final class EndOpeningEffects {
private static final TextColor END_GREEN = TextColor.color(0x80A71A);
private @Nullable DimensionScheduler scheduler;
void configure(DimensionScheduler scheduler) {
@@ -28,7 +29,7 @@ final class EndOpeningEffects {
List<String> messages = this.scheduler.getMessages("end-activation-denied");
if(messages.isEmpty()) return;
String message = messages.get(ThreadLocalRandom.current().nextInt(messages.size()));
player.sendActionBar(Component.text(message, NamedTextColor.RED));
player.sendMessage(Component.text(message, END_GREEN));
}
void playOpening() {
@@ -38,8 +39,7 @@ final class EndOpeningEffects {
}
void play(Effect effect) {
NamedTextColor color = effect.minutesBeforeOpening() == 0 ? NamedTextColor.LIGHT_PURPLE : NamedTextColor.GRAY;
Component message = Component.text(effect.message(), color);
Component message = Component.text(effect.message(), END_GREEN);
Bukkit.getOnlinePlayers().forEach(player -> player.sendMessage(message));
}
}
@@ -22,7 +22,7 @@ import java.util.Map;
import java.util.UUID;
class EndPreventListener extends ApplianceListener<EndPrevent> {
private final Map<UUID, Integer> lastDeniedActivationTick = new HashMap<>();
private final Map<UUID, Integer> lastDeniedTick = new HashMap<>();
@EventHandler
public void onEnderEyeInteraction(PlayerInteractEvent event) {
@@ -32,20 +32,13 @@ class EndPreventListener extends ApplianceListener<EndPrevent> {
if(!(event.getClickedBlock().getBlockData() instanceof EndPortalFrame frame) || frame.hasEye()) return;
if(event.getItem() == null) return;
if(!event.getItem().getType().equals(Material.ENDER_EYE)) return;
if(!this.getAppliance().isEndClosed()) return;
// Cancel either hand, but show only one flavour text if both hands fire in the same tick.
event.setCancelled(true);
Player player = event.getPlayer();
int currentTick = Bukkit.getCurrentTick();
Integer previousTick = this.lastDeniedActivationTick.put(player.getUniqueId(), currentTick);
if(previousTick != null && previousTick == currentTick) return;
this.getAppliance().effects().denyActivation(player);
this.cancelIfClosed(event, event.getPlayer());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
this.lastDeniedActivationTick.remove(event.getPlayer().getUniqueId());
this.lastDeniedTick.remove(event.getPlayer().getUniqueId());
}
@EventHandler
@@ -62,16 +55,15 @@ class EndPreventListener extends ApplianceListener<EndPrevent> {
this.cancelIfOnlyInner(event, event.getPlayer());
}
private void cancelIfClosed(Cancellable event, Player p) {
private void cancelIfClosed(Cancellable event, Player player) {
if(!this.getAppliance().isEndClosed()) return;
event.setCancelled(true);
// Cancel every attempt, but show only one flavour text per player and server tick.
int currentTick = Bukkit.getCurrentTick();
Integer previousTick = this.lastDeniedActivationTick.put(p.getUniqueId(), currentTick);
Integer previousTick = this.lastDeniedTick.put(player.getUniqueId(), currentTick);
if(previousTick != null && previousTick == currentTick) return;
this.getAppliance().effects().denyActivation(p);
/*event.setCancelled(true);
p.sendActionBar(Component.text("Das End ist nicht freigeschaltet!", NamedTextColor.RED));*/
this.getAppliance().effects().denyActivation(player);
}
private void cancelIfOnlyInner(Cancellable event, Player p) {