Skip to content

Commit 4996717

Browse files
GH-766 Add multiple notifications at once. (#873)
* Bump LiteCommands version to 3.8.0. Use experimental "Literal" feature. * Separated alert command Updated methods removeBroadcastWithType and removeLatestBroadcastWithType Removed unnecessary import * Fast fix NullPointerException * Fix FNF Fix Duration Override Added optional command duration argument * Update eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/alert/AlertQueueCommand.java Co-authored-by: Norbert Dejlich <[email protected]> * Rename EternalCoreBroadcastImpl -> EternalCoreBroadcast --------- Co-authored-by: Rollczi <[email protected]>
1 parent f6100b5 commit 4996717

File tree

10 files changed

+201
-67
lines changed

10 files changed

+201
-67
lines changed

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object Versions {
2323
const val ORMLITE = "6.1"
2424
const val HIKARI_CP = "6.0.0"
2525

26-
const val LITE_COMMANDS = "3.7.1"
26+
const val LITE_COMMANDS = "3.8.0"
2727
const val LITE_SKULL_API = "1.3.0"
2828

2929
const val GUAVA = "33.3.1-jre"

eternalcore-core/src/main/java/com/eternalcode/core/bridge/litecommand/argument/DurationArgument.java

Lines changed: 0 additions & 59 deletions
This file was deleted.

eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/AlertCommand.java renamed to eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/alert/AlertCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
package com.eternalcode.core.feature.essentials;
1+
package com.eternalcode.core.feature.essentials.alert;
22

33
import com.eternalcode.annotations.scan.command.DescriptionDocs;
44
import com.eternalcode.core.injector.annotations.Inject;
55
import com.eternalcode.core.notice.NoticeService;
66
import com.eternalcode.core.notice.NoticeTextType;
77
import dev.rollczi.litecommands.annotations.argument.Arg;
8-
import dev.rollczi.litecommands.annotations.join.Join;
8+
import dev.rollczi.litecommands.annotations.command.Command;
99
import dev.rollczi.litecommands.annotations.execute.Execute;
10+
import dev.rollczi.litecommands.annotations.join.Join;
1011
import dev.rollczi.litecommands.annotations.permission.Permission;
11-
import dev.rollczi.litecommands.annotations.command.Command;
1212

1313
@Command(name = "alert", aliases = { "broadcast", "bc" })
1414
@Permission("eternalcore.alert")
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.eternalcode.core.feature.essentials.alert;
2+
3+
import com.eternalcode.commons.scheduler.Scheduler;
4+
import com.eternalcode.core.injector.annotations.Inject;
5+
import com.eternalcode.core.injector.annotations.component.Service;
6+
import com.eternalcode.core.notice.EternalCoreBroadcast;
7+
import com.eternalcode.core.notice.NoticeTextType;
8+
import com.eternalcode.core.translation.Translation;
9+
import com.eternalcode.core.viewer.Viewer;
10+
11+
import com.eternalcode.multification.notice.NoticeBroadcast;
12+
import java.time.Duration;
13+
import java.util.ArrayList;
14+
import java.util.HashMap;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.Set;
18+
import java.util.UUID;
19+
20+
@Service
21+
class AlertManager {
22+
23+
private final static Set<NoticeTextType> DELAYED_TYPES = Set.of(NoticeTextType.TITLE, NoticeTextType.SUBTITLE, NoticeTextType.ACTIONBAR);
24+
25+
private final Map<AlertKey, List<NoticeBroadcast<Viewer, Translation, ?>>> broadcasts = new HashMap<>();
26+
private final Scheduler scheduler;
27+
28+
@Inject
29+
AlertManager(Scheduler scheduler) {
30+
this.scheduler = scheduler;
31+
}
32+
33+
void addBroadcast(UUID uuid, NoticeTextType type, NoticeBroadcast<Viewer, Translation, ?> broadcast) {
34+
this.broadcasts.computeIfAbsent(new AlertKey(uuid, type), k -> new ArrayList<>()).add(broadcast);
35+
}
36+
37+
boolean removeBroadcastWithType(UUID uuid, NoticeTextType type) {
38+
return this.broadcasts.remove(new AlertKey(uuid, type)) != null;
39+
}
40+
41+
boolean removeLatestBroadcastWithType(UUID uuid, NoticeTextType type) {
42+
AlertKey key = new AlertKey(uuid, type);
43+
List<NoticeBroadcast<Viewer, Translation, ?>> broadcasts = this.broadcasts.get(key);
44+
45+
if (broadcasts != null && !broadcasts.isEmpty()) {
46+
broadcasts.remove(broadcasts.size() - 1);
47+
if (broadcasts.isEmpty()) {
48+
this.removeBroadcastWithType(uuid, type);
49+
}
50+
return true;
51+
}
52+
53+
return false;
54+
}
55+
56+
void clearBroadcasts(UUID uuid) {
57+
this.broadcasts.entrySet().removeIf(entry -> entry.getKey().uuid().equals(uuid));
58+
}
59+
60+
void send(UUID uuid, Duration delay) {
61+
this.broadcasts.forEach((alertKey, broadcasts) -> {
62+
if (!alertKey.uuid().equals(uuid)) {
63+
return;
64+
}
65+
66+
NoticeTextType type = alertKey.type();
67+
if (DELAYED_TYPES.contains(type)) {
68+
for (int i = 0; i < broadcasts.size(); i++) {
69+
NoticeBroadcast<Viewer, Translation, ?> broadcast = broadcasts.get(i);
70+
scheduler.runLater(broadcast::send, delay.multipliedBy(i));
71+
}
72+
73+
return;
74+
}
75+
76+
for (NoticeBroadcast<Viewer, Translation, ?> broadcast : broadcasts) {
77+
broadcast.send();
78+
}
79+
});
80+
81+
clearBroadcasts(uuid);
82+
}
83+
84+
private record AlertKey(UUID uuid, NoticeTextType type) {}
85+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.eternalcode.core.feature.essentials.alert;
2+
3+
import com.eternalcode.annotations.scan.command.DescriptionDocs;
4+
import com.eternalcode.core.injector.annotations.Inject;
5+
import com.eternalcode.core.notice.NoticeService;
6+
import com.eternalcode.core.notice.NoticeTextType;
7+
import dev.rollczi.litecommands.annotations.argument.Arg;
8+
import dev.rollczi.litecommands.annotations.context.Sender;
9+
import dev.rollczi.litecommands.annotations.join.Join;
10+
import dev.rollczi.litecommands.annotations.execute.Execute;
11+
import dev.rollczi.litecommands.annotations.literal.Literal;
12+
import dev.rollczi.litecommands.annotations.permission.Permission;
13+
import dev.rollczi.litecommands.annotations.command.Command;
14+
import org.bukkit.entity.Player;
15+
16+
import java.time.Duration;
17+
import java.util.Optional;
18+
19+
@Command(name = "alert-queue", aliases = { "alert-q" })
20+
@Permission("eternalcore.alert.queue")
21+
class AlertQueueCommand {
22+
23+
private final NoticeService noticeService;
24+
private final AlertManager alertService;
25+
26+
@Inject
27+
AlertQueueCommand(
28+
NoticeService noticeService,
29+
AlertManager alertService
30+
) {
31+
this.noticeService = noticeService;
32+
this.alertService = alertService;
33+
}
34+
35+
@Execute(name = "add")
36+
@DescriptionDocs(description = "Adds alert to the queue with specified notice type and messages", arguments = "<type> <message>")
37+
void executeAdd(@Sender Player sender, @Arg NoticeTextType type, @Join String text) {
38+
39+
this.alertService.addBroadcast(sender.getUniqueId(), type, this.noticeService.create()
40+
.notice(type, translation -> translation.chat().alertMessageFormat())
41+
.placeholder("{BROADCAST}", text)
42+
.onlinePlayers());
43+
44+
this.noticeService.create()
45+
.player(sender.getUniqueId())
46+
.notice(translation -> translation.chat().alertQueueAdded())
47+
.send();
48+
}
49+
50+
@Execute(name = "remove")
51+
@DescriptionDocs(description = "Removes all alerts of the given type from the queue", arguments = "<type> all")
52+
void executeRemoveAll(@Sender Player sender, @Arg NoticeTextType type, @Literal("all") String all) {
53+
boolean success = this.alertService.removeBroadcastWithType(sender.getUniqueId(), type);
54+
55+
this.noticeService.create()
56+
.player(sender.getUniqueId())
57+
.notice(translation -> success ? translation.chat().alertQueueRemoved() : translation.chat().alertQueueEmpty())
58+
.send();
59+
}
60+
61+
@Execute(name = "remove")
62+
@DescriptionDocs(description = "Removes a latest alert of the given type from the queue", arguments = "<type> latest")
63+
void executeRemove(@Sender Player sender, @Arg NoticeTextType type, @Literal("latest") String latest) {
64+
boolean success = this.alertService.removeLatestBroadcastWithType(sender.getUniqueId(), type);
65+
66+
this.noticeService.create()
67+
.player(sender.getUniqueId())
68+
.notice(translation -> success ? translation.chat().alertQueueRemoved() : translation.chat().alertQueueEmpty())
69+
.send();
70+
}
71+
72+
@Execute(name = "clear")
73+
@DescriptionDocs(description = "Clears all alerts from the queue")
74+
void executeClear(@Sender Player sender) {
75+
this.alertService.clearBroadcasts(sender.getUniqueId());
76+
this.noticeService.create()
77+
.player(sender.getUniqueId())
78+
.notice(translation -> translation.chat().alertQueueCleared())
79+
.send();
80+
}
81+
82+
@Execute(name = "send")
83+
@DescriptionDocs(description = "Sends all alerts from the queue")
84+
void executeSend(@Sender Player sender, @Arg Optional<Duration> duration) {
85+
this.alertService.send(sender.getUniqueId(), duration.orElse(Duration.ofSeconds(2)));
86+
this.noticeService.create()
87+
.player(sender.getUniqueId())
88+
.notice(translation -> translation.chat().alertQueueSent())
89+
.send();
90+
}
91+
}

eternalcore-core/src/main/java/com/eternalcode/core/notice/EternalCoreBroadcastImpl.java renamed to eternalcore-core/src/main/java/com/eternalcode/core/notice/EternalCoreBroadcast.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
/**
2525
* This class is an extension of {@link NoticeBroadcastImpl} that provides more methods for creating notices.
2626
*/
27-
public class EternalCoreBroadcastImpl<Viewer, Translation, B extends EternalCoreBroadcastImpl<Viewer, Translation, B>>
27+
public class EternalCoreBroadcast<Viewer, Translation, B extends EternalCoreBroadcast<Viewer, Translation, B>>
2828
extends NoticeBroadcastImpl<Viewer, Translation, B> {
2929

30-
public EternalCoreBroadcastImpl(
30+
public EternalCoreBroadcast(
3131
AsyncExecutor asyncExecutor,
3232
TranslationProvider<Translation> translationProvider,
3333
ViewerProvider<Viewer> viewerProvider,

eternalcore-core/src/main/java/com/eternalcode/core/notice/NoticeService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ public PlatformBroadcaster platformBroadcaster() {
112112
}
113113

114114
@Override
115-
public EternalCoreBroadcastImpl<Viewer, Translation, ?> create() {
116-
return new EternalCoreBroadcastImpl<>(
115+
public EternalCoreBroadcast<Viewer, Translation, ?> create() {
116+
return new EternalCoreBroadcast<>(
117117
this.asyncExecutor(),
118118
this.translationProvider(),
119119
this.viewerProvider(),

eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.eternalcode.multification.notice.Notice;
77
import org.bukkit.Material;
88
import org.bukkit.event.entity.EntityDamageEvent;
9+
910
import java.util.Collection;
1011
import java.util.HashMap;
1112
import java.util.List;
@@ -132,6 +133,11 @@ interface ChatSection {
132133
Notice tellrawNoSaved();
133134
Notice tellrawMultipleSent();
134135
Notice tellrawCleared();
136+
Notice alertQueueAdded();
137+
Notice alertQueueRemoved();
138+
Notice alertQueueCleared();
139+
Notice alertQueueEmpty();
140+
Notice alertQueueSent();
135141
}
136142

137143
// Warp Section

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ public static class ENChatSection implements ChatSection {
296296
public Notice tellrawNoSaved = Notice.chat("<red>✘ <dark_red>No messages saved in queue!");
297297
public Notice tellrawMultipleSent = Notice.chat("<green>► <white>Messages sent! Message que has been cleared!");
298298
public Notice tellrawCleared = Notice.chat("<green>► <white>Message queue cleared!");
299+
public Notice alertQueueAdded = Notice.chat("<green>► <white>Message added to the queue!");
300+
public Notice alertQueueRemoved = Notice.chat("<green>► <white>Message removed from the queue!");
301+
public Notice alertQueueCleared = Notice.chat("<green>► <white>Message queue cleared!");
302+
public Notice alertQueueEmpty = Notice.chat("<red>✘ <dark_red>Error: <red>The message queue is empty!");
303+
public Notice alertQueueSent = Notice.chat("<green>► <white>All messages sent from the queue!");
304+
299305
}
300306

301307
@Description({

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ public static class PLChatSection implements ChatSection {
299299
public Notice tellrawNoSaved = Notice.chat("<red>✘ <dark_red>Nie ma zapisanych wiadomości!");
300300
public Notice tellrawMultipleSent = Notice.chat("<green>► <white>Wysłano wszystkie zapisane wiadomości!");
301301
public Notice tellrawCleared = Notice.chat("<green>► <white>Wyczyszczono zapisane wiadomości!");
302+
public Notice alertQueueAdded = Notice.chat("<green>► <white>Dodano wiadomość do kolejki!");
303+
public Notice alertQueueRemoved = Notice.chat("<green>► <white>Usunięto wiadomość z kolejki!");
304+
public Notice alertQueueCleared = Notice.chat("<green>► <white>Wyczyszczono kolejkę wiadomości!");
305+
public Notice alertQueueEmpty = Notice.chat("<red>✘ <dark_red>Błąd: <red>Kolejka wiadomości jest pusta!");
306+
public Notice alertQueueSent = Notice.chat("<green>► <white>Wysłano wszystkie wiadomości z kolejki!");
302307
}
303308

304309
@Description({

0 commit comments

Comments
 (0)