Compare commits

...

2 Commits

12 changed files with 253 additions and 325 deletions

View File

@ -1,36 +1,24 @@
For those who are wanting to contribute, we fully encourage doing so. There are a few rules we require following when
contributing however.
For those who are wanting to contribute, we fully encourage doing so. There are a few rules we require following when contributing however.
## Steps
1. Make an issue and get feedback. It's important to know if your idea will be accepted before writing any code.
- If it is a feature request, describe the feature and be extremely specific.
- If it is a bug report, ensure you include how to reproduce the bug and the expected outcome
- If it is an enhancement, describe your proposed changes. Ensure you are extremely specific.
2. Fork this project
3. Create a new branch that describes the new feature, enhancement, or bug fix. For example, this is
good: `feature/add-xyz`. This is bad: `fix-this-lol`.
3. Create a new branch that describes the new feature, enhancement, or bug fix. For example, this is good: `feature/add-xyz`. This is bad: `fix-this-lol`.
4. Write the code that addresses your change.
- Keep in mind that it **must** be formatted correctly. If you are using IntelliJ, there is a `codeStyle.xml` file that
tells IntelliJ how to format your code. Check this link for information on how to use the
file: https://www.jetbrains.com/help/idea/configuring-code-style.html#import-export-schemes
- If you are not using IntelliJ, that is fine. We use Allman style so please format your code accordingly.
- Keep in mind that it **must** be formatted correctly. If you are using IntelliJ, there is a `codeStyle.xml` file that tells IntelliJ how to format your code. Check this link for information on how to use the file: https://www.jetbrains.com/help/idea/configuring-code-style.html#import-export-schemes
- If you are not using IntelliJ, that is fine. We use Google Java Code Style in this particular Module so please format your code accordingly.
6. Push your changes to your new branch and make a PR based off of that branch.
## Requirements for a PR
- The issue must be marked as approved
- It must only address each specific issue. Don't make one PR for multiple issues.
- Your PR must compile and work. If it does not compile or work, your PR will most likely be rejected.
## Code requirements
- Most importantly, your code must be efficient. Your pull request may be rejected if your code is deemed inefficient or
sloppy.
- Most importantly, your code must be efficient. Your pull request may be rejected if your code is deemed inefficient or sloppy.
- Do not repeat yourself. Create functions as needed if you're using large blocks of code over and over again.
- Do not use an excessive amount of commits when making your PR. It makes the master branch look messy.
- Your code must be consistent with Plex's codebase. If a function already exists, use it.
- Your code must be consistent with Plex's codebase. If a function already exists, use it.

View File

