Skip to content

Conversation

@vLuckyyy
Copy link
Member

@vLuckyyy vLuckyyy commented Feb 9, 2026

No description provided.

@vLuckyyy vLuckyyy requested a review from a team as a code owner February 9, 2026 20:13
@vLuckyyy vLuckyyy changed the title feat(helpop): add helpop reply functionality and related events GH-1296 feat(helpop): add helpop reply functionality and related events Feb 9, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable helpop reply feature, complete with a new service, command, and event. The implementation is well-structured and the code is generally clean. I've identified a couple of areas for improvement related to configurability and code coupling to enhance maintainability, which are detailed in the specific comments.

.placeholder("{TEXT}", escapedMessage);

for (Player onlinePlayer : this.server.getOnlinePlayers()) {
if (!onlinePlayer.hasPermission(HelpOpCommand.HELPOP_SPY)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The HELPOP_SPY constant is referenced from HelpOpCommand. This creates a tight coupling between two command classes. It would be better to define this permission constant in a more central and accessible place, for example, the HelpOpService interface. This would improve modularity and make the code easier to maintain.

For example, you could add String HELPOP_SPY_PERMISSION = "eternalcore.helpop.spy"; to HelpOpService and use it in both command classes.

class HelpOpServiceImpl implements HelpOpService {

private final Cache<UUID, Boolean> helpOpSenders = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofHours(1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The cache expiration is hardcoded to 1 hour. The Javadoc for HelpOpService#hasSentHelpOp states that 'Helpop requests expire after a configured duration (default: 1 hour)', which implies this value should be configurable. Consider adding a setting for this in HelpOpSettings and using it here to allow for configuration.

*
* @param playerUuid the UUID of the player who sent the helpop request
*/
void markSender(@NotNull UUID playerUuid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

markHelpOp

import org.jspecify.annotations.NonNull;

@Service
class HelpOpServiceImpl implements HelpOpService {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class HelpOpServiceImpl implements HelpOpService {
class CachedHelpOpService implements HelpOpService {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why though?? So we should add the Cached prefix to everything that has cache? I think we have other services and they don't have that prefix, so we need to be consistent.

class HelpOpServiceImpl implements HelpOpService {

private final Cache<UUID, Boolean> helpOpSenders = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofHours(1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo too much

Suggested change
.expireAfterWrite(Duration.ofHours(1))
.expireAfterWrite(Duration.ofMinutes(10))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this configurable

/**
* Gets the reply message content.
*
* @return the reply content
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @return the reply content
* @return the reply content as raw string

I think it would be good to specify this in Javadoc, as the tag-escaping process is done after calling the event: https://github.com/EternalCodeTeam/EternalCore/pull/1296/changes#diff-2c33053246b78aac204d193999e57efd64d38f95eeb1bd6cc571be001f923810R62

class HelpOpServiceImpl implements HelpOpService {

private final Cache<UUID, Boolean> helpOpSenders = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofHours(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with Gemini here; it won't hurt us if we make this configurable.

Comment on lines +72 to +78
for (Player onlinePlayer : this.server.getOnlinePlayers()) {
if (!onlinePlayer.hasPermission(HelpOpCommand.HELPOP_SPY)) {
continue;
}

notice = notice.player(onlinePlayer.getUniqueId());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Service
class HelpOpServiceImpl implements HelpOpService {

private final Cache<UUID, Boolean> helpOpSenders = CacheBuilder.newBuilder()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question, do we plan to manually invalidate this cache? The current implementation just allows the administrators to reply to a single HelpOp request infinite times in the given time period.

.placeholder("{TEXT}", escapedMessage);

for (Player onlinePlayer : this.server.getOnlinePlayers()) {
if (!onlinePlayer.hasPermission(HelpOpCommand.HELPOP_SPY)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the concept, but in a few hundred player servers with players spamming the helpop and admins replying, it will basically also send the reply to all other administrators with the permission, and they have absolutely no way to toggle it.

A /helpoptoggle <all/reply/requests> with a simple cache should suffice IMO. Up for discussion with other reviewers.


@Comment("# {ADMIN} - Admin who replied, {PLAYER} - Player who received the reply, {TEXT} - Reply message")
Notice adminReply = BukkitNotice.builder()
.chat("<dark_gray>[<color:#9d6eef>HelpOp<dark_gray>] <white>{ADMIN} <dark_gray>-> <white>{PLAYER}<dark_gray>: <white>{TEXT}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.chat("<dark_gray>[<color:#9d6eef>HelpOp<dark_gray>] <white>{ADMIN} <dark_gray>-> <white>{PLAYER}<dark_gray>: <white>{TEXT}")
.chat("<dark_gray>[<color:#9d6eef>HelpOp<dark_gray>] <white>{ADMIN} <dark_gray> <white>{PLAYER}<dark_gray>: <white>{TEXT}")

private String content;
private boolean cancelled;

public HelpOpReplyEvent(@NotNull Player admin, @NotNull Player target, @NotNull String content) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not the Jspecify?????????????????????

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applies for the whole class

.sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.0f)
.build();

@Comment(" ")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Comment(" ")
@Comment("# {PLAYER} - Nazwa gracza")

this.eventCaller = eventCaller;
this.server = server;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add default execute - when player is not provided - then admin replays to the last helpop message

Comment on lines +19 to +20

@Command(name = "helpopreply")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add alias "hr"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants