Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b5e54ad
Innit commit
CitralFlo Jan 12, 2025
ffd29c5
In progress: add messages, setup methods and commands
CitralFlo Jan 14, 2025
88a71f7
Merge branch 'refs/heads/master' into msgtoggle
CitralFlo Jan 17, 2025
43ea1b0
Add msgToggle repo, service, API and commands
CitralFlo Jan 17, 2025
f054dbd
Fix logic
CitralFlo Jan 17, 2025
2437624
Fix logic, rename messages
CitralFlo Jan 22, 2025
aa1ff47
Remove comments
CitralFlo Jan 22, 2025
6da3ddf
Delete duplicated message.
CitralFlo Jan 22, 2025
4a77643
Update eternalcore-api/src/main/java/com/eternalcode/core/feature/msg…
CitralFlo Jan 22, 2025
00e97d0
Delete duplicated message.
CitralFlo Jan 22, 2025
5291625
Merge remote-tracking branch 'origin/msgtoggle' into msgtoggle
CitralFlo Jan 22, 2025
a091a18
Fix coderabbit issue
CitralFlo Jan 22, 2025
b3dae93
Fix naming and logic.
CitralFlo Jan 28, 2025
97d5914
Merge branch 'master' into msgtoggle
CitralFlo Jan 28, 2025
76d85d9
Resolve @imDMK review
CitralFlo Jan 28, 2025
df9b84f
Add comments to api
CitralFlo Jan 28, 2025
4709133
Resolve Rollcz's review
CitralFlo Jan 28, 2025
450813c
Resolve coderabbit review
CitralFlo Jan 28, 2025
f22fe08
Update README.md
CitralFlo Jan 30, 2025
98cb286
Fix logic: enable -> enable priv messages.
CitralFlo Feb 5, 2025
f9cd9b7
Resolve @coderabbitai nitpick comment, simplify command and api
CitralFlo Feb 5, 2025
39b6dfc
Refactor names of variables following vLuckyyy comment
CitralFlo Feb 5, 2025
1ed9c34
Change name from toggleState to State
CitralFlo Feb 5, 2025
d72ae5c
Simplify logic (i hope @Rollczi will like it) refactor to PrivateChat…
CitralFlo Feb 6, 2025
6a12777
Merge branch 'master' into msgtoggle
CitralFlo Feb 12, 2025
dabdf7d
Resolve master changes
CitralFlo Feb 12, 2025
297cff4
Resolve @coderabbitai 's review
CitralFlo Feb 12, 2025
1b57a89
Cleanup method and parameters names. Remove unused classes.
Rollczi Feb 13, 2025
6227fa3
Simplify commands
Rollczi Feb 13, 2025
5a41247
Fix command messages
Rollczi Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Get the latest development builds from our [GitHub Actions](https://github.com/E
- Chat On/Off Switch
- Chat Slow Mode
- /ignore and /unignore (with -all option)
- /msg, /socialspy, and /reply commands
- /msg, /msgtoggle, /socialspy, and /reply commands
- /helpop command
- Advanced Notification System allowing you to customize every message to your liking (Title, Subtitle, Actionbar, Chat, etc.)
- :hammer: Open Utility Blocks with simple commands like `/workbench`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.eternalcode.core.feature.privatechat.toggle;

/**
* Enum representing state of blocking incoming private messages by the player.
*/
public enum PrivateChatState {

/**
* Player can receive private messages.
*/
ENABLE,

/**
* Player cannot receive private messages.
*/
DISABLE;

PrivateChatState invert() {
return this == ENABLE ? DISABLE : ENABLE;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.eternalcode.core.feature.privatechat.toggle;

import java.util.UUID;
import java.util.concurrent.CompletableFuture;

/**
* This Service manages player's receiving of private messages
*/
public interface PrivateChatStateService {

/**
* Checks status of player's private chat messages blocking.
*
* @param playerUniqueId player's UUID.
* @return state of player's private chat messages blocking.
*/
CompletableFuture<PrivateChatState> getChatState(UUID playerUniqueId);

/**
* Sets blocking of incoming private messages.
*
* @param playerUniqueId player's UUID.
* @param state desired state of player's private chat messages blocking.
*/
CompletableFuture<Void> setChatState(UUID playerUniqueId, PrivateChatState state);


/**
* Toggle blocking of incoming private messages.
*
* @param playerUniqueId player's UUID.
* @return new state of player's private chat messages blocking.
*/
CompletableFuture<PrivateChatState> toggleChatState(UUID playerUniqueId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.eternalcode.core.event.EventCaller;
import com.eternalcode.core.feature.ignore.IgnoreService;
import com.eternalcode.core.feature.privatechat.toggle.PrivateChatStateService;
import com.eternalcode.core.feature.privatechat.toggle.PrivateChatState;
import com.eternalcode.core.injector.annotations.Inject;
import com.eternalcode.core.injector.annotations.component.Service;
import com.eternalcode.core.notice.NoticeService;
Expand All @@ -24,6 +26,7 @@ class PrivateChatServiceImpl implements PrivateChatService {
private final UserManager userManager;
private final PrivateChatPresenter presenter;
private final EventCaller eventCaller;
private final PrivateChatStateService privateChatStateService;

private final Cache<UUID, UUID> replies = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofHours(1))
Expand All @@ -36,12 +39,14 @@ class PrivateChatServiceImpl implements PrivateChatService {
NoticeService noticeService,
IgnoreService ignoreService,
UserManager userManager,
EventCaller eventCaller
EventCaller eventCaller,
PrivateChatStateService privateChatStateService
) {
this.noticeService = noticeService;
this.ignoreService = ignoreService;
this.userManager = userManager;
this.eventCaller = eventCaller;
this.privateChatStateService = privateChatStateService;

this.presenter = new PrivateChatPresenter(noticeService);
}
Expand All @@ -53,15 +58,25 @@ void privateMessage(User sender, User target, String message) {
return;
}

this.ignoreService.isIgnored(target.getUniqueId(), sender.getUniqueId()).thenAccept(isIgnored -> {
if (!isIgnored) {
this.replies.put(target.getUniqueId(), sender.getUniqueId());
this.replies.put(sender.getUniqueId(), target.getUniqueId());
UUID uniqueId = target.getUniqueId();

this.privateChatStateService.getChatState(uniqueId).thenAccept(privateChatState -> {
if (privateChatState == PrivateChatState.DISABLE) {
this.noticeService.player(sender.getUniqueId(), translation -> translation.privateChat().receiverDisabledMessages());

return;
}

PrivateChatEvent event = new PrivateChatEvent(sender.getUniqueId(), target.getUniqueId(), message);
this.eventCaller.callEvent(event);
this.presenter.onPrivate(new PrivateMessage(sender, target, event.getContent(), this.socialSpy, isIgnored));
this.ignoreService.isIgnored(uniqueId, sender.getUniqueId()).thenAccept(isIgnored -> {
if (!isIgnored) {
this.replies.put(uniqueId, sender.getUniqueId());
this.replies.put(sender.getUniqueId(), uniqueId);
}

PrivateChatEvent event = new PrivateChatEvent(sender.getUniqueId(), uniqueId, message);
this.eventCaller.callEvent(event);
this.presenter.onPrivate(new PrivateMessage(sender, target, event.getContent(), this.socialSpy, isIgnored));
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ public class ENPrivateMessages implements PrivateChatMessages {
public Notice socialSpyMessage = Notice.chat(
"<dark_gray>[<red>ss<dark_gray>] <dark_gray>[<gray>{SENDER} -> <white>{TARGET}<dark_gray>]<gray>: <white>{MESSAGE}");

public Notice receiverDisabledMessages = Notice.chat("<red>► <dark_red>This player has disabled private messages!");

public Notice selfMessagesDisabled = Notice.chat("<green>► <white>Private messages have been <red>disabled<white>!");
public Notice selfMessagesEnabled = Notice.chat("<green>► <white>Private messages have been <green>enabled<white>!");

@Description("# {PLAYER} - Player")
public Notice otherMessagesDisabled = Notice.chat("<green>► <white>Private messages have been <red>disabled <white>for <green>{PLAYER}<white>!");
public Notice otherMessagesEnabled = Notice.chat("<green>► <white>Private messages have been <green>enabled <white>for <green>{PLAYER}<white>!");

@Description(" ")
public Notice socialSpyEnable = Notice.chat("<green>► <white>SocialSpy has been {STATE}<white>!");
public Notice socialSpyDisable = Notice.chat("<red>► <white>SocialSpy has been {STATE}<white>!");
Expand All @@ -39,10 +48,10 @@ public class ENPrivateMessages implements PrivateChatMessages {
public Notice alreadyIgnorePlayer = Notice.chat("<red>► <dark_red>You already ignore this player!");

@Description("# {PLAYER} - Unignored player")
public Notice unIgnorePlayer = Notice.chat("<red>► <dark_red>{PLAYER} <red>player has been uningored!");
public Notice unIgnorePlayer = Notice.chat("<red>► <dark_red>{PLAYER} <red>player has been unignored!");

@Description(" ")
public Notice unIgnoreAll = Notice.chat("<red>► <dark_red>All players have been uningored!");
public Notice unIgnoreAll = Notice.chat("<red>► <dark_red>All players have been unignored!");
public Notice cantUnIgnoreYourself = Notice.chat("<red>► <dark_red>You can't unignore yourself!");

@Description({" ", "# {PLAYER} - Ignored player"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ public class PLPrivateChatMessages implements PrivateChatMessages {
public Notice socialSpyEnable = Notice.chat("<green>► <white>SocialSpy został {STATE}<white>!");
public Notice socialSpyDisable = Notice.chat("<red>► <white>SocialSpy został {STATE}<white>!");

public Notice receiverDisabledMessages = Notice.chat("<red>► <dark_red>Wiadomości prywatne zostały wyłączone!");

public Notice selfMessagesDisabled = Notice.chat("<green>► <white>Wiadomości prywatne zostały <red>wyłączone!");
public Notice selfMessagesEnabled = Notice.chat("<green>► <white>Wiadomości prywatne zostały <green>włączone!");

@Description({" ", "# {PLAYER} - Gracz któremu wyłączono wiadomości prywatne"})
public Notice otherMessagesDisabled = Notice.chat("<green>► <white>Wiadomości prywatne zostały <red>wyłączone <white>dla gracza <green>{PLAYER}<white>!");
public Notice otherMessagesEnabled = Notice.chat("<green>► <white>Wiadomości prywatne zostały <green>włączone <white>dla gracza <green>{PLAYER}<white>!");

@Description({" ", "# {PLAYER} - Gracz który jest zignorowany"})
public Notice ignorePlayer = Notice.chat("<green>► <white>Zignorowano gracza <red>{PLAYER}<white>!");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ public interface PrivateChatMessages {
Notice socialSpyEnable();
Notice socialSpyDisable();

Notice receiverDisabledMessages();
Notice selfMessagesDisabled();
Notice selfMessagesEnabled();
Notice otherMessagesDisabled();
Notice otherMessagesEnabled();

Notice ignorePlayer();
Notice ignoreAll();
Notice unIgnorePlayer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.eternalcode.core.feature.privatechat.toggle;

import com.eternalcode.annotations.scan.command.DescriptionDocs;
import com.eternalcode.core.injector.annotations.Inject;
import com.eternalcode.core.notice.NoticeService;
import dev.rollczi.litecommands.annotations.argument.Arg;
import dev.rollczi.litecommands.annotations.command.Command;
import dev.rollczi.litecommands.annotations.context.Context;
import dev.rollczi.litecommands.annotations.execute.Execute;
import dev.rollczi.litecommands.annotations.permission.Permission;
import java.util.UUID;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

@Command(name = "msgtoggle")
@Permission("eternalcore.msgtoggle")
class PrivateChatStateCommand {

private final PrivateChatStateService privateChatStateService;
private final NoticeService noticeService;

@Inject
PrivateChatStateCommand(PrivateChatStateService privateChatStateService, NoticeService noticeService) {
this.privateChatStateService = privateChatStateService;
this.noticeService = noticeService;
}

@Execute
@DescriptionDocs(description = "Toggle receiving private messages")
void execute(@Context Player sender) {
UUID player = sender.getUniqueId();
this.privateChatStateService.toggleChatState(player)
.thenAccept(toggledState -> noticePlayer(toggledState, player));
}

@Execute
@DescriptionDocs(description = "Switch receiving private messages", arguments = "<state>")
void execute(@Context Player sender, @Arg PrivateChatState state) {
UUID player = sender.getUniqueId();
this.privateChatStateService.setChatState(player, state)
.thenAccept(ignored -> noticePlayer(state, player));
}

@Execute
@Permission("eternalcore.msgtoggle.other")
@DescriptionDocs(description = "Switch receiving private messages for other player", arguments = "<player>")
void other(@Context CommandSender sender, @Arg Player target) {
UUID player = target.getUniqueId();
this.privateChatStateService.toggleChatState(player)
.thenAccept(toggledState -> noticeOtherPlayer(sender, toggledState, target));
}

@Execute
@Permission("eternalcore.msgtoggle.other")
@DescriptionDocs(description = "Switch receiving private messages for other player", arguments = "<player> <toggle>")
void other(@Context CommandSender sender, @Arg Player target, @Arg PrivateChatState state) {
UUID player = target.getUniqueId();
this.privateChatStateService.setChatState(player, state)
.thenAccept(ignored -> noticeOtherPlayer(sender, state, target));
}

private void noticeOtherPlayer(CommandSender sender, PrivateChatState state, Player target) {
this.noticePlayer(state, target.getUniqueId());
if (sender.equals(target)) {
return;
}

this.noticeService.create()
.sender(sender)
.notice(translation -> state == PrivateChatState.DISABLE
? translation.privateChat().otherMessagesDisabled()
: translation.privateChat().otherMessagesEnabled()
)
.placeholder("{PLAYER}", target.getName())
.send();
}

private void noticePlayer(PrivateChatState state, UUID player) {
this.noticeService.create()
.player(player)
.notice(translation -> state == PrivateChatState.ENABLE
? translation.privateChat().selfMessagesEnabled()
: translation.privateChat().selfMessagesDisabled()
)
.send();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.eternalcode.core.feature.privatechat.toggle;


import java.util.UUID;
import java.util.concurrent.CompletableFuture;

interface PrivateChatStateRepository {

CompletableFuture<PrivateChatState> getPrivateChatState(UUID uuid);

CompletableFuture<Void> setPrivateChatState(UUID uuid, PrivateChatState toggledOff);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.eternalcode.core.feature.privatechat.toggle;

import com.eternalcode.commons.scheduler.Scheduler;
import com.eternalcode.core.database.DatabaseManager;
import com.eternalcode.core.database.wrapper.AbstractRepositoryOrmLite;
import com.eternalcode.core.injector.annotations.Inject;
import com.eternalcode.core.injector.annotations.component.Repository;
import com.j256.ormlite.table.TableUtils;
import java.sql.SQLException;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@Repository
class PrivateChatStateRepositoryOrmLite extends AbstractRepositoryOrmLite implements PrivateChatStateRepository {

@Inject
private PrivateChatStateRepositoryOrmLite(DatabaseManager databaseManager, Scheduler scheduler) throws SQLException {
super(databaseManager, scheduler);
TableUtils.createTableIfNotExists(databaseManager.connectionSource(), PrivateChatStateWrapper.class);
}

@Override
public CompletableFuture<PrivateChatState> getPrivateChatState(UUID uuid) {
return this.selectSafe(PrivateChatStateWrapper.class, uuid)
.thenApply(
optional -> optional.map(PrivateChatStateWrapper::isEnabled).orElse(PrivateChatState.ENABLE)
).exceptionally(throwable -> PrivateChatState.ENABLE);
}

@Override
public CompletableFuture<Void> setPrivateChatState(UUID uuid, PrivateChatState state) {
return this.save(PrivateChatStateWrapper.class, new PrivateChatStateWrapper(uuid, state))
.thenApply(status -> null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.eternalcode.core.feature.privatechat.toggle;

import com.eternalcode.core.injector.annotations.Inject;
import com.eternalcode.core.injector.annotations.component.Service;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;

@Service
class PrivateChatStateServiceImpl implements PrivateChatStateService {

private final PrivateChatStateRepository msgToggleRepository;
private final ConcurrentHashMap<UUID, PrivateChatState> cachedToggleStates;

@Inject
PrivateChatStateServiceImpl(PrivateChatStateRepository msgToggleRepository) {
this.cachedToggleStates = new ConcurrentHashMap<>();
this.msgToggleRepository = msgToggleRepository;

}


@Override
public CompletableFuture<PrivateChatState> getChatState(UUID playerUniqueId) {
if (this.cachedToggleStates.containsKey(playerUniqueId)) {
return CompletableFuture.completedFuture(this.cachedToggleStates.get(playerUniqueId));
}

return this.msgToggleRepository.getPrivateChatState(playerUniqueId);
}

@Override
public CompletableFuture<Void> setChatState(UUID playerUniqueId, PrivateChatState state) {
this.cachedToggleStates.put(playerUniqueId, state);

return this.msgToggleRepository.setPrivateChatState(playerUniqueId, state)
.exceptionally(throwable -> {
this.cachedToggleStates.remove(playerUniqueId);
return null;
});
}

@Override
public CompletableFuture<PrivateChatState> toggleChatState(UUID playerUniqueId) {
return this.getChatState(playerUniqueId).thenCompose(state -> {
PrivateChatState newState = state.invert();
return this.setChatState(playerUniqueId, newState)
.thenApply(aVoid -> newState);
});
}
}
Loading