@ -7,9 +7,8 @@ import net.kyori.adventure.text.Component;
@Data
@AllArgsConstructor
public class Message
{
public class Message {
UUID sender;
Component message;
UUID sender;
Component message;
}

View File

@ -2,34 +2,29 @@ package dev.plex.nush;
import javax.annotation.Nullable;
public enum NushAction
{
MUTE("Mute Player", 0),
CANCEL("Cancel", 1),
SMITE("Smite", 2),
BAN("Ban Player", 3),
ACCEPT("Accept", 4);
public enum NushAction {
MUTE("Mute Player", 0),
CANCEL("Cancel", 1),
SMITE("Smite", 2),
BAN("Ban Player", 3),
ACCEPT("Accept", 4);
public final String humanReadable;
public final int ordinal;
public final String humanReadable;
public final int ordinal;
NushAction(String humanReadable, int ordinal)
{
this.humanReadable = humanReadable;
this.ordinal = ordinal;
}
NushAction(String humanReadable, int ordinal) {
this.humanReadable = humanReadable;
this.ordinal = ordinal;
}
@Nullable
public static NushAction fromOrdinal(int ordinal)
{
for (NushAction value : NushAction.values())
{
if (value.ordinal == ordinal)
{
return value;
}
}
@Nullable
public static NushAction fromOrdinal(int ordinal) {
for (NushAction value : NushAction.values()) {
if (value.ordinal == ordinal) {
return value;
}
}
return null;
}
return null;
}
}

View File

@ -8,38 +8,33 @@ import dev.plex.nush.handler.impl.ListenerHandler;
import java.util.Map;
import java.util.Map.Entry;
public class NushModule extends PlexModule
{
public class NushModule extends PlexModule {
public static final Map<String, String> messages = Map.ofEntries(
Map.entry("nushToggled", "<aqua>{0} - {1} NUSH."),
Map.entry("nushApply", "<yellow>Applying {0} to {1}!"));
public static boolean enabled = false;
private static NushModule INSTANCE;
public static final Map<String, String> messages = Map.ofEntries(
Map.entry("nushToggled", "<aqua>{0} - {1} NUSH."),
Map.entry("nushApply", "<yellow>Applying {0} to {1}!"));
public static boolean enabled = false;
private static NushModule INSTANCE;
public static NushModule getInstance()
{
return INSTANCE;
}
public static NushModule getInstance() {
return INSTANCE;
}
@Override
public void enable()
{
INSTANCE = this;
Plex plex = getPlex();
for (Entry<String, String> entry : messages.entrySet())
{
plex.messages.addDefault(entry.getKey(), entry.getValue());
}
@Override
public void enable() {
INSTANCE = this;
Plex plex = getPlex();
for (Entry<String, String> entry : messages.entrySet()) {
plex.messages.addDefault(entry.getKey(), entry.getValue());
}
new ActionHandler().init(this);
new CommandHandler().init(this);
new ListenerHandler().init(this);
}
new ActionHandler().init(this);
new CommandHandler().init(this);
new ListenerHandler().init(this);
}
@Override
public void disable()
{
// Unregistering listeners / commands is handled by Plex
}
@Override
public void disable() {
// Unregistering listeners / commands is handled by Plex
}
}

View File

@ -18,83 +18,68 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static dev.plex.nush.NushAction.ACCEPT;
import static dev.plex.nush.NushAction.CANCEL;
@CommandParameters(name = "nush", aliases = "raidmode", description = "Toggle NUSH on or off.", usage = "/<command> [on | enable | off | disable | toggle]")
@CommandPermissions(level = Rank.ADMIN, permission = "plex.nush.command")
public class NUSHCommand extends PlexCommand
{
public class NUSHCommand extends PlexCommand {
@Override
protected Component execute(@NotNull CommandSender commandSender, @Nullable Player player,
@NotNull String[] args)
{
if (args.length == 0)
{
NushModule.enabled = !NushModule.enabled;
}
else if (args.length == 1)
{
switch (args[0].toLowerCase())
{
case "on", "enable" -> NushModule.enabled = true;
case "off", "disable" -> NushModule.enabled = false;
case "toggle" -> NushModule.enabled = !NushModule.enabled;
}
}
else
{
if (args[0].equalsIgnoreCase("work"))
{
try
{
UUID nushIdentifier = UUID.fromString(args[1]);
Message nushMessage = ActionHandler.MAP.get(nushIdentifier);
@Override
protected Component execute(@NotNull CommandSender commandSender, @Nullable Player player,
@NotNull String[] args) {
if (args.length == 0) {
NushModule.enabled = !NushModule.enabled;
} else if (args.length == 1) {
switch (args[0].toLowerCase()) {
case "on", "enable" -> NushModule.enabled = true;
case "off", "disable" -> NushModule.enabled = false;
case "toggle" -> NushModule.enabled = !NushModule.enabled;
}
} else {
if (args[0].equalsIgnoreCase("work")) {
try {
UUID nushIdentifier = UUID.fromString(args[1]);
Message nushMessage = ActionHandler.MAP.get(nushIdentifier);
if (nushMessage == null)
{
return null;
}
if (nushMessage == null) {
return null;
}
NushAction action = NushAction.fromOrdinal(Integer.parseInt(args[2]));
if (action == null)
{
return null;
}
NushAction action = NushAction.fromOrdinal(Integer.parseInt(args[2]));
if (action == null) {
return null;
}
if (action == ACCEPT || action == CANCEL)
{
ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW);
}
if (action == ACCEPT || action == CANCEL) {
ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW);
}
StringBuilder command = new StringBuilder();
StringBuilder command = new StringBuilder();
command.append(action.name().toLowerCase());
command.append(" ");
command.append(nushMessage.getSender());
command.append(action.name().toLowerCase());
command.append(" ");
command.append(nushMessage.getSender());
if (!command.toString().trim().isEmpty())
{
PlexLog.debug("Dispatching command: {0}", command.toString());
Bukkit.dispatchCommand(commandSender, command.toString());
}
if (!command.toString().trim().isEmpty()) {
PlexLog.debug("Dispatching command: {0}", command.toString());
Bukkit.dispatchCommand(commandSender, command.toString());
}
ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW);
}
catch (Exception ignored)
{
return null;
}
}
ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW);
} catch (Exception ignored) {
return null;
}
}
return null;
}
return null;
}
PlexUtils.broadcastToAdmins(messageComponent("nushToggled", commandSender.getName(),
NushModule.enabled ? "Enabling" : "Disabling"));
return null;
}
PlexUtils.broadcastToAdmins(messageComponent("nushToggled", commandSender.getName(),
NushModule.enabled ? "Enabling" : "Disabling"));
return null;
}
}

