Add support for tracks

This commit is contained in:
Luck 2016-07-15 22:44:25 +01:00
parent 90b6f41f13
commit 874a90253b
44 changed files with 1585 additions and 59 deletions

View File

@ -6,6 +6,7 @@ A (fairly bad) permissions implementation for Bukkit/BungeeCord.
* **Multi-server support** - data is synced across all servers/platforms
* **Per-server permissions/groups** - define user/group permissions that only apply on certain servers
* **Server-specific groups** - define groups that only apply on certain servers
* **Tracks / paths** - users can be promoted/demoted along multiple group tracks
* **Vault Support** - hooks into Vault to integrate with other plugins
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
* **Efficient/lightweight** - maybe? Who knows, it might be.
@ -41,6 +42,13 @@ Arguments: <required> [optional]
Users with OP have access to all commands.
Additionally, you can use wildcards to grant users access to a selection of commands.
* **All commands** - luckperms.*
* **All user commands** - luckperms.user.*
* **All group commands** - luckperms.group.*
* **All track commands** - luckperms.track.*
| **Command** | **Description** | **Permission** |
| /perms | Sends plugin info and usage | N/A |
| /perms sync | Runs an update task and reloads the data of all online users | luckperms.sync |
@ -55,6 +63,12 @@ Users with OP have access to all commands.
| | | |
| | | |
| | | |
| /perms createtrack <track> | Creates a new track with the given name | luckperms.createtrack |
| /perms deletetrack <track> | Deletes an existing track | luckperms.deletetrack |
| /perms listtracks | Shows a list of the tracks registered within the system | luckperms.listtracks |
| | | |
| | | |
| | | |
| /perms user <user> info | Shows info about the user | luckperms.user.info |
| /perms user <user> getuuid | Shows the users Mojang UUID | luckperms.user.getuuid |
| /perms user <user> listnodes | Lists all of the permission nodes the user has | luckperms.user.listnodes |
@ -65,6 +79,10 @@ Users with OP have access to all commands.
| /perms user <user> addgroup <group> [server] | Adds the user to a group | luckperms.user.addgroup |
| /perms user <user> removegroup <group> [server] | Removes the user from a group | luckperms.user.removegroup |
| /perms user <user> setprimarygroup <group> | Sets the users primary group | luckperms.user.setprimarygroup |
| /perms user <user> showtracks | Shows a list of the tracks the user can be promoted/demoted on | luckperms.user.showtracks |
| /perms user <user> promote <track> | Promotes the user along a given track | luckperms.user.promote |
| /perms user <user> demote <track> | Demotes the user along a given track | luckperms.user.demote |
| /perms user <user> showpos <track> | Shows the users position on a given track | luckperms.user.showpos |
| /perms user <user> clear | Clears all permissions the user has | luckperms.user.clear |
| | | |
| | | |
@ -77,7 +95,17 @@ Users with OP have access to all commands.
| /perms group <group> unset <node> [server] | Unsets a permission for the group | luckperms.group.unsetpermission |
| /perms group <group> setinherit <group> [server]| Sets the group to inherit all permissions from another group | luckperms.group.setinherit |
| /perms group <group> unsetinherit <group> [server] | Unsets a perviously defined inheritance rule | luckperms.group.unsetinherit |
| /perms group <group> showtracks | Shows a list of the tracks that the users in the group can be promoted/demoted on | luckperms.group.showtracks |
| /perms group <group> clear | Clears all permissions the group has | luckperms.group.clear |
| | | |
| | | |
| | | |
| /perms track <track> info | Shows info about the track | luckperms.track.info |
| /perms track <track> append <group> | Appends a group to the end of the track | luckperms.track.append |
| /perms track <track> insert <group> <position> | Inserts a group at the given position on the track | luckperms.track.insert |
| /perms track <track> remove <group> | Removes a group from the track | luckperms.track.remove |
| /perms track <track> clear | Clears all groups on the track | luckperms.track.clear |
=== License
See LICENSE.md.
See LICENSE.md.

View File

@ -9,6 +9,7 @@ import me.lucko.luckperms.data.methods.SQLiteDatastore;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.listeners.PlayerListener;
import me.lucko.luckperms.runnables.UpdateTask;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.BukkitUserManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
@ -29,6 +30,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
@Override
@ -70,6 +72,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
userManager = new BukkitUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
// Run update task to refresh any online users
runUpdateTask();

View File

@ -3,7 +3,7 @@ package me.lucko.luckperms.vaulthooks;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import net.milkbowl.vault.permission.Permission;
@ -54,7 +54,7 @@ class VaultPermissionHook extends Permission {
try {
user.unsetPermission(permission);
} catch (ObjectLacksPermissionException ignored) {}
} catch (ObjectLacksException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}
@ -84,7 +84,7 @@ class VaultPermissionHook extends Permission {
try {
group.unsetPermission(permission);
} catch (ObjectLacksPermissionException ignored) {}
} catch (ObjectLacksException ignored) {}
plugin.runUpdateTask();
return true;
}
@ -123,7 +123,7 @@ class VaultPermissionHook extends Permission {
try {
user.removeGroup(group);
} catch (ObjectLacksPermissionException ignored) {}
} catch (ObjectLacksException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}

View File

