Compare commits

...

3 commits

13 changed files with 326 additions and 254 deletions

View file

@ -1,24 +1,36 @@
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 ## Steps
1. Make an issue and get feedback. It's important to know if your idea will be accepted before writing any code. 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 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 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. - If it is an enhancement, describe your proposed changes. Ensure you are extremely specific.
2. Fork this project 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. 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 Google Java Code Style in this particular Module 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 Allman style so please format your code accordingly.
6. Push your changes to your new branch and make a PR based off of that branch. 6. Push your changes to your new branch and make a PR based off of that branch.
## Requirements for a PR ## Requirements for a PR
- The issue must be marked as approved - The issue must be marked as approved
- It must only address each specific issue. Don't make one PR for multiple issues. - 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. - Your PR must compile and work. If it does not compile or work, your PR will most likely be rejected.
## Code requirements ## 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 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. - 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

@ -5,7 +5,7 @@ plugins {
repositories { repositories {
maven { maven {
url = uri("https://papermc.io/repo/repository/maven-public/") url = uri("https://repo.papermc.io/repository/maven-public/")
} }
maven { maven {

View file

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

View file

@ -2,7 +2,8 @@ package dev.plex.nush;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public enum NushAction { public enum NushAction
{
MUTE("Mute Player", 0), MUTE("Mute Player", 0),
CANCEL("Cancel", 1), CANCEL("Cancel", 1),
SMITE("Smite", 2), SMITE("Smite", 2),
@ -12,15 +13,19 @@ public enum NushAction {
public final String humanReadable; public final String humanReadable;
public final int ordinal; public final int ordinal;
NushAction(String humanReadable, int ordinal) { NushAction(String humanReadable, int ordinal)
{
this.humanReadable = humanReadable; this.humanReadable = humanReadable;
this.ordinal = ordinal; this.ordinal = ordinal;
} }
@Nullable @Nullable
public static NushAction fromOrdinal(int ordinal) { public static NushAction fromOrdinal(int ordinal)
for (NushAction value : NushAction.values()) { {
if (value.ordinal == ordinal) { for (NushAction value : NushAction.values())
{
if (value.ordinal == ordinal)
{
return value; return value;
} }
} }

View file

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

View file

@ -18,41 +18,53 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import static dev.plex.nush.NushAction.ACCEPT; import static dev.plex.nush.NushAction.ACCEPT;
import static dev.plex.nush.NushAction.CANCEL; 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]") @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") @CommandPermissions(level = Rank.ADMIN, permission = "plex.nush.command")
public class NUSHCommand extends PlexCommand { public class NUSHCommand extends PlexCommand
{
@Override @Override
protected Component execute(@NotNull CommandSender commandSender, @Nullable Player player, protected Component execute(@NotNull CommandSender commandSender, @Nullable Player player,
@NotNull String[] args) { @NotNull String[] args)
if (args.length == 0) { {
if (args.length == 0)
{
NushModule.enabled = !NushModule.enabled; NushModule.enabled = !NushModule.enabled;
} else if (args.length == 1) { }
switch (args[0].toLowerCase()) { else if (args.length == 1)
{
switch (args[0].toLowerCase())
{
case "on", "enable" -> NushModule.enabled = true; case "on", "enable" -> NushModule.enabled = true;
case "off", "disable" -> NushModule.enabled = false; case "off", "disable" -> NushModule.enabled = false;
case "toggle" -> NushModule.enabled = !NushModule.enabled; case "toggle" -> NushModule.enabled = !NushModule.enabled;
} }
} else { }
if (args[0].equalsIgnoreCase("work")) { else
try { {
if (args[0].equalsIgnoreCase("work"))
{
try
{
UUID nushIdentifier = UUID.fromString(args[1]); UUID nushIdentifier = UUID.fromString(args[1]);
Message nushMessage = ActionHandler.MAP.get(nushIdentifier); Message nushMessage = ActionHandler.MAP.get(nushIdentifier);
if (nushMessage == null) { if (nushMessage == null)
{
return null; return null;
} }
NushAction action = NushAction.fromOrdinal(Integer.parseInt(args[2])); NushAction action = NushAction.fromOrdinal(Integer.parseInt(args[2]));
if (action == null) { if (action == null)
{
return null; return null;
} }
if (action == ACCEPT || action == CANCEL) { if (action == ACCEPT || action == CANCEL)
{
ActionHandler.resolve(nushIdentifier, action); ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW); return Component.text(action.humanReadable, NamedTextColor.YELLOW);
} }
@ -63,14 +75,17 @@ public class NUSHCommand extends PlexCommand {
command.append(" "); command.append(" ");
command.append(nushMessage.getSender()); command.append(nushMessage.getSender());
if (!command.toString().trim().isEmpty()) { if (!command.toString().trim().isEmpty())
{
PlexLog.debug("Dispatching command: {0}", command.toString()); PlexLog.debug("Dispatching command: {0}", command.toString());
Bukkit.dispatchCommand(commandSender, command.toString()); Bukkit.dispatchCommand(commandSender, command.toString());
} }
ActionHandler.resolve(nushIdentifier, action); ActionHandler.resolve(nushIdentifier, action);
return Component.text(action.humanReadable, NamedTextColor.YELLOW); return Component.text(action.humanReadable, NamedTextColor.YELLOW);
} catch (Exception ignored) { }
catch (Exception ignored)
{
return null; return null;
} }
} }

View file

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

View file

@ -12,7 +12,6 @@ import dev.plex.util.minimessage.SafeMiniMessage;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.identity.Identity; import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
@ -24,7 +23,8 @@ import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class ActionHandler implements Handler { public class ActionHandler implements Handler
{
public static final Map<UUID, Message> MAP = new HashMap<>(); public static final Map<UUID, Message> MAP = new HashMap<>();
private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig.builder() private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig.builder()
@ -34,14 +34,19 @@ public class ActionHandler implements Handler {
ClickEvent.openUrl(matchResult.group()))).build(); ClickEvent.openUrl(matchResult.group()))).build();
private static NushModule MODULE; private static NushModule MODULE;
public static void resolve(UUID uuid, NushAction action) { public static void resolve(UUID uuid, NushAction action)
{
Message message = MAP.get(uuid); Message message = MAP.get(uuid);
if (message == null) { if (message == null)
{
return; return;
} }
if (action == NushAction.ACCEPT) { if (action == NushAction.ACCEPT)
for (Player player : Bukkit.getOnlinePlayers()) { {
if (player.getUniqueId() != message.getSender()) { for (Player player : Bukkit.getOnlinePlayers())
{
if (player.getUniqueId() != message.getSender())
{
player.sendMessage(Identity.identity(message.getSender()), getMessage(message)); player.sendMessage(Identity.identity(message.getSender()), getMessage(message));
} }
} }
@ -49,14 +54,16 @@ public class ActionHandler implements Handler {
MAP.remove(uuid); MAP.remove(uuid);
} }
public static Component getMessage(Message message) { public static Component getMessage(Message message)
{
String text = PlexUtils.getTextFromComponent(message.getMessage()); String text = PlexUtils.getTextFromComponent(message.getMessage());
Plex plex = MODULE.getPlex(); Plex plex = MODULE.getPlex();
PlexPlayer plexPlayer = DataUtils.getPlayer(message.getSender()); PlexPlayer plexPlayer = DataUtils.getPlayer(message.getSender());
Component prefix = plex.getRankManager().getPrefix(plexPlayer); Component prefix = plex.getRankManager().getPrefix(plexPlayer);
Component component = Component.empty(); Component component = Component.empty();
if (prefix != null) { if (prefix != null)
{
component = component.append(prefix); component = component.append(prefix);
} }
@ -75,7 +82,8 @@ public class ActionHandler implements Handler {
} }
@Override @Override
public void init(NushModule module) { public void init(NushModule module)
{
MODULE = NushModule.getInstance(); MODULE = NushModule.getInstance();
} }
} }

View file

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

View file

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

View file

@ -22,16 +22,22 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
public class ChatListener extends PlexListener { public class ChatListener extends PlexListener
{
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onChat(AsyncChatEvent event) { public void onChat(AsyncChatEvent event)
if(event.isCancelled()) return; {
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer(); Player player = event.getPlayer();
Instant firstJoined = Instant.ofEpochMilli(player.getFirstPlayed()); Instant firstJoined = Instant.ofEpochMilli(player.getFirstPlayed());
Instant rightNow = Instant.now(); Instant rightNow = Instant.now();
long difference = (Duration.between(firstJoined, rightNow).getSeconds() / 60); long difference = (Duration.between(firstJoined, rightNow).getSeconds() / 60);
if (difference >= 15) { if (difference >= 15)
{
PlexLog.debug("{0} has been on the server for {1} minutes, so Nush will skip them.", player.getName(), difference); PlexLog.debug("{0} has been on the server for {1} minutes, so Nush will skip them.", player.getName(), difference);
return; return;
} }
@ -41,7 +47,8 @@ public class ChatListener extends PlexListener {
PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId()); PlexPlayer plexPlayer = DataUtils.getPlayer(player.getUniqueId());
RankManager rankManager = plex.getRankManager(); RankManager rankManager = plex.getRankManager();
if (rankManager.isAdmin(plexPlayer)) { if (rankManager.isAdmin(plexPlayer))
{
PlexLog.debug("{0} is an admin so Nush will skip them.", player.getName()); 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 return; // we needn't process the chat message if they're an admin
} }
@ -57,7 +64,8 @@ public class ChatListener extends PlexListener {
component = component.append(Component.text("\n")); component = component.append(Component.text("\n"));
for (NushAction value : NushAction.values()) { for (NushAction value : NushAction.values())
{
String command = String.format("/nush work %s %d", key, value.ordinal); String command = String.format("/nush work %s %d", key, value.ordinal);
component = component.append( component = component.append(
Component.text(String.format("[%s] ", value.humanReadable)) Component.text(String.format("[%s] ", value.humanReadable))

View file

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

View file

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