View File

@ -2,8 +2,7 @@ package dev.plex.nush.handler;
import dev.plex.nush.NushModule;
public interface Handler
{
public interface Handler {
void init(NushModule module);
void init(NushModule module);
}

View File

@ -12,6 +12,7 @@ import dev.plex.util.minimessage.SafeMiniMessage;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
@ -23,67 +24,58 @@ import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class ActionHandler implements Handler
{
public class ActionHandler implements Handler {
public static final Map<UUID, Message> MAP = new HashMap<>();
private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig.builder()
.match("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]")
.replacement(
(matchResult, builder) -> Component.empty().content(matchResult.group()).clickEvent(
ClickEvent.openUrl(matchResult.group()))).build();
private static NushModule MODULE;
public static final Map<UUID, Message> MAP = new HashMap<>();
private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig.builder()
.match("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]")
.replacement(
(matchResult, builder) -> Component.empty().content(matchResult.group()).clickEvent(
ClickEvent.openUrl(matchResult.group()))).build();
private static NushModule MODULE;
public static void resolve(UUID uuid, NushAction action)
{
Message message = MAP.get(uuid);
if (message == null)
{
return;
}
if (action == NushAction.ACCEPT)
{
for (Player player : Bukkit.getOnlinePlayers())
{
if (player.getUniqueId() != message.getSender())
{
player.sendMessage(Identity.identity(message.getSender()), getMessage(message));
}
}
}
MAP.remove(uuid);
}
public static void resolve(UUID uuid, NushAction action) {
Message message = MAP.get(uuid);
if (message == null) {
return;
}
if (action == NushAction.ACCEPT) {
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getUniqueId() != message.getSender()) {
player.sendMessage(Identity.identity(message.getSender()), getMessage(message));
}
}
}
MAP.remove(uuid);
}
public static Component getMessage(Message message)
{
String text = PlexUtils.getTextFromComponent(message.getMessage());
Plex plex = MODULE.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(message.getSender());
Component prefix = plex.getRankManager().getPrefix(plexPlayer);
Component component = Component.empty();
public static Component getMessage(Message message) {
String text = PlexUtils.getTextFromComponent(message.getMessage());
Plex plex = MODULE.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(message.getSender());
Component prefix = plex.getRankManager().getPrefix(plexPlayer);
Component component = Component.empty();
if (prefix != null)
{
component = component.append(prefix);
}
if (prefix != null) {
component = component.append(prefix);
}
return component.append(Component.space()).append(
PlexUtils.mmDeserialize(plex.config.getString("chat.name-color", "<white>") +
MiniMessage.builder().tags(
TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(),
StandardTags.decorations(), StandardTags.gradient(),
StandardTags.transition()
)).build().serialize(plexPlayer.getPlayer().displayName())))
.append(Component.space())
.append(Component.text("»").color(NamedTextColor.GRAY)).append(Component.space())
.append(
SafeMiniMessage.mmDeserializeWithoutEvents(text))
.replaceText(URL_REPLACEMENT_CONFIG);
}
return component.append(Component.space()).append(
PlexUtils.mmDeserialize(plex.config.getString("chat.name-color", "<white>") +
MiniMessage.builder().tags(
TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(),
StandardTags.decorations(), StandardTags.gradient(),
StandardTags.transition()
)).build().serialize(plexPlayer.getPlayer().displayName())))
.append(Component.space())
.append(Component.text("»").color(NamedTextColor.GRAY)).append(Component.space())
.append(
SafeMiniMessage.mmDeserializeWithoutEvents(text))
.replaceText(URL_REPLACEMENT_CONFIG);
}
@Override
public void init(NushModule module)
{
MODULE = NushModule.getInstance();
}
@Override
public void init(NushModule module) {
MODULE = NushModule.getInstance();
}
}

