Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement better adventure audience system #75

Merged
merged 13 commits into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions sonar-api/src/main/java/xyz/jonesdev/sonar/api/Sonar.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import xyz.jonesdev.sonar.api.event.SonarEventManager;
import xyz.jonesdev.sonar.api.fallback.Fallback;
import xyz.jonesdev.sonar.api.logger.LoggerWrapper;
import xyz.jonesdev.sonar.api.server.ServerWrapper;
import xyz.jonesdev.sonar.api.verbose.Verbose;

import java.io.File;
Expand All @@ -35,9 +34,9 @@ public interface Sonar {
String LINE_SEPARATOR = "\n"; // Using System.lineSeparator is broken, for some reason...

/**
* @return A small wrapper for the server
* @return The platform the plugin is being run on
*/
@NotNull ServerWrapper getServer();
@NotNull SonarPlatform getPlatform();

/**
* @return A small wrapper for the plugin logger so we can use the logger everywhere
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import xyz.jonesdev.sonar.api.command.subcommand.Subcommand;

@Getter
@RequiredArgsConstructor
@ToString(of = "rawArguments")
public final class CommandInvocation {
private final InvocationSource sender;
private final Subcommand command;
private final Subcommand subcommand;
private final String[] rawArguments;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
public abstract class InvocationSource {
private final String name;
private final Audience audience;
private final boolean player;

/**
* Sends an empty chat message to the command executor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
package xyz.jonesdev.sonar.api.command;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.cappuccino.Cappuccino;
import xyz.jonesdev.cappuccino.ExpiringCache;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.command.subcommand.Subcommand;
import xyz.jonesdev.sonar.api.command.subcommand.argument.Argument;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.Collections.emptyList;

public interface SonarCommand {
List<String> TAB_SUGGESTIONS = new ArrayList<>();
Expand All @@ -34,63 +38,55 @@ public interface SonarCommand {

ExpiringCache<Object> DELAY = Cappuccino.buildExpiring(500L);

int COPYRIGHT_YEAR = Calendar.getInstance().get(Calendar.YEAR);

List<Component> CACHED_HELP_MESSAGE = new Vector<>();
List<Component> CACHED_HELP_MESSAGE = new ArrayList<>();

default void cacheHelpMessage() {
CACHED_HELP_MESSAGE.addAll(Arrays.asList(
Component.text("Running Sonar " + Sonar.get().getVersion()
+ " on " + Sonar.get().getServer().getPlatform().getDisplayName()
+ ".", NamedTextColor.YELLOW),
Component.text("(C) " + COPYRIGHT_YEAR + " Jones Development and Sonar Contributors", NamedTextColor.YELLOW),
Component.text("https://github.com/jonesdevelopment/sonar", NamedTextColor.GREEN)
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/jonesdevelopment/sonar")),
Component.empty(),
Component.text("Need help or have any questions?", NamedTextColor.YELLOW),
Component.textOfChildren(
Component.text("Open a ticket on the Discord ", NamedTextColor.YELLOW)
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("(Click to open Discord)")))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, "https://jonesdev.xyz/discord/")),
Component.text("or open a new issue on GitHub.", NamedTextColor.YELLOW)
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("(Click to open GitHub)")))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/jonesdevelopment/sonar" +
"/issues"))
),
Component.empty()
));
static void prepareCachedMessages() {
// Cache help message
CACHED_HELP_MESSAGE.clear();
for (final String message : Sonar.get().getConfig().getCommands().getHelpHeader()) {
CACHED_HELP_MESSAGE.add(MiniMessage.miniMessage().deserialize(message
.replace("%version%", Sonar.get().getVersion().getFormatted())
.replace("%platform%", Sonar.get().getPlatform().getDisplayName())
.replace("%copyright_year%", String.valueOf(Calendar.getInstance().get(Calendar.YEAR)))));
}

Sonar.get().getSubcommandRegistry().getSubcommands().forEach(sub -> {
Component component = Component.textOfChildren(
Component.text(" ▪ ", NamedTextColor.GRAY),
Component.text("/sonar " + sub.getInfo().name(), NamedTextColor.GREEN),
Component.text(" - ", NamedTextColor.GRAY),
Component.text(sub.getInfo().description(), NamedTextColor.WHITE)
);
final String subcommandFormat = Sonar.get().getConfig().getCommands().getHelpSubcommands();
Sonar.get().getSubcommandRegistry().getSubcommands().forEach(subcommand -> {
final Component deserialized = MiniMessage.miniMessage().deserialize(subcommandFormat
.replace("%subcommand%", subcommand.getInfo().name())
.replace("%description%", subcommand.getInfo().description())
.replace("%only_players%", subcommand.getInfo().onlyPlayers() ? "<green>✔</green>" : "<red>✗</red>")
.replace("%require_console%", subcommand.getInfo().onlyConsole() ? "<green>✔</green>" : "<red>✗</red>")
.replace("%permission%", subcommand.getPermission())
.replace("%aliases%", subcommand.getAliases()));
CACHED_HELP_MESSAGE.add(deserialized);
});

Component hoverComponent = Component.textOfChildren(
Component.text("Only players: ", NamedTextColor.GRAY),
Component.text(sub.getInfo().onlyPlayers() ? "✔" : "✗",
sub.getInfo().onlyPlayers() ? NamedTextColor.GREEN : NamedTextColor.RED),
Component.newline(),
Component.text("Require console: ", NamedTextColor.GRAY),
Component.text(sub.getInfo().onlyConsole() ? "✔" : "✗",
sub.getInfo().onlyConsole() ? NamedTextColor.GREEN : NamedTextColor.RED),
Component.newline(),
Component.text("Permission: ", NamedTextColor.GRAY),
Component.text(sub.getPermission(), NamedTextColor.WHITE)
);
if (sub.getInfo().aliases().length > 0) {
hoverComponent = hoverComponent
.append(Component.newline())
.append(Component.text("Aliases: ", NamedTextColor.GRAY))
.append(Component.text(sub.getAliases(), NamedTextColor.WHITE));
// Don't re-cache tab suggestions
if (!TAB_SUGGESTIONS.isEmpty()) return;
// Cache tab suggestions
for (final Subcommand subcommand : Sonar.get().getSubcommandRegistry().getSubcommands()) {
TAB_SUGGESTIONS.add(subcommand.getInfo().name());
if (subcommand.getInfo().aliases().length > 0) {
TAB_SUGGESTIONS.addAll(Arrays.asList(subcommand.getInfo().aliases()));
}
component = component
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND,
"/sonar " + sub.getInfo().name() + " "))
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponent));
CACHED_HELP_MESSAGE.add(component);
});
final List<String> parsedArguments = Arrays.stream(subcommand.getInfo().arguments())
.map(Argument::value)
.collect(Collectors.toList());
ARG_TAB_SUGGESTIONS.put(subcommand.getInfo().name(), parsedArguments);
for (final String alias : subcommand.getInfo().aliases()) {
ARG_TAB_SUGGESTIONS.put(alias, parsedArguments);
}
}
}

default List<String> getCachedTabSuggestions(final String @NotNull [] arguments) {
if (arguments.length <= 1) {
return TAB_SUGGESTIONS;
} else if (arguments.length == 2) {
final String subCommandName = arguments[0].toLowerCase();
return ARG_TAB_SUGGESTIONS.getOrDefault(subCommandName, emptyList());
}
return emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,31 @@ protected final void incorrectUsage(final @NotNull InvocationSource sender) {
.replace("%usage%", info.name() + " (" + arguments + ")"));
}

public abstract void execute(final @NotNull CommandInvocation invocation);
public final void invoke(final @NotNull InvocationSource invocationSource, final String @NotNull [] arguments) {
// Check if the subcommand can only be executed by players
if (getInfo().onlyPlayers() && !invocationSource.isPlayer()) {
invocationSource.sendMessage(Sonar.get().getConfig().getCommands().getPlayersOnly());
return;
}

// Check if the subcommand can only be executed though console
if (getInfo().onlyConsole() && invocationSource.isPlayer()) {
invocationSource.sendMessage(Sonar.get().getConfig().getCommands().getConsoleOnly());
return;
}

final CommandInvocation commandInvocation = new CommandInvocation(invocationSource, this, arguments);

// The subcommands has arguments which are not present in the executed command
if (getInfo().argumentsRequired() && getInfo().arguments().length > 0 && arguments.length <= 1) {
invocationSource.sendMessage(Sonar.get().getConfig().getCommands().getIncorrectCommandUsage()
.replace("%usage%", getInfo().name() + " (" + getArguments() + ")"));
return;
}

// Execute the sub command
execute(commandInvocation);
}

protected abstract void execute(final @NotNull CommandInvocation invocation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package xyz.jonesdev.sonar.api.config;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.simpleyaml.configuration.comments.format.YamlCommentFormat;
import org.simpleyaml.configuration.file.YamlFile;
import xyz.jonesdev.sonar.api.Sonar;
Expand All @@ -36,8 +37,8 @@ public final class SimpleYamlConfig {

private static final List<String> HEADER = Arrays.asList(
"",
"Running Sonar version " + Sonar.get().getVersion()
+ " on " + Sonar.get().getServer().getPlatform().getDisplayName(),
String.format("Running Sonar version %s on %s",
Sonar.get().getVersion(), Sonar.get().getPlatform().getDisplayName()),
"Need help or have questions? https://jonesdev.xyz/discord",
"https://github.com/jonesdevelopment/sonar",
""
Expand All @@ -47,7 +48,7 @@ public SimpleYamlConfig(final File dataFolder, final String fileName) {
this(new File(dataFolder, fileName + ".yml"), dataFolder);
}

private SimpleYamlConfig(final File file, final File folder) {
private SimpleYamlConfig(final File file, final @NotNull File folder) {
if (!folder.exists() && !folder.mkdir()) {
throw new IllegalStateException("Could not create folder?!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.command.SonarCommand;
import xyz.jonesdev.sonar.api.dependencies.Dependency;

import java.io.File;
Expand Down Expand Up @@ -157,10 +158,11 @@ public static final class Commands {
private String networkStatistics;
private String cpuStatistics;

private List<String> helpHeader;
private String helpSubcommands;

private String verboseSubscribed;
private String verboseUnsubscribed;
private String verboseSubscribedOther;
private String verboseUnsubscribedOther;

private String reloading;
private String reloaded;
Expand Down Expand Up @@ -507,6 +509,33 @@ public void load() {
"%footer%"
))));

messagesConfig.getYaml().setComment("commands.main",
"Translations for '/sonar'");
messagesConfig.getYaml().setComment("commands.main.header",
"Informational message that is shown above everything when running the main command");
commands.helpHeader = messagesConfig.getStringList("commands.main.header",
Arrays.asList(
"<yellow>Running Sonar %version% on %platform%.",
"<yellow>(C) %copyright_year% Jones Development and Sonar Contributors",
"<green><click:open_url:'https://github.com/jonesdevelopment/sonar'>https://github.com/jonesdevelopment/sonar",
"",
"<yellow>Need help or have any questions?",
"<yellow><click:open_url:'https://jonesdev.xyz/discord/'><hover:show_text:'(Click to open Discord)'>Open a " +
"ticket on the Discord </hover></click></yellow><yellow><click:open_url:'https://github" +
".com/jonesdevelopment/sonar/issues'><hover:show_text:'(Click to open GitHub)'>or open a new issue on " +
"GitHub.",
""
));
messagesConfig.getYaml().setComment("commands.main.subcommands",
"Formatting of the list of subcommands shown when running the main command");
commands.helpSubcommands = formatString(messagesConfig.getString("commands.main.subcommands",
"<click:suggest_command:'/sonar %subcommand% '><hover:show_text:'<gray>Only players: " +
"</gray>%only_players%<br><gray>Require console: </gray>%require_console%<br><gray>Permission: " +
"</gray><white>%permission%<br><gray>Aliases: </gray>%aliases%'><gray> ▪ </gray><green>/sonar " +
"%subcommand%</green><gray> - </gray><white>%description%"));

SonarCommand.prepareCachedMessages();

messagesConfig.getYaml().setComment("commands.reload",
"Translations for '/sonar reload'");
messagesConfig.getYaml().setComment("commands.reload.start",
Expand Down Expand Up @@ -543,16 +572,6 @@ public void load() {
commands.verboseUnsubscribed = formatString(messagesConfig.getString("commands.verbose.unsubscribed",
"%prefix%You are no longer viewing Sonar verbose."));

messagesConfig.getYaml().setComment("commands.verbose.subscribed-other",
"Message that is shown when a player makes another player subscribe to Sonar verbose");
commands.verboseSubscribedOther = formatString(messagesConfig.getString("commands.verbose.subscribed-other",
"%prefix%%player% is now viewing Sonar verbose."));

messagesConfig.getYaml().setComment("commands.verbose.unsubscribed-other",
"Message that is shown when a player makes another player unsubscribe from Sonar verbose");
commands.verboseUnsubscribedOther = formatString(messagesConfig.getString("commands.verbose.unsubscribed-other",
"%prefix%%player% is no longer viewing Sonar verbose."));

messagesConfig.getYaml().setComment("commands.blacklist",
"Translations for '/sonar blacklist'");
messagesConfig.getYaml().setComment("commands.blacklist.empty",
Expand Down

This file was deleted.

Loading