@ -9,6 +9,7 @@ import me.lucko.luckperms.data.methods.MySQLDatastore;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.listeners.PlayerListener;
import me.lucko.luckperms.runnables.UpdateTask;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.BungeeUserManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
@ -24,6 +25,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
@Override
@ -58,6 +60,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
userManager = new BungeeUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
int mins = getConfiguration().getSyncTime();
if (mins > 0) {

View File

@ -2,6 +2,7 @@ package me.lucko.luckperms;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
@ -12,16 +13,22 @@ public interface LuckPermsPlugin {
/**
* Retrieves the {@link UserManager} used to manage users and their permissions/groups
* @return the {@link UserManager} object
* @return the {@link UserManager} instance
*/
UserManager getUserManager();
/**
* Retrieves the {@link GroupManager} used to manage the loaded groups and modify their permissions
* @return the {@link GroupManager} object
* @return the {@link GroupManager} instance
*/
GroupManager getGroupManager();
/**
* Retrieves the {@link TrackManager} used to manage the loaded tracks
* @return the {@link TrackManager} instance
*/
TrackManager getTrackManager();
/**
* Retrieves the {@link LPConfiguration} for getting values from the config
* @return the {@link LPConfiguration} implementation for the platform

View File

@ -10,6 +10,11 @@ import me.lucko.luckperms.commands.group.subcommands.*;
import me.lucko.luckperms.commands.misc.DebugCommand;
import me.lucko.luckperms.commands.misc.InfoCommand;
import me.lucko.luckperms.commands.misc.SyncCommand;
import me.lucko.luckperms.commands.track.CreateTrackCommand;
import me.lucko.luckperms.commands.track.DeleteTrackCommand;
import me.lucko.luckperms.commands.track.ListTracksCommand;
import me.lucko.luckperms.commands.track.TrackMainCommand;
import me.lucko.luckperms.commands.track.subcommands.*;
import me.lucko.luckperms.commands.user.UserMainCommand;
import me.lucko.luckperms.commands.user.subcommands.*;
import me.lucko.luckperms.constants.Message;
@ -32,14 +37,18 @@ public class CommandManager {
this.registerMainCommand(userCommand);
userCommand.registerSubCommand(new UserAddGroupCommand());
userCommand.registerSubCommand(new UserClearCommand());
userCommand.registerSubCommand(new UserDemoteCommand());
userCommand.registerSubCommand(new UserGetUUIDCommand());
userCommand.registerSubCommand(new UserHasPermCommand());
userCommand.registerSubCommand(new UserInfoCommand());
userCommand.registerSubCommand(new UserInheritsPermCommand());
userCommand.registerSubCommand(new UserListNodesCommand());
userCommand.registerSubCommand(new UserPromoteCommand());
userCommand.registerSubCommand(new UserRemoveGroupCommand());
userCommand.registerSubCommand(new UserSetPermissionCommand());
userCommand.registerSubCommand(new UserSetPrimaryGroupCommand());
userCommand.registerSubCommand(new UserShowPosCommand());
userCommand.registerSubCommand(new UserShowTracksCommand());
userCommand.registerSubCommand(new UserUnSetPermissionCommand());
GroupMainCommand groupCommand = new GroupMainCommand();
@ -51,12 +60,24 @@ public class CommandManager {
groupCommand.registerSubCommand(new GroupListNodesCommand());
groupCommand.registerSubCommand(new GroupSetInheritCommand());
groupCommand.registerSubCommand(new GroupSetPermissionCommand());
groupCommand.registerSubCommand(new GroupShowTracksCommand());
groupCommand.registerSubCommand(new GroupUnsetInheritCommand());
groupCommand.registerSubCommand(new GroupUnSetPermissionCommand());
TrackMainCommand trackCommand = new TrackMainCommand();
this.registerMainCommand(trackCommand);
trackCommand.registerSubCommand(new TrackAppendCommand());
trackCommand.registerSubCommand(new TrackClearCommand());
trackCommand.registerSubCommand(new TrackInfoCommand());
trackCommand.registerSubCommand(new TrackInsertCommand());
trackCommand.registerSubCommand(new TrackRemoveCommand());
this.registerMainCommand(new CreateGroupCommand());
this.registerMainCommand(new DeleteGroupCommand());
this.registerMainCommand(new ListGroupsCommand());
this.registerMainCommand(new CreateTrackCommand());
this.registerMainCommand(new DeleteTrackCommand());
this.registerMainCommand(new ListTracksCommand());
this.registerMainCommand(new DebugCommand());
this.registerMainCommand(new InfoCommand());
this.registerMainCommand(new SyncCommand());

View File

@ -48,6 +48,44 @@ public class Util {
return sb.delete(sb.length() - 2, sb.length()).toString();
}
public static String listToArrowSep(List<String> strings, String highlight) {
if (strings.isEmpty()) return "&6None";
StringBuilder sb = new StringBuilder();
for (String s : strings) {
if (s.equalsIgnoreCase(highlight)) {
sb.append("&e").append(s).append("&7 ---> ");
} else {
sb.append("&6").append(s).append("&7 ---> ");
}
}
return sb.delete(sb.length() - 6, sb.length()).toString();
}
public static String listToArrowSep(List<String> strings, String highlightFirst, String highlightSecond, boolean reversed) {
if (strings.isEmpty()) return "&6None";
StringBuilder sb = new StringBuilder();
for (String s : strings) {
if (s.equalsIgnoreCase(highlightFirst)) {
sb.append("&e").append(s).append("&4").append(reversed ? " <--- " : " ---> ");
} else if (s.equalsIgnoreCase(highlightSecond)) {
sb.append("&e").append(s).append("&7").append(reversed ? " <--- " : " ---> ");
} else {
sb.append("&6").append(s).append("&7").append(reversed ? " <--- " : " ---> ");
}
}
return sb.delete(sb.length() - 6, sb.length()).toString();
}
public static String listToArrowSep(List<String> strings) {
if (strings.isEmpty()) return "&6None";
StringBuilder sb = new StringBuilder();
strings.forEach(s -> sb.append("&6").append(s).append("&e ---> "));
return sb.delete(sb.length() - 6, sb.length()).toString();
}
public static String nodesToString(Map<String, Boolean> nodes) {
if (nodes.isEmpty()) return "&6None";

View File

@ -43,7 +43,7 @@ public class CreateGroupCommand extends MainCommand {
if (!success1) {
Message.CREATE_GROUP_ERROR.send(sender);
} else {
Message.CREATE_GROUP_SUCCESS.send(sender, groupName);
Message.CREATE_SUCCESS.send(sender, groupName);
plugin.runUpdateTask();
}
});

View File

@ -43,7 +43,7 @@ public class DeleteGroupCommand extends MainCommand {
if (!success1) {
Message.DELETE_GROUP_ERROR.send(sender);
} else {
Message.DELETE_GROUP_SUCCESS.send(sender, groupName);
Message.DELETE_SUCCESS.send(sender, groupName);
plugin.runUpdateTask();
}
});

View File

@ -0,0 +1,37 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
import java.util.stream.Collectors;
public class GroupShowTracksCommand extends GroupSubCommand {
public GroupShowTracksCommand() {
super("showtracks", "Lists the tracks that this group features on", "/perms group <group> showtracks", Permission.GROUP_SHOWTRACKS);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args) {
plugin.getDatastore().loadAllTracks(success -> {
if (!success) {
Message.TRACKS_LOAD_ERROR.send(sender);
return;
}
Message.TRACKS_LIST.send(sender, Util.listToCommaSep(
plugin.getTrackManager().getApplicableTracks(group.getName()).stream().map(Track::getName).collect(Collectors.toList())));
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}

View File

@ -5,7 +5,7 @@ import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
@ -42,7 +42,7 @@ public class GroupUnSetPermissionCommand extends GroupSubCommand {
}
saveGroup(group, sender, plugin);
} catch (ObjectLacksPermissionException e) {
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getName());
}
}

View File

@ -5,7 +5,7 @@ import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import java.util.List;
@ -31,7 +31,7 @@ public class GroupUnsetInheritCommand extends GroupSubCommand {
}
saveGroup(group, sender, plugin);
} catch (ObjectLacksPermissionException e) {
} catch (ObjectLacksException e) {
Message.GROUP_DOES_NOT_INHERIT.send(sender, group.getName(), groupName);
}
}

View File

@ -18,7 +18,7 @@ public class DebugCommand extends MainCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args) {
Message.DEBUG.send(sender, plugin.getPlayerCount(), plugin.getUserManager().getUsers().size(),
plugin.getGroupManager().getGroups().size()
plugin.getGroupManager().getGroups().size(), plugin.getTrackManager().getTracks().size()
);
}

View File

@ -0,0 +1,63 @@
package me.lucko.luckperms.commands.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.List;
public class CreateTrackCommand extends MainCommand {
public CreateTrackCommand() {
super("CreateTrack", "/perms createtrack <track>", 1);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args) {
if (args.size() == 0) {
sendUsage(sender);
return;
}
String trackName = args.get(0).toLowerCase();
if (trackName.length() > 36) {
Message.TRACK_NAME_TOO_LONG.send(sender, trackName);
return;
}
if (Patterns.NON_ALPHA_NUMERIC.matcher(trackName).find()) {
Message.TRACK_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadTrack(trackName, success -> {
if (success) {
Message.TRACK_ALREADY_EXISTS.send(sender);
} else {
plugin.getDatastore().createAndLoadTrack(trackName, success1 -> {
if (!success1) {
Message.CREATE_TRACK_ERROR.send(sender);
} else {
Message.CREATE_SUCCESS.send(sender, trackName);
plugin.runUpdateTask();
}
});
}
});
}
@Override
public List<? extends SubCommand> getSubCommands() {
return new ArrayList<>();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.CREATE_TRACK.isAuthorized(sender);
}
}

View File

@ -0,0 +1,59 @@
package me.lucko.luckperms.commands.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import java.util.ArrayList;
import java.util.List;
public class DeleteTrackCommand extends MainCommand {
public DeleteTrackCommand() {
super("DeleteTrack", "/perms deletetrack <track>", 1);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args) {
if (args.size() == 0) {
sendUsage(sender);
return;
}
String trackName = args.get(0).toLowerCase();
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
} else {
Track track = plugin.getTrackManager().getTrack(trackName);
if (track == null) {
Message.TRACK_LOAD_ERROR.send(sender);
} else {
plugin.getDatastore().deleteTrack(track, success1 -> {
if (!success1) {
Message.DELETE_TRACK_ERROR.send(sender);
} else {
Message.DELETE_SUCCESS.send(sender, trackName);
plugin.runUpdateTask();
}
});
}
}
});
}
@Override
public List<SubCommand> getSubCommands() {
return new ArrayList<>();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.DELETE_TRACK.isAuthorized(sender);
}
}

View File

@ -0,0 +1,39 @@
package me.lucko.luckperms.commands.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import java.util.ArrayList;
import java.util.List;
public class ListTracksCommand extends MainCommand {
public ListTracksCommand() {
super("ListTracks", "/perms listtracks", 0);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args) {
plugin.getDatastore().loadAllTracks(success -> {
if (!success) {
Message.TRACKS_LOAD_ERROR.send(sender);
} else {
Message.TRACKS_LIST.send(sender, Util.listToCommaSep(new ArrayList<>(plugin.getTrackManager().getTracks().keySet())));
}
});
}
@Override
public List<SubCommand> getSubCommands() {
return new ArrayList<>();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.LIST_TRACKS.isAuthorized(sender);
}
}

View File

@ -0,0 +1,78 @@
package me.lucko.luckperms.commands.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.tracks.Track;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class TrackMainCommand extends MainCommand {
private final List<TrackSubCommand> subCommands = new ArrayList<>();
public TrackMainCommand() {
super("Track", "/perms track <track>", 2);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args) {
if (args.size() < 2) {
sendUsage(sender);
return;
}
Optional<TrackSubCommand> o = subCommands.stream().filter(s -> s.getName().equalsIgnoreCase(args.get(1))).limit(1).findAny();
if (!o.isPresent()) {
Message.COMMAND_NOT_RECOGNISED.send(sender);
return;
}
final TrackSubCommand sub = o.get();
if (!sub.isAuthorized(sender)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return;
}
List<String> strippedArgs = new ArrayList<>();
if (args.size() > 2) {
strippedArgs.addAll(args.subList(2, args.size()));
}
if (sub.isArgLengthInvalid(strippedArgs.size())) {
sub.sendUsage(sender);
return;
}
final String trackName = args.get(0).toLowerCase();
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_NOT_FOUND.send(sender);
return;
}
Track track = plugin.getTrackManager().getTrack(trackName);
if (track == null) {
Message.TRACK_NOT_FOUND.send(sender);
return;
}
sub.execute(plugin, sender, track, strippedArgs);
});
}
@Override
public List<? extends SubCommand> getSubCommands() {
return subCommands;
}
public void registerSubCommand(TrackSubCommand subCommand) {
subCommands.add(subCommand);
}
}

View File

@ -0,0 +1,30 @@
package me.lucko.luckperms.commands.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public abstract class TrackSubCommand extends SubCommand {
public TrackSubCommand(String name, String description, String usage, Permission permission) {
super(name, description, usage, permission);
}
protected abstract void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args);
protected void saveTrack(Track track, Sender sender, LuckPermsPlugin plugin) {
plugin.getDatastore().saveTrack(track, success -> {
if (success) {
Message.TRACK_SAVE_SUCCESS.send(sender);
} else {
Message.TRACK_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
});
}
}

View File

@ -0,0 +1,50 @@
package me.lucko.luckperms.commands.track.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.track.TrackSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public class TrackAppendCommand extends TrackSubCommand {
public TrackAppendCommand() {
super("append", "Appends a group onto the end of the track", "/perms track <track> append <group>", Permission.TRACK_APPEND);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args) {
String groupName = args.get(0).toLowerCase();
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
} else {
Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return;
}
try {
track.appendGroup(group);
Message.TRACK_APPEND_SUCCESS.send(sender, group.getName(), track.getName());
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), group.getName()));
saveTrack(track, sender, plugin);
} catch (ObjectAlreadyHasException e) {
Message.TRACK_ALREADY_CONTAINS.send(sender, track.getName(), group.getName());
}
}
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1;
}
}

View File

@ -0,0 +1,28 @@
package me.lucko.luckperms.commands.track.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.track.TrackSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public class TrackClearCommand extends TrackSubCommand {
public TrackClearCommand() {
super("clear", "Clears the groups on the track", "/perms track <track> clear", Permission.TRACK_CLEAR);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args) {
track.clearGroups();
Message.TRACK_CLEAR.send(sender, track.getName());
saveTrack(track, sender, plugin);
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}

View File

@ -0,0 +1,27 @@
package me.lucko.luckperms.commands.track.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.track.TrackSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public class TrackInfoCommand extends TrackSubCommand {
public TrackInfoCommand() {
super("info", "Gives info about the track", "/perms track <track> info", Permission.TRACK_INFO);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args) {
Message.TRACK_INFO.send(sender, track.getName(), Util.listToArrowSep(track.getGroups()));
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}

View File

@ -0,0 +1,60 @@
package me.lucko.luckperms.commands.track.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.track.TrackSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public class TrackInsertCommand extends TrackSubCommand {
public TrackInsertCommand() {
super("insert", "Inserts a group at a given position along the track",
"/perms track <track> insert <group> <position>", Permission.TRACK_INSERT);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args) {
String groupName = args.get(0).toLowerCase();
int pos;
try {
pos = Integer.parseInt(args.get(1));
} catch (NumberFormatException e) {
Message.TRACK_INSERT_ERROR_NUMBER.send(sender, args.get(1));
return;
}
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
} else {
Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return;
}
try {
track.insertGroup(group, pos - 1);
Message.TRACK_INSERT_SUCCESS.send(sender, group.getName(), track.getName(), pos);
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), group.getName()));
saveTrack(track, sender, plugin);
} catch (ObjectAlreadyHasException e) {
Message.TRACK_ALREADY_CONTAINS.send(sender, track.getName(), group.getName());
} catch (IndexOutOfBoundsException e) {
Message.TRACK_INSERT_ERROR_INVALID_POS.send(sender, pos);
}
}
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 2;
}
}

View File

@ -0,0 +1,34 @@
package me.lucko.luckperms.commands.track.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.track.TrackSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
public class TrackRemoveCommand extends TrackSubCommand {
public TrackRemoveCommand() {
super("remove", "Removes a group from the track", "/perms track <track> remove <group>", Permission.TRACK_REMOVE);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args) {
String groupName = args.get(0).toLowerCase();
try {
track.removeGroup(groupName);
Message.TRACK_REMOVE_SUCCESS.send(sender, groupName, track.getName());
saveTrack(track, sender, plugin);
} catch (ObjectLacksException e) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), groupName);
}
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1;
}
}

View File

@ -0,0 +1,86 @@
package me.lucko.luckperms.commands.user.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.List;
public class UserDemoteCommand extends UserSubCommand {
public UserDemoteCommand() {
super("demote", "Demotes a user along a track", "/perms user <user> demote <track>", Permission.USER_DEMOTE);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args) {
final String trackName = args.get(0).toLowerCase();
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
} else {
Track track = plugin.getTrackManager().getTrack(trackName);
if (track == null) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return;
}
if (track.getSize() <= 1) {
Message.TRACK_EMPTY.send(sender);
return;
}
final String old = user.getPrimaryGroup();
final String previous;
try {
previous = track.getPrevious(old);
} catch (ObjectLacksException e) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), old);
Message.USER_DEMOTE_ERROR_NOT_CONTAIN_GROUP.send(sender);
return;
}
if (previous == null) {
Message.USER_DEMOTE_ERROR_ENDOFTRACK.send(sender, track.getName());
return;
}
plugin.getDatastore().loadGroup(previous, success1 -> {
if (!success1) {
Message.USER_DEMOTE_ERROR_MALFORMED.send(sender, previous);
} else {
Group previousGroup = plugin.getGroupManager().getGroup(previous);
if (previousGroup == null) {
Message.USER_DEMOTE_ERROR_MALFORMED.send(sender, previous);
return;
}
try {
user.unsetPermission("group." + old);
user.addGroup(previousGroup);
user.setPrimaryGroup(previousGroup.getName());
} catch (ObjectLacksException | ObjectAlreadyHasException ignored) {}
Message.USER_DEMOTE_SUCCESS_PROMOTE.send(sender, track.getName(), old, previousGroup.getName());
Message.USER_DEMOTE_SUCCESS_REMOVE.send(sender, user.getName(), old, previousGroup.getName(), previousGroup.getName());
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), previousGroup.getName(), old, true));
saveUser(user, sender, plugin);
}
});
}
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1;
}
}

View File

@ -0,0 +1,86 @@
package me.lucko.luckperms.commands.user.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.List;
public class UserPromoteCommand extends UserSubCommand {
public UserPromoteCommand() {
super("promote", "Promotes the user along a track", "/perms user <user> promote <track>", Permission.USER_PROMOTE);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args) {
final String trackName = args.get(0).toLowerCase();
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
} else {
Track track = plugin.getTrackManager().getTrack(trackName);
if (track == null) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return;
}
if (track.getSize() <= 1) {
Message.TRACK_EMPTY.send(sender);
return;
}
final String old = user.getPrimaryGroup();
final String next;
try {
next = track.getNext(old);
} catch (ObjectLacksException e) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), old);
Message.USER_PROMOTE_ERROR_NOT_CONTAIN_GROUP.send(sender);
return;
}
if (next == null) {
Message.USER_PROMOTE_ERROR_ENDOFTRACK.send(sender, track.getName());
return;
}
plugin.getDatastore().loadGroup(next, success1 -> {
if (!success1) {
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
} else {
Group nextGroup = plugin.getGroupManager().getGroup(next);
if (nextGroup == null) {
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
return;
}
try {
user.unsetPermission("group." + old);
user.addGroup(nextGroup);
user.setPrimaryGroup(nextGroup.getName());
} catch (ObjectLacksException | ObjectAlreadyHasException ignored) {}
Message.USER_PROMOTE_SUCCESS_PROMOTE.send(sender, track.getName(), old, nextGroup.getName());
Message.USER_PROMOTE_SUCCESS_REMOVE.send(sender, user.getName(), old, nextGroup.getName(), nextGroup.getName());
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), old, nextGroup.getName(), false));
saveUser(user, sender, plugin);
}
});
}
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1;
}
}

View File

@ -5,7 +5,7 @@ import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.users.User;
import java.util.List;
@ -36,7 +36,7 @@ public class UserRemoveGroupCommand extends UserSubCommand {
}
saveUser(user, sender, plugin);
} catch (ObjectLacksPermissionException e) {
} catch (ObjectLacksException e) {
Message.USER_NOT_MEMBER_OF.send(sender, user.getName(), groupName);
}
}

View File

@ -0,0 +1,52 @@
package me.lucko.luckperms.commands.user.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.List;
public class UserShowPosCommand extends UserSubCommand {
public UserShowPosCommand() {
super("showpos", "Shows a users position on a track", "/perms user <user> showpos <track>", Permission.USER_SHOWPOS);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args) {
final String trackName = args.get(0).toLowerCase();
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
} else {
Track track = plugin.getTrackManager().getTrack(trackName);
if (track == null) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return;
}
if (track.getSize() <= 1) {
Message.TRACK_EMPTY.send(sender);
return;
}
if (!track.containsGroup(user.getPrimaryGroup())) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), user.getPrimaryGroup());
return;
}
Message.USER_SHOWPOS.send(sender, user.getName(), track.getName(), Util.listToArrowSep(track.getGroups(), user.getPrimaryGroup()));
}
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1;
}
}

View File

@ -0,0 +1,38 @@
package me.lucko.luckperms.commands.user.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.List;
import java.util.stream.Collectors;
public class UserShowTracksCommand extends UserSubCommand {
public UserShowTracksCommand() {
super("showtracks", "Lists the tracks that this user's primary group features on", "/perms user <user> showtracks", Permission.USER_SHOWTRACKS);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args) {
plugin.getDatastore().loadAllTracks(success -> {
if (!success) {
Message.TRACKS_LOAD_ERROR.send(sender);
return;
}
Message.USER_SHOWTRACKS_INFO.send(sender, user.getPrimaryGroup(), user.getName());
Message.TRACKS_LIST.send(sender, Util.listToCommaSep(
plugin.getTrackManager().getApplicableTracks(user.getPrimaryGroup()).stream().map(Track::getName).collect(Collectors.toList())));
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}

View File

@ -5,7 +5,7 @@ import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.user.UserSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.Patterns;
@ -42,7 +42,7 @@ public class UserUnSetPermissionCommand extends UserSubCommand {
}
saveUser(user, sender, plugin);
} catch (ObjectLacksPermissionException e) {
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVEPERMISSION.send(sender, user.getName());
}
}

View File

@ -8,44 +8,78 @@ import me.lucko.luckperms.commands.Util;
@AllArgsConstructor
public enum Message {
/**
* General & Commands
*/
PREFIX("&7&l[&b&lL&a&lP&7&l] &c", false),
EMPTY("%s", true),
COMMAND_NOT_RECOGNISED("Command not recognised.", true),
COMMAND_NO_PERMISSION("You do not have permission to use this command!", true),
INFO_BRIEF("&6Running &bLuckPerms %s&6.", true),
ALREADY_HASPERMISSION("%s already has this permission!", true),
DOES_NOT_HAVEPERMISSION("%s does not have this permission set.", true),
/**
* Loading / Saving
*/
USER_NOT_FOUND("&eUser could not be found.", true),
USER_SAVE_SUCCESS("&7(User data was saved to the datastore)", true),
USER_SAVE_ERROR("There was an error whilst saving the user.", true),
USER_ALREADY_MEMBER_OF("%s is already a member of '%s'.", true),
USER_NOT_MEMBER_OF("%s is not a member of '%s'.", true),
USER_USE_ADDGROUP("Use the addgroup command instead of specifying the node.", true),
USER_USE_REMOVEGROUP("Use the removegroup command instead of specifying the node.", true),
USER_INVALID_ENTRY("&d%s&c is not a valid username/uuid.", true),
USER_ATTEMPTING_LOOKUP("&7(Attempting UUID lookup, since you specified a user)", true),
GROUP_NOT_FOUND("&eGroup could not be found.", true),
GROUP_SAVE_SUCCESS("&7(Group data was saved to the datastore)", true),
GROUP_SAVE_ERROR("There was an error whilst saving the group.", true),
GROUP_ALREADY_INHERITS("%s already inherits '%s'.", true),
GROUP_DOES_NOT_INHERIT("%s does not inherit '%s'.", true),
TRACK_NOT_FOUND("&eTrack could not be found.", true),
TRACK_SAVE_SUCCESS("&7(Track data was saved to the datastore)", true),
TRACK_SAVE_ERROR("There was an error whilst saving the track.", true),
/**
* Command Syntax
*/
USER_USE_ADDGROUP("Use the addgroup command instead of specifying the node.", true),
USER_USE_REMOVEGROUP("Use the removegroup command instead of specifying the node.", true),
USER_INVALID_ENTRY("&d%s&c is not a valid username/uuid.", true),
GROUP_USE_INHERIT("Use the setinherit command instead of specifying the node.", true),
GROUP_USE_UNINHERIT("Use the unsetinherit command instead of specifying the node.", true),
GROUP_INVALID_ENTRY("Group names can only contain alphanumeric charcters.", true),
TRACK_INVALID_ENTRY("Track names can only contain alphanumeric charcters.", true),
USER_ATTEMPTING_LOOKUP("&7(Attempting UUID lookup, since you specified a user)", true),
/**
* Commands
*/
CREATE_SUCCESS("&b%s&a was successfully created.", true),
DELETE_SUCCESS("&b%s&a was successfully deleted.", true),
USER_ALREADY_MEMBER_OF("%s is already a member of '%s'.", true),
USER_NOT_MEMBER_OF("%s is not a member of '%s'.", true),
GROUP_ALREADY_INHERITS("%s already inherits '%s'.", true),
GROUP_DOES_NOT_INHERIT("%s does not inherit '%s'.", true),
TRACK_ALREADY_CONTAINS("Track %s already contains the group '%s'.", true),
TRACK_DOES_NOT_CONTAIN("Track %s does not contain the group '%s'.", true),
GROUP_ALREADY_EXISTS("That group already exists!", true),
GROUP_DOES_NOT_EXIST("That group does not exist!", true),
GROUP_NAME_TOO_LONG("Group name '%s' exceeds the maximum length of 36 characters.", true),
GROUP_LOAD_ERROR("An unexpected error occurred. Group not loaded.", true),
GROUPS_LOAD_ERROR("An unexpected error occurred. Unable to load all groups.", true),
TRACK_ALREADY_EXISTS("That track already exists!", true),
TRACK_DOES_NOT_EXIST("That track does not exist!", true),
TRACK_NAME_TOO_LONG("Track name '%s' exceeds the maximum length of 36 characters.", true),
TRACK_LOAD_ERROR("An unexpected error occurred. Track not loaded.", true),
TRACKS_LOAD_ERROR("An unexpected error occurred. Unable to load all tracks.", true),
TRACK_EMPTY("The track cannot be used as it is empty or contains only one group.", true),
UPDATE_TASK_RUN("&bRunning update task for all online users.", true),
INFO(
@ -58,17 +92,20 @@ public enum Message {
PREFIX + "&d&l> &dDebug Info" + "\n" +
PREFIX + "&eOnline Players: &6%s" + "\n" +
PREFIX + "&eLoaded Users: &6%s" + "\n" +
PREFIX + "&eLoaded Groups: &6%s",
PREFIX + "&eLoaded Groups: &6%s" + "\n" +
PREFIX + "&eLoaded Tracks: &6%s",
false
),
CREATE_GROUP_ERROR("There was an error whilst creating the group.", true),
CREATE_GROUP_SUCCESS("&b%s&a was successfully created.", true),
DELETE_GROUP_ERROR("There was an error whilst deleting the group.", true),
DELETE_GROUP_ERROR_DEFAULT("You cannot delete the default group.", true),
DELETE_GROUP_SUCCESS("&b%s&a was successfully deleted.", true),
GROUPS_LIST("&aGroups: %s", true),
CREATE_TRACK_ERROR("There was an error whilst creating the track.", true),
DELETE_TRACK_ERROR("There was an error whilst deleting the track.", true),
TRACKS_LIST("&aTracks: %s", true),
LISTNODES("&e%s's Nodes:" + "\n" + "%s", true),
SETPERMISSION_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a.", true),
SETPERMISSION_SERVER_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a.", true),
@ -95,6 +132,26 @@ public enum Message {
USER_PRIMARYGROUP_SUCCESS("&b%s&a's primary group was set to &b%s&a.", true),
USER_PRIMARYGROUP_ERROR_ALREADYHAS("The user already has this group set as their primary group.", true),
USER_PRIMARYGROUP_ERROR_NOTMEMBER("The user must be a member of the group first! Use &4/perms user <user> addgroup <group>", true),
USER_SHOWTRACKS_INFO("&aShowing tracks that contain the group '&b%s&a' (%s's primary group)", true),
USER_PROMOTE_SUCCESS_PROMOTE("&aPromoting user along track &b%s&a from &b%s&a to &b%s&a.", true),
USER_PROMOTE_SUCCESS_REMOVE("&b%s&a was removed from &b%s&a, added to &b%s&a, and their primary group was set to &b%s&a.", true),
USER_PROMOTE_ERROR_ENDOFTRACK("The end of track &4%s&c was reached. Unable to promote user.", true),
USER_PROMOTE_ERROR_MALFORMED(
PREFIX + "The next group on the track, %s, no longer exists. Unable to promote user." + "\n" +
PREFIX + "Either create the group, or remove it from the track and try again.",
false
),
USER_PROMOTE_ERROR_NOT_CONTAIN_GROUP("Promotions are done based on primary groups. The users primary group is not on the track specified.", true),
USER_DEMOTE_SUCCESS_PROMOTE("&aDemoting user along track &b%s&a from &b%s&a to &b%s&a.", true),
USER_DEMOTE_SUCCESS_REMOVE("&b%s&a was removed from &b%s&a, added to &b%s&a, and their primary group was set to &b%s&a.", true),
USER_DEMOTE_ERROR_ENDOFTRACK("The end of track &4%s&c was reached. Unable to demote user.", true),
USER_DEMOTE_ERROR_MALFORMED(
PREFIX + "The previous group on the track, %s, no longer exists. Unable to demote user." + "\n" +
PREFIX + "Either create the group, or remove it from the track and try again.",
false
),
USER_DEMOTE_ERROR_NOT_CONTAIN_GROUP("Demotions are done based on primary groups. The users primary group is not on the track specified.", true),
USER_SHOWPOS("&aShowing &b%s&a's position on track &b%s&a.\n%s", true),
GROUP_INFO(
PREFIX + "&d-> &eGroup: &6%s" + "\n" +
@ -105,7 +162,19 @@ public enum Message {
GROUP_SETINHERIT_SUCCESS("&b%s&a now inherits permissions from &b%s&a.", true),
GROUP_SETINHERIT_SERVER_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a.", true),
GROUP_UNSETINHERIT_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a.", true),
GROUP_UNSETINHERIT_SERVER_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a on server &b%s&a.", true);
GROUP_UNSETINHERIT_SERVER_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a on server &b%s&a.", true),
TRACK_INFO(
PREFIX + "&d-> &eTrack: &6%s" + "\n" +
PREFIX + "&d-> &ePath: &6%s",
false
),
TRACK_CLEAR("&b%s&a's groups track was cleared.", true),
TRACK_APPEND_SUCCESS("&aGroup &b%s&a was successfully appended to track &b%s&a.", true),
TRACK_INSERT_SUCCESS("&aGroup &b%s&a was successfully inserted into to track &b%s&a at position &b%s&a.", true),
TRACK_INSERT_ERROR_NUMBER("Expected number but instead received: %s", true),
TRACK_INSERT_ERROR_INVALID_POS("Unable to insert at position %s. Index out of bounds.", true),
TRACK_REMOVE_SUCCESS("&aGroup &b%s&a was successfully removed from track &b%s&a.", true);
private String message;
private boolean showPrefix;

View File

@ -16,6 +16,10 @@ public enum Permission {
DELETE_GROUP("deletegroup", null),
LIST_GROUPS("listgroups", null),
CREATE_TRACK("createtrack", null),
DELETE_TRACK("deletetrack", null),
LIST_TRACKS("listtracks", null),
USER_INFO("info", PermissionGroup.USER),
USER_GETUUID("getuuid", PermissionGroup.USER),
USER_LISTNODES("listnodes", PermissionGroup.USER),
@ -26,6 +30,10 @@ public enum Permission {
USER_ADDGROUP("addgroup", PermissionGroup.USER),
USER_REMOVEGROUP("removegroup", PermissionGroup.USER),
USER_SETPRIMARYGROUP("setprimarygroup", PermissionGroup.USER),
USER_SHOWTRACKS("showtracks", PermissionGroup.USER),
USER_PROMOTE("promote", PermissionGroup.USER),
USER_DEMOTE("demote", PermissionGroup.USER),
USER_SHOWPOS("showpos", PermissionGroup.USER),
USER_CLEAR("clear", PermissionGroup.USER),
GROUP_INFO("info", PermissionGroup.GROUP),
@ -36,7 +44,14 @@ public enum Permission {
GROUP_UNSETPERMISSION("unsetpermission", PermissionGroup.GROUP),
GROUP_SETINHERIT("setinherit", PermissionGroup.GROUP),
GROUP_UNSETINHERIT("unsetinherit", PermissionGroup.GROUP),
GROUP_CLEAR("clear", PermissionGroup.GROUP);
GROUP_SHOWTRACKS("showtracks", PermissionGroup.GROUP),
GROUP_CLEAR("clear", PermissionGroup.GROUP),
TRACK_INFO("info", PermissionGroup.TRACK),
TRACK_APPEND("append", PermissionGroup.TRACK),
TRACK_INSERT("insert", PermissionGroup.TRACK),
TRACK_REMOVE("remove", PermissionGroup.TRACK),
TRACK_CLEAR("clear", PermissionGroup.TRACK);
private String node;
private PermissionGroup group;
@ -57,7 +72,8 @@ public enum Permission {
@AllArgsConstructor
private enum PermissionGroup {
USER("user"),
GROUP("group");
GROUP("group"),
TRACK("track");
private String node;

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.UUID;
@ -45,7 +46,7 @@ public abstract class Datastore {
}
/*
These methods will block the thread that they're ran on.
These methods are called immediately and in the same thread as they are called in.
*/
public abstract void init();
public abstract void shutdown();
@ -57,16 +58,19 @@ public abstract class Datastore {
public abstract boolean loadAllGroups();
public abstract boolean saveGroup(Group group);
public abstract boolean deleteGroup(Group group);
public abstract boolean createAndLoadTrack(String name);
public abstract boolean loadTrack(String name);
public abstract boolean loadAllTracks();
public abstract boolean saveTrack(Track track);
public abstract boolean deleteTrack(Track track);
public abstract boolean saveUUIDData(String username, UUID uuid);
public abstract UUID getUUID(String username);
/*
These methods will return as soon as they are called. The callback will be ran when the task is complete
They therefore will not block the thread that they're ran on
Callbacks are ran on the main server thread (if applicable)
These methods will schedule the operation to run async. The callback will be ran when the task is complete.
Callbacks are ran on the main Bukkit server thread (if applicable)
*/
public void loadOrCreateUser(UUID uuid, String username, Callback callback) {
doAsync(() -> runCallback(loadOrCreateUser(uuid, username), callback));
@ -100,6 +104,26 @@ public abstract class Datastore {
doAsync(() -> runCallback(deleteGroup(group), callback));
}
public void createAndLoadTrack(String name, Callback callback) {
doAsync(() -> runCallback(createAndLoadTrack(name), callback));
}
public void loadTrack(String name, Callback callback) {
doAsync(() -> runCallback(loadTrack(name), callback));
}
public void loadAllTracks(Callback callback) {
doAsync(() -> runCallback(loadAllTracks(), callback));
}
public void saveTrack(Track track, Callback callback) {
doAsync(() -> runCallback(saveTrack(track), callback));
}
public void deleteTrack(Track track, Callback callback) {
doAsync(() -> runCallback(deleteTrack(track), callback));
}
public void saveUUIDData(String username, UUID uuid, Callback callback) {
doAsync(() -> runCallback(saveUUIDData(username, uuid), callback));
}

View File

@ -5,6 +5,7 @@ import com.google.gson.stream.JsonWriter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.io.*;
@ -20,6 +21,7 @@ public class FlatfileDatastore extends Datastore {
private final File pluginDir;
private File usersDir;
private File groupsDir;
private File tracksDir;
private File uuidData;
public FlatfileDatastore(LuckPermsPlugin plugin, File pluginDir) {
@ -107,6 +109,9 @@ public class FlatfileDatastore extends Datastore {
groupsDir = new File(data, "groups");
groupsDir.mkdir();
tracksDir = new File(data, "tracks");
tracksDir.mkdir();
uuidData = new File(data, "uuidcache.txt");
uuidData.createNewFile();
}
@ -365,6 +370,132 @@ public class FlatfileDatastore extends Datastore {
return true;
}
@Override
public boolean createAndLoadTrack(String name) {
Track track = plugin.getTrackManager().makeTrack(name);
List<String> groups = new ArrayList<>();
File trackFile = new File(tracksDir, name + ".json");
if (!trackFile.exists()) {
try {
trackFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return false;
}
boolean success = doWrite(trackFile, writer -> {
writer.beginObject();
writer.name("name").value(track.getName());
writer.name("groups");
writer.beginArray();
for (String s : track.getGroups()) {
writer.value(s);
}
writer.endArray();
writer.endObject();
return true;
});
if (!success) return false;
}
boolean success = doRead(trackFile, reader -> {
reader.beginObject();
reader.nextName(); // name record
reader.nextString(); // name
reader.nextName(); // groups record
reader.beginArray();
while (reader.hasNext()) {
groups.add(reader.nextString());
}
reader.endArray();
reader.endObject();
return true;
});
track.setGroups(groups);
if (success) plugin.getTrackManager().updateOrSetTrack(track);
return success;
}
@Override
public boolean loadTrack(String name) {
Track track = plugin.getTrackManager().makeTrack(name);
List<String> groups = new ArrayList<>();
File trackFile = new File(tracksDir, name + ".json");
if (!trackFile.exists()) {
return false;
}
boolean success = doRead(trackFile, reader -> {
reader.beginObject();
reader.nextName(); // name record
reader.nextString(); // name
reader.nextName(); // groups record
reader.beginArray();
while (reader.hasNext()) {
groups.add(reader.nextString());
}
reader.endArray();
reader.endObject();
return true;
});
track.setGroups(groups);
if (success) plugin.getTrackManager().updateOrSetTrack(track);
return success;
}
@Override
public boolean loadAllTracks() {
String[] fileNames = tracksDir.list((dir, name) -> name.endsWith(".json"));
if (fileNames == null) return false;
List<String> tracks = Arrays.stream(fileNames).map(s -> s.substring(0, s.length() - 5)).collect(Collectors.toList());
plugin.getTrackManager().unloadAll();
tracks.forEach(this::loadTrack);
return true;
}
@Override
public boolean saveTrack(Track track) {
File trackFile = new File(tracksDir, track.getName() + ".json");
if (!trackFile.exists()) {
try {
trackFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
boolean success = doWrite(trackFile, writer -> {
writer.beginObject();
writer.name("name").value(track.getName());
writer.name("groups");
writer.beginArray();
for (String s : track.getGroups()) {
writer.value(s);
}
writer.endArray();
writer.endObject();
return true;
});
return success;
}
@Override
public boolean deleteTrack(Track track) {
File trackFile = new File(tracksDir, track.getName() + ".json");
if (trackFile.exists()) {
trackFile.delete();
}
return true;
}
private Map<String, String> getUUIDCache() {
Map<String, String> cache = new HashMap<>();

View File

@ -13,6 +13,7 @@ public class MySQLDatastore extends SQLDatastore {
private static final String CREATETABLE_UUID = "CREATE TABLE IF NOT EXISTS `lp_uuid` (`name` VARCHAR(16) NOT NULL, `uuid` VARCHAR(36) NOT NULL, PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
private static final String CREATETABLE_USERS = "CREATE TABLE IF NOT EXISTS `lp_users` (`uuid` VARCHAR(36) NOT NULL, `name` VARCHAR(16) NOT NULL, `primary_group` VARCHAR(36) NOT NULL, `perms` TEXT NOT NULL, PRIMARY KEY (`uuid`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
private static final String CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
private final MySQLConfiguration configuration;
private HikariDataSource hikari;
@ -39,7 +40,7 @@ public class MySQLDatastore extends SQLDatastore {
hikari.addDataSourceProperty("user", username);
hikari.addDataSourceProperty("password", password);
if (!setupTables(CREATETABLE_UUID, CREATETABLE_USERS, CREATETABLE_GROUPS)) {
if (!setupTables(CREATETABLE_UUID, CREATETABLE_USERS, CREATETABLE_GROUPS, CREATETABLE_TRACKS)) {
plugin.getLogger().log(Level.SEVERE, "Error occurred whilst initialising the database. All connections are disallowed.");
shutdown();
} else {

View File

@ -8,6 +8,8 @@ import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.User;
import java.lang.reflect.Type;
@ -24,6 +26,7 @@ import java.util.UUID;
abstract class SQLDatastore extends Datastore {
private static final Type NM_TYPE = new TypeToken<Map<String, Boolean>>(){}.getType();
private static final Type T_TYPE = new TypeToken<List<String>>(){}.getType();
private static final String USER_INSERT = "INSERT INTO lp_users VALUES(?, ?, ?, ?)";
private static final String USER_SELECT = "SELECT * FROM lp_users WHERE uuid=?";
@ -35,6 +38,12 @@ abstract class SQLDatastore extends Datastore {
private static final String GROUP_UPDATE = "UPDATE lp_groups SET perms=? WHERE name=?";
private static final String GROUP_DELETE = "DELETE FROM lp_groups WHERE name=?";
private static final String TRACK_INSERT = "INSERT INTO lp_tracks VALUES(?, ?)";
private static final String TRACK_SELECT = "SELECT groups FROM lp_tracks WHERE name=?";
private static final String TRACK_SELECT_ALL = "SELECT * FROM lp_tracks";
private static final String TRACK_UPDATE = "UPDATE lp_tracks SET groups=? WHERE name=?";
private static final String TRACK_DELETE = "DELETE FROM lp_tracks WHERE name=?";
private static final String UUIDCACHE_INSERT = "INSERT INTO lp_uuid VALUES(?, ?)";
private static final String UUIDCACHE_SELECT = "SELECT uuid FROM lp_uuid WHERE name=?";
private static final String UUIDCACHE_UPDATE = "UPDATE lp_uuid SET uuid=? WHERE name=?";
@ -303,6 +312,111 @@ abstract class SQLDatastore extends Datastore {
return success;
}
@Override
public boolean createAndLoadTrack(String name) {
Track track = plugin.getTrackManager().makeTrack(name);
boolean success = runQuery(new QueryRS(TRACK_SELECT) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, track.getName());
}
@Override
boolean onResult(ResultSet resultSet) throws SQLException {
boolean success = true;
if (!resultSet.next()) {
success = runQuery(new QueryPS(TRACK_INSERT) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, track.getName());
preparedStatement.setString(2, gson.toJson(track.getGroups()));
}
});
} else {
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
}
return success;
}
});
if (success) plugin.getTrackManager().updateOrSetTrack(track);
return success;
}
@Override
public boolean loadTrack(String name) {
Track track = plugin.getTrackManager().makeTrack(name);
boolean success = runQuery(new QueryRS(TRACK_SELECT) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, name);
}
@Override
boolean onResult(ResultSet resultSet) throws SQLException {
if (resultSet.next()) {
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
return true;
}
return false;
}
});
if (success) plugin.getTrackManager().updateOrSetTrack(track);
return success;
}
@Override
public boolean loadAllTracks() {
List<Track> tracks = new ArrayList<>();
boolean success = runQuery(new QueryRS(TRACK_SELECT_ALL) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
}
@Override
boolean onResult(ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
Track track = plugin.getTrackManager().makeTrack(resultSet.getString("name"));
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
tracks.add(track);
}
return true;
}
});
if (success) {
TrackManager tm = plugin.getTrackManager();
tm.unloadAll();
tracks.forEach(tm::setTrack);
}
return success;
}
@Override
public boolean saveTrack(Track track) {
boolean success = runQuery(new QueryPS(TRACK_UPDATE) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, gson.toJson(track.getGroups()));
preparedStatement.setString(2, track.getName());
}
});
return success;
}
@Override
public boolean deleteTrack(Track track) {
boolean success = runQuery(new QueryPS(TRACK_DELETE) {
@Override
void onRun(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, track.getName());
}
});
return success;
}
@Override
public boolean saveUUIDData(String username, UUID uuid) {
boolean success = runQuery(new QueryRS(UUIDCACHE_SELECT) {

View File

@ -13,6 +13,7 @@ public class SQLiteDatastore extends SQLDatastore {
private static final String CREATETABLE_UUID = "CREATE TABLE IF NOT EXISTS `lp_uuid` (`name` VARCHAR(16) NOT NULL, `uuid` VARCHAR(36) NOT NULL, PRIMARY KEY (`name`));";
private static final String CREATETABLE_USERS = "CREATE TABLE IF NOT EXISTS `lp_users` (`uuid` VARCHAR(36) NOT NULL, `name` VARCHAR(16) NOT NULL, `primary_group` VARCHAR(36) NOT NULL, `perms` TEXT NOT NULL, PRIMARY KEY (`uuid`));";
private static final String CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`));";
private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`));";
private final File file;
private Connection connection = null;
@ -24,7 +25,7 @@ public class SQLiteDatastore extends SQLDatastore {
@Override
public void init() {
if (!setupTables(CREATETABLE_UUID, CREATETABLE_USERS, CREATETABLE_GROUPS)) {
if (!setupTables(CREATETABLE_UUID, CREATETABLE_USERS, CREATETABLE_GROUPS, CREATETABLE_TRACKS)) {
plugin.getLogger().log(Level.SEVERE, "Error occurred whilst initialising the database. All connections are disallowed.");
shutdown();
} else {

View File

@ -0,0 +1,4 @@
package me.lucko.luckperms.exceptions;
public class ObjectLacksException extends Exception {
}

View File

@ -1,4 +0,0 @@
package me.lucko.luckperms.exceptions;
public class ObjectLacksPermissionException extends Exception {
}

View File

@ -17,7 +17,6 @@ public class GroupManager {
public GroupManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
loadAllGroups();
}
/**

View File

@ -18,6 +18,9 @@ public class UpdateTask implements Runnable {
plugin.getDatastore().createAndLoadGroup(defaultGroup);
}
// Reload all of the tracks
plugin.getDatastore().loadAllTracks();
// Refresh all online users.
plugin.getUserManager().updateAllUsers();
}

View File

@ -0,0 +1,197 @@
package me.lucko.luckperms.tracks;
import lombok.Getter;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Track {
/**
* The name of the track
*/
@Getter
private final String name;
/**
* The groups within this track
*/
private List<String> groups = new ArrayList<>();
Track(String name) {
this.name = name;
}
/**
* Gets an ordered list of the groups on this track
* @return am ordered {@link List} of the groups on this track
*/
public List<String> getGroups() {
return Collections.unmodifiableList(groups);
}
public void setGroups(List<String> groups) {
this.groups.clear();
this.groups.addAll(groups);
}
/**
* Gets the number of groups on this track
* @return the number of groups on this track
*/
public int getSize() {
return groups.size();
}
/**
* Gets the next group on the track, after the one provided
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
public String getNext(Group current) throws ObjectLacksException {
return getNext(current.getName());
}
/**
* Gets the group before the group provided
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
public String getPrevious(Group current) throws ObjectLacksException {
return getPrevious(current.getName());
}
/**
* Gets the next group on the track, after the one provided
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
public String getNext(String current) throws ObjectLacksException {
assertContains(current);
if (groups.indexOf(current) == groups.size() - 1) {
return null;
}
return groups.get(groups.indexOf(current) + 1);
}
/**
* Gets the group before the group provided
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
public String getPrevious(String current) throws ObjectLacksException {
assertContains(current);
if (groups.indexOf(current) == 0) {
return null;
}
return groups.get(groups.indexOf(current) - 1);
}
/**
* Appends a group to the end of this track
* @param group the group to append
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
*/
public void appendGroup(Group group) throws ObjectAlreadyHasException {
assertNotContains(group);
groups.add(group.getName());
}
/**
* Inserts a group at a certain position on this track
* @param group the group to be inserted
* @param position the index position (a value of 0 inserts at the start)
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
*/
public void insertGroup(Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
assertNotContains(group);
groups.add(position, group.getName());
}
/**
* Removes a group from this track
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
*/
public void removeGroup(Group group) throws ObjectLacksException {
removeGroup(group.getName());
}
/**
* Removes a group from this track
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
*/
public void removeGroup(String group) throws ObjectLacksException {
assertContains(group);
groups.remove(group);
}
/**
* Checks if a group features on this track
* @param group the group to check
* @return true if the group is on this track
*/
public boolean containsGroup(Group group) {
return containsGroup(group.getName());
}
/**
* Checks if a group features on this track
* @param group the group to check
* @return true if the group is on this track
*/
public boolean containsGroup(String group) {
return groups.contains(group);
}
/**
* Clear all of the groups within this track
*/
public void clearGroups() {
groups.clear();
}
private void assertContains(Group g) throws ObjectLacksException {
if (!containsGroup(g)) {
throw new ObjectLacksException();
}
}
private void assertNotContains(Group g) throws ObjectAlreadyHasException {
if (containsGroup(g)) {
throw new ObjectAlreadyHasException();
}
}
private void assertContains(String g) throws ObjectLacksException {
if (!containsGroup(g)) {
throw new ObjectLacksException();
}
}
private void assertNotContains(String g) throws ObjectAlreadyHasException {
if (containsGroup(g)) {
throw new ObjectAlreadyHasException();
}
}
@Override
public String toString() {
return name;
}
}

View File

@ -0,0 +1,104 @@
package me.lucko.luckperms.tracks;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class TrackManager {
private final LuckPermsPlugin plugin;
/**
* A {@link Map} containing all loaded tracks
*/
@Getter
private final Map<String, Track> tracks = new ConcurrentHashMap<>();
public TrackManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
/**
* Get a track object by name
* @param name the name to search by
* @return a {@link Track} object if the track is loaded, else returns null
*/
public Track getTrack(String name) {
return tracks.get(name);
}
/**
* Returns a set of tracks that contain at least one of the groups from the Set provided
* @param group the group to filter by
* @return a set of tracks that the groups could be a member of
*/
public Set<Track> getApplicableTracks(String group) {
return tracks.values().stream().filter(t -> t.containsGroup(group)).collect(Collectors.toSet());
}
/**
* Add a track to the loaded tracks map
* @param track The track to add
*/
public void setTrack(Track track) {
tracks.put(track.getName(), track);
}
/**
* Updates (or sets if the track wasn't already loaded) a track in the tracks map
* @param track The track to update or set
*/
public void updateOrSetTrack(Track track) {
if (!isLoaded(track.getName())) {
// The track isn't already loaded
tracks.put(track.getName(), track);
} else {
tracks.get(track.getName()).setGroups(track.getGroups());
}
}
/**
* Check to see if a track is loaded or not
* @param name The name of the track
* @return true if the track is loaded
*/
public boolean isLoaded(String name) {
return tracks.containsKey(name);
}
/**
* Removes and unloads the track from the plugins internal storage
* @param track The track to unload
*/
public void unloadTrack(Track track) {
if (track != null) {
tracks.remove(track.getName());
}
}
/**
* Unloads all tracks from the manager
*/
public void unloadAll() {
tracks.clear();
}
/**
* Load all tracks from the datastore
*/
public void loadAllTracks() {
plugin.getDatastore().loadAllTracks(success -> {});
}
/**
* Makes a new track object
* @param name The name of the track
* @return a new {@link Track} object
*/
public Track makeTrack(String name) {
return new Track(name);
}
}

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import me.lucko.luckperms.utils.PermissionObject;
@ -96,9 +96,9 @@ public abstract class User extends PermissionObject {
/**
* Remove the user from a group
* @param group the group to remove the user from
* @throws ObjectLacksPermissionException if the user isn't a member of the group
* @throws ObjectLacksException if the user isn't a member of the group
*/
public void removeGroup(Group group) throws ObjectLacksPermissionException {
public void removeGroup(Group group) throws ObjectLacksException {
removeGroup(group, "global");
}
@ -106,9 +106,9 @@ public abstract class User extends PermissionObject {
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @throws ObjectLacksPermissionException if the user isn't a member of the group
* @throws ObjectLacksException if the user isn't a member of the group
*/
public void removeGroup(Group group, String server) throws ObjectLacksPermissionException {
public void removeGroup(Group group, String server) throws ObjectLacksException {
if (server == null) {
server = "global";
}
@ -214,12 +214,12 @@ public abstract class User extends PermissionObject {
groups.addAll(serverSpecificGroups.entrySet().stream()
.filter(Map.Entry::getValue)
.map(e -> Patterns.SERVER_SPLIT.split(e.getKey(), 2)[1])
.map(e -> Patterns.DOT_SPLIT.split(e.getKey(), 2)[1])
.collect(Collectors.toList())
);
groups.addAll(groupNodes.entrySet().stream()
.filter(Map.Entry::getValue)
.map(e -> Patterns.SERVER_SPLIT.split(e.getKey(), 2)[1])
.map(e -> Patterns.DOT_SPLIT.split(e.getKey(), 2)[1])
.collect(Collectors.toList())
);
return groups;

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksPermissionException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import java.util.ArrayList;
@ -126,12 +126,12 @@ public abstract class PermissionObject {
/**
* Unsets a permission for the object
* @param node The node to be unset
* @throws ObjectLacksPermissionException if the node wasn't already set
* @throws ObjectLacksException if the node wasn't already set
*/
public void unsetPermission(String node) throws ObjectLacksPermissionException {
public void unsetPermission(String node) throws ObjectLacksException {
if (node.startsWith("global/")) node = node.replace("global/", "");
if (!getNodes().containsKey(node)) {
throw new ObjectLacksPermissionException();
throw new ObjectLacksException();
}
getNodes().remove(node);
}
@ -140,9 +140,9 @@ public abstract class PermissionObject {
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @throws ObjectLacksPermissionException if the node wasn't already set
* @throws ObjectLacksException if the node wasn't already set
*/
public void unsetPermission(String node, String server) throws ObjectLacksPermissionException {
public void unsetPermission(String node, String server) throws ObjectLacksException {
unsetPermission(server + "/" + node);
}