View File

@ -4,12 +4,10 @@ import dev.plex.nush.NushModule;
import dev.plex.nush.command.impl.NUSHCommand;
import dev.plex.nush.handler.Handler;
public class CommandHandler implements Handler
{
public class CommandHandler implements Handler {
@Override
public void init(NushModule module)
{
module.registerCommand(new NUSHCommand());
}
@Override
public void init(NushModule module) {
module.registerCommand(new NUSHCommand());
}
}

View File

@ -5,13 +5,11 @@ import dev.plex.nush.handler.Handler;
import dev.plex.nush.listener.impl.ChatListener;
import dev.plex.nush.listener.impl.JoinListener;
public class ListenerHandler implements Handler
{
public class ListenerHandler implements Handler {
@Override
public void init(NushModule module)
{
module.registerListener(new ChatListener());
module.registerListener(new JoinListener());
}
@Override
public void init(NushModule module) {
module.registerListener(new ChatListener());
module.registerListener(new JoinListener());
}
}

View File

@ -22,60 +22,52 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
public class ChatListener extends PlexListener
{
public class ChatListener extends PlexListener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onChat(AsyncChatEvent event)
{
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
Instant firstJoined = Instant.ofEpochMilli(player.getFirstPlayed());
Instant rightNow = Instant.now();
long difference = (Duration.between(firstJoined, rightNow).getSeconds() / 60);
if (difference >= 15)
{
PlexLog.debug("{0} has been on the server for {1} minutes, so Nush will skip them.", player.getName(), difference);
return;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChat(AsyncChatEvent event) {
if(event.isCancelled()) return;
Player player = event.getPlayer();
Instant firstJoined = Instant.ofEpochMilli(player.getFirstPlayed());
Instant rightNow = Instant.now();
long difference = (Duration.between(firstJoined, rightNow).getSeconds() / 60);
if (difference >= 15) {
PlexLog.debug("{0} has been on the server for {1} minutes, so Nush will skip them.", player.getName(), difference);
return;
}
NushModule module = NushModule.getInstance();
Plex plex = module.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId());
RankManager rankManager = plex.getRankManager();
NushModule module = NushModule.getInstance();
Plex plex = module.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId());
RankManager rankManager = plex.getRankManager();
if (rankManager.isAdmin(plexPlayer))
{
PlexLog.debug("{0} is an admin so Nush will skip them.", player.getName());
return; // we needn't process the chat message if they're an admin
}
if (rankManager.isAdmin(plexPlayer)) {
PlexLog.debug("{0} is an admin so Nush will skip them.", player.getName());
return; // we needn't process the chat message if they're an admin
}
event.setCancelled(true);
UUID key = UUID.randomUUID();
Message message = new Message(event.getPlayer().getUniqueId(), event.originalMessage());
ActionHandler.MAP.put(key, message);
Component component = ActionHandler.getMessage(message);
event.setCancelled(true);
UUID key = UUID.randomUUID();
Message message = new Message(event.getPlayer().getUniqueId(), event.originalMessage());
ActionHandler.MAP.put(key, message);
Component component = ActionHandler.getMessage(message);
// Send the user the message so they think it got sent
player.sendMessage(component);
// Send the user the message so they think it got sent
player.sendMessage(component);
component = component.append(Component.text("\n"));
component = component.append(Component.text("\n"));
for (NushAction value : NushAction.values())
{
String command = String.format("/nush work %s %d", key, value.ordinal);
component = component.append(
Component.text(String.format("[%s] ", value.humanReadable))
.clickEvent(ClickEvent.runCommand(command))
.hoverEvent(
Component.text(command, NamedTextColor.YELLOW)
)
);
}
for (NushAction value : NushAction.values()) {
String command = String.format("/nush work %s %d", key, value.ordinal);
component = component.append(
Component.text(String.format("[%s] ", value.humanReadable))
.clickEvent(ClickEvent.runCommand(command))
.hoverEvent(
Component.text(command, NamedTextColor.YELLOW)
)
);
}
PlexUtils.broadcastToAdmins(component);
}
PlexUtils.broadcastToAdmins(component);
}
}

View File

@ -10,25 +10,22 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class JoinListener extends PlexListener
{
public class JoinListener extends PlexListener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
NushModule module = NushModule.getInstance();
Plex plex = module.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId());
RankManager rankManager = plex.getRankManager();
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
NushModule module = NushModule.getInstance();
Plex plex = module.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId());
RankManager rankManager = plex.getRankManager();
if (!rankManager.isAdmin(plexPlayer))
{
return; // we only want to add admins
}
if (!rankManager.isAdmin(plexPlayer)) {
return; // we only want to add admins
}
/*if (ChatListener.work.containsKey())
{
}*/
}
}
}

View File

@ -10,52 +10,42 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ReflectionsUtil
{
public class ReflectionsUtil {
@SuppressWarnings("UnstableApiUsage")
public static Set<Class<?>> getClassesFrom(String packageName)
{
Set<Class<?>> classes = new HashSet<>();
try
{
ClassPath path = ClassPath.from(Plex.class.getClassLoader());
ImmutableSet<ClassPath.ClassInfo> infoSet = path.getTopLevelClasses(packageName);
infoSet.forEach(info ->
{
try
{
Class<?> clazz = Class.forName(info.getName());
classes.add(clazz);
}
catch (ClassNotFoundException ex)
{
PlexLog.error("Unable to find class " + info.getName() + " in " + packageName);
}
});
}
catch (IOException ex)
{
PlexLog.error("Something went wrong while fetching classes from " + packageName);
throw new RuntimeException(ex);
}
return Collections.unmodifiableSet(classes);
}
@SuppressWarnings("UnstableApiUsage")
public static Set<Class<?>> getClassesFrom(String packageName) {
Set<Class<?>> classes = new HashSet<>();
try {
ClassPath path = ClassPath.from(Plex.class.getClassLoader());
ImmutableSet<ClassPath.ClassInfo> infoSet = path.getTopLevelClasses(packageName);
infoSet.forEach(info ->
{
try {
Class<?> clazz = Class.forName(info.getName());
classes.add(clazz);
} catch (ClassNotFoundException ex) {
PlexLog.error("Unable to find class " + info.getName() + " in " + packageName);
}
});
} catch (IOException ex) {
PlexLog.error("Something went wrong while fetching classes from " + packageName);
throw new RuntimeException(ex);
}
return Collections.unmodifiableSet(classes);
}
@SuppressWarnings("unchecked")
public static <T> Set<Class<? extends T>> getClassesBySubType(String packageName,
Class<T> subType)
{
Set<Class<?>> loadedClasses = getClassesFrom(packageName);
Set<Class<? extends T>> classes = new HashSet<>();
loadedClasses.forEach(clazz ->
{
if (clazz.getSuperclass() == subType || Arrays.asList(clazz.getInterfaces())
.contains(subType))
{
classes.add((Class<? extends T>)clazz);
}
});
return Collections.unmodifiableSet(classes);
}
@SuppressWarnings("unchecked")
public static <T> Set<Class<? extends T>> getClassesBySubType(String packageName,
Class<T> subType) {
Set<Class<?>> loadedClasses = getClassesFrom(packageName);
Set<Class<? extends T>> classes = new HashSet<>();
loadedClasses.forEach(clazz ->
{
if (clazz.getSuperclass() == subType || Arrays.asList(clazz.getInterfaces())
.contains(subType)) {
classes.add((Class<? extends T>) clazz);
}
});
return Collections.unmodifiableSet(classes);
}
}