Cleanup & multiple small fixes

This commit is contained in:
Luck 2016-07-21 14:15:14 +01:00
parent 1870893fe1
commit a413c0a50a
53 changed files with 452 additions and 371 deletions

View File

@ -7,66 +7,49 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
public class BukkitConfig implements LPConfiguration {
private final LPBukkitPlugin plugin;
class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
private YamlConfiguration configuration;
public BukkitConfig(LPBukkitPlugin plugin) {
this.plugin = plugin;
create();
BukkitConfig(LPBukkitPlugin plugin) {
super(plugin, "global", true, "sqlite");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private void create() {
File configFile = new File(plugin.getDataFolder(), "config.yml");
@Override
protected void init() {
File configFile = new File(getPlugin().getDataFolder(), "config.yml");
if (!configFile.exists()) {
configFile.getParentFile().mkdirs();
plugin.saveResource("config.yml", false);
getPlugin().saveResource("config.yml", false);
}
configuration = new YamlConfiguration();
try {
configuration.load(configFile);
} catch (InvalidConfigurationException | IOException e) {
e.printStackTrace();
}
}
@Override
public String getServer() {
return configuration.getString("server", "global");
protected void set(String path, Object value) {
configuration.set(path, value);
}
@Override
public int getSyncTime() {
return configuration.getInt("sql.sync-minutes", 3);
protected String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
public String getDefaultGroupNode() {
return "group." + configuration.getString("default-group", "default");
protected int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
public String getDefaultGroupName() {
return configuration.getString("default-group", "default");
}
@Override
public boolean getIncludeGlobalPerms() {
return configuration.getBoolean("include-global", true);
}
@Override
public String getDatabaseValue(String value) {
return configuration.getString("sql." + value);
}
@Override
public String getStorageMethod() {
return configuration.getString("storage-method", "sqlite");
protected boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
}

View File

@ -38,6 +38,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
@Override
public void onEnable() {
getLogger().info("Loading configuration...");
configuration = new BukkitConfig(this);
// register events
@ -45,14 +46,15 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
pm.registerEvents(new PlayerListener(this), this);
// register commands
getLogger().info("Registering commands...");
CommandManagerBukkit commandManager = new CommandManagerBukkit(this);
PluginCommand main = getServer().getPluginCommand("luckperms");
main.setExecutor(commandManager);
main.setTabCompleter(commandManager);
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
getLogger().info("Detecting storage method...");
final String storageMethod = configuration.getStorageMethod();
if (storageMethod.equalsIgnoreCase("mysql")) {
getLogger().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, new MySQLConfiguration(
@ -68,17 +70,20 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
getLogger().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(this, getDataFolder());
} else {
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
getLogger().severe("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
}
getLogger().info("Initialising datastore...");
datastore.init();
getLogger().info("Loading internal permission managers...");
userManager = new BukkitUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
trackManager = new TrackManager();
// Run update task to refresh any online users
getLogger().info("Scheduling Update Task to refresh any online users.");
runUpdateTask();
int mins = getConfiguration().getSyncTime();
@ -88,13 +93,20 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
// Provide vault support
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
VaultHook.hook(this);
getLogger().info("Registered Vault permission & chat hook.");
} else {
getLogger().info("Vault not found.");
getLogger().info("Attempting to hook into Vault...");
try {
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
VaultHook.hook(this);
getLogger().info("Registered Vault permission & chat hook.");
} else {
getLogger().info("Vault not found.");
}
} catch (Exception e) {
getLogger().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
getLogger().info("Successfully loaded.");
}
@Override

View File

@ -16,13 +16,14 @@ import org.bukkit.event.player.PlayerQuitEvent;
@AllArgsConstructor
public class PlayerListener implements Listener {
private static final String KICK_MESSAGE = Util.color(Message.PREFIX + "User data could not be loaded. Please contact an administrator.");
private final LPBukkitPlugin plugin;
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
Util.color(Message.PREFIX + "Error whilst validating login with the network. \nPlease contact an administrator."));
// Datastore is disabled, prevent players from joining the server
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, KICK_MESSAGE);
return;
}
plugin.getDatastore().loadOrCreateUser(e.getUniqueId(), e.getName());
@ -30,12 +31,11 @@ public class PlayerListener implements Listener {
@EventHandler
public void onPlayerLogin(PlayerLoginEvent e) {
Player player = e.getPlayer();
User user = plugin.getUserManager().getUser(player.getUniqueId());
final Player player = e.getPlayer();
final User user = plugin.getUserManager().getUser(player.getUniqueId());
if (user == null) {
e.disallow(PlayerLoginEvent.Result.KICK_OTHER,
Util.color(Message.PREFIX + "User data could not be loaded. Please contact an administrator."));
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, KICK_MESSAGE);
return;
}
@ -52,7 +52,7 @@ public class PlayerListener implements Listener {
// Save UUID data for the player
plugin.getDatastore().saveUUIDData(e.getPlayer().getName(), e.getPlayer().getUniqueId(), success -> {});
User user = plugin.getUserManager().getUser(e.getPlayer().getUniqueId());
final User user = plugin.getUserManager().getUser(e.getPlayer().getUniqueId());
if (user != null) {
// Refresh permissions again
user.refreshPermissions();
@ -62,10 +62,10 @@ public class PlayerListener implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
Player player = e.getPlayer();
final Player player = e.getPlayer();
// Unload the user from memory when they disconnect
User user = plugin.getUserManager().getUser(player.getUniqueId());
final User user = plugin.getUserManager().getUser(player.getUniqueId());
plugin.getUserManager().unloadUser(user);
}

View File

@ -3,7 +3,6 @@ package me.lucko.luckperms.users;
import lombok.Getter;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionAttachment;
@ -31,7 +30,7 @@ public class BukkitUser extends User {
@Override
public void refreshPermissions() {
plugin.doSync(() -> {
Player player = Bukkit.getPlayer(getUuid());
final Player player = plugin.getServer().getPlayer(getUuid());
if (player == null) return;
if (attachment == null) {

View File

@ -1,7 +1,6 @@
package me.lucko.luckperms.users;
import me.lucko.luckperms.LPBukkitPlugin;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
@ -22,7 +21,7 @@ public class BukkitUserManager extends UserManager {
BukkitUser u = (BukkitUser) user;
if (u.getAttachment() != null) {
Player player = Bukkit.getPlayer(u.getUuid());
Player player = plugin.getServer().getPlayer(u.getUuid());
if (player != null) {
player.removeAttachment(u.getAttachment());
@ -37,7 +36,7 @@ public class BukkitUserManager extends UserManager {
@Override
public void cleanupUser(User user) {
if (Bukkit.getPlayer(user.getUuid()) == null) {
if (plugin.getServer().getPlayer(user.getUuid()) == null) {
unloadUser(user);
}
}

View File

@ -10,30 +10,20 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
public class BungeeConfig implements LPConfiguration {
private final LPBungeePlugin plugin;
class BungeeConfig extends LPConfiguration<LPBungeePlugin> {
private Configuration configuration;
public BungeeConfig(LPBungeePlugin plugin) {
this.plugin = plugin;
reload();
}
private void reload() {
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(makeFile("config.yml"));
} catch (IOException e) {
e.printStackTrace();
}
BungeeConfig(LPBungeePlugin plugin) {
super(plugin, "bungee", false, "flatfile");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private File makeFile(String file) throws IOException {
File cfg = new File(plugin.getDataFolder(), file);
File cfg = new File(getPlugin().getDataFolder(), file);
if (!cfg.exists()) {
plugin.getDataFolder().mkdir();
try (InputStream is = plugin.getResourceAsStream(file)) {
getPlugin().getDataFolder().mkdir();
try (InputStream is = getPlugin().getResourceAsStream(file)) {
Files.copy(is, cfg.toPath());
}
}
@ -42,37 +32,31 @@ public class BungeeConfig implements LPConfiguration {
}
@Override
public String getServer() {
return configuration.getString("server", "bungee");
protected void init() {
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(makeFile("config.yml"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public int getSyncTime() {
return configuration.getInt("sql.sync-minutes", 3);
protected void set(String path, Object value) {
configuration.set(path, value);
}
@Override
public String getDefaultGroupNode() {
return "group." + configuration.getString("default-group", "default");
protected String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
public String getDefaultGroupName() {
return configuration.getString("default-group", "default");
protected int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
public boolean getIncludeGlobalPerms() {
return configuration.getBoolean("include-global", false);
}
@Override
public String getDatabaseValue(String value) {
return configuration.getString("sql." + value);
}
@Override
public String getStorageMethod() {
return configuration.getString("storage-method", "sqlite");
protected boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
}

View File

@ -33,19 +33,21 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override
public void onEnable() {
getLogger().info("Loading configuration...");
configuration = new BungeeConfig(this);
// register events
getProxy().getPluginManager().registerListener(this, new PlayerListener(this));
// register commands
getLogger().info("Registering commands...");
getProxy().getPluginManager().registerCommand(this, new MainCommand(new CommandManager(this)));
// disable the default Bungee /perms command so it gets handled by the Bukkit plugin
getProxy().getDisabledCommands().add("perms");
getLogger().info("Detecting storage method...");
final String storageMethod = configuration.getStorageMethod();
if (storageMethod.equalsIgnoreCase("mysql")) {
getLogger().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, new MySQLConfiguration(
@ -58,20 +60,28 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
getLogger().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(this, getDataFolder());
} else {
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using Flatfile as fallback.");
getLogger().severe("Storage method '" + storageMethod + "' was not recognised. Using Flatfile as fallback.");
datastore = new FlatfileDatastore(this, getDataFolder());
}
getLogger().info("Initialising datastore...");
datastore.init();
getLogger().info("Loading internal permission managers...");
userManager = new BungeeUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
trackManager = new TrackManager();
// Run update task to refresh any online users
getLogger().info("Scheduling Update Task to refresh any online users.");
runUpdateTask();
int mins = getConfiguration().getSyncTime();
if (mins > 0) {
getProxy().getScheduler().schedule(this, new UpdateTask(this), mins, mins, TimeUnit.MINUTES);
}
getLogger().info("Successfully loaded.");
}
@Override

View File

@ -16,7 +16,6 @@ class MainCommand extends Command implements TabExecutor {
public MainCommand(CommandManager manager) {
super("luckpermsbungee", null, "bperms", "lpb", "bpermissions", "bp", "bperm");
this.manager = manager;
}
@Override

View File

@ -17,7 +17,9 @@ import java.util.concurrent.TimeUnit;
@AllArgsConstructor
public class PlayerListener implements Listener {
private static final TextComponent WARN_MESSAGE = new TextComponent(Util.color(
Message.PREFIX + "Permissions data could not be loaded. Please contact an administrator.")
);
private final LPBungeePlugin plugin;
@EventHandler
@ -25,12 +27,13 @@ public class PlayerListener implements Listener {
final ProxiedPlayer player = e.getPlayer();
final WeakReference<ProxiedPlayer> p = new WeakReference<>(player);
// Create user async and at post login. We're not concerned if data couldn't be loaded, the player won't be kicked.
plugin.getDatastore().loadOrCreateUser(player.getUniqueId(), player.getName(), success -> {
if (!success) {
plugin.getProxy().getScheduler().schedule(plugin, () -> {
final ProxiedPlayer pl = p.get();
if (pl != null) {
pl.sendMessage(new TextComponent(Util.color(Message.PREFIX + "Permissions data could not be loaded. Please contact an administrator.")));
pl.sendMessage(WARN_MESSAGE);
}
}, 3, TimeUnit.SECONDS);
@ -48,10 +51,10 @@ public class PlayerListener implements Listener {
@EventHandler
public void onPlayerQuit(PlayerDisconnectEvent e) {
ProxiedPlayer player = e.getPlayer();
final ProxiedPlayer player = e.getPlayer();
// Unload the user from memory when they disconnect
User user = plugin.getUserManager().getUser(player.getUniqueId());
final User user = plugin.getUserManager().getUser(player.getUniqueId());
plugin.getUserManager().unloadUser(user);
}
}

View File

@ -147,7 +147,8 @@ public class CommandManager {
return mains.stream().map(MainCommand::getName).map(String::toLowerCase).collect(Collectors.toList());
}
return mains.stream().map(MainCommand::getName).map(String::toLowerCase).filter(s -> s.startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
return mains.stream().map(MainCommand::getName).map(String::toLowerCase)
.filter(s -> s.startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
Optional<MainCommand> o = mains.stream().filter(m -> m.getName().equalsIgnoreCase(args.get(0))).limit(1).findAny();

View File

@ -1,5 +1,8 @@
package me.lucko.luckperms.commands;
/**
* Wrapper class to represent a CommandSender in Bukkit/Bungee within the luckperms-common command implementations.
*/
public interface Sender {
void sendMessage(String s);

View File

@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.users.User;
import java.util.ArrayList;
import java.util.Arrays;
@ -11,6 +12,13 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Abstract SubCommand class
* Doesn't declare any abstract onCommand methods, as sub classes declare their own with parameters unique to the sub command type.
* For example, see: {@link me.lucko.luckperms.commands.user.UserSubCommand#execute(LuckPermsPlugin, Sender, User, List, String)}
*
* SubCommand #execute methods are always called from the {@link MainCommand} class related to them, so abstraction is not needed.
*/
@Getter
@AllArgsConstructor
public abstract class SubCommand {
@ -19,6 +27,25 @@ public abstract class SubCommand {
private final String usage;
private final Permission permission;
public abstract boolean isArgLengthInvalid(int argLength);
public boolean isAuthorized(Sender sender) {
return permission.isAuthorized(sender);
}
public void sendUsage(Sender sender, String label) {
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
}
/**
* Returns a list of suggestions, which are empty by default. Sub classes that give tab complete suggestions override
* this method to give their own list.
*/
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
}
/* Utility methods used by #onTabComplete implementations in sub classes */
protected static List<String> getGroupTabComplete(List<String> args, LuckPermsPlugin plugin) {
return getTabComplete(new ArrayList<>(plugin.getGroupManager().getGroups().keySet()), args);
}
@ -27,6 +54,14 @@ public abstract class SubCommand {
return getTabComplete(new ArrayList<>(plugin.getTrackManager().getTracks().keySet()), args);
}
protected static List<String> getBoolTabComplete(List<String> args) {
if (args.size() == 2) {
return Arrays.asList("true", "false");
} else {
return Collections.emptyList();
}
}
private static List<String> getTabComplete(List<String> options, List<String> args) {
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
@ -38,26 +73,4 @@ public abstract class SubCommand {
return Collections.emptyList();
}
protected static List<String> getBoolTabComplete(List<String> args) {
if (args.size() == 2) {
return Arrays.asList("true", "false");
} else {
return Collections.emptyList();
}
}
public boolean isAuthorized(Sender sender) {
return permission.isAuthorized(sender);
}
public void sendUsage(Sender sender, String label) {
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
}
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
}
public abstract boolean isArgLengthInvalid(int argLength);
}

View File

@ -1,5 +1,7 @@
package me.lucko.luckperms.commands;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.utils.DateUtil;
@ -7,10 +9,9 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Util {
private Util() {}
public static void sendPluginMessage(Sender sender, String message) {
sender.sendMessage(color(Message.PREFIX + message));
}

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.Collections;
@ -32,6 +33,11 @@ public class DeleteGroup extends MainCommand {
return;
}
if (Patterns.NON_ALPHA_NUMERIC.matcher(groupName).find()) {
Message.GROUP_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_DOES_NOT_EXIST.send(sender);

View File

@ -6,6 +6,7 @@ import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.List;
@ -51,6 +52,12 @@ public class GroupMainCommand extends MainCommand {
}
final String groupName = args.get(0).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(groupName).find()) {
Message.GROUP_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_NOT_FOUND.send(sender);

View File

@ -4,8 +4,10 @@ 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.utils.Patterns;
import java.util.List;
@ -18,6 +20,11 @@ public class GroupHasPerm extends GroupSubCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() == 2) {
if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1).toLowerCase()));
} else {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, "global"));

View File

@ -4,8 +4,10 @@ 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.utils.Patterns;
import java.util.List;
@ -18,6 +20,11 @@ public class GroupInheritsPerm extends GroupSubCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() == 2) {
if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1).toLowerCase()));
} else {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true));

View File

@ -7,6 +7,7 @@ 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.utils.Patterns;
import java.util.List;
@ -32,6 +33,11 @@ public class GroupSetInherit extends GroupSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.setPermission("group." + groupName, true, server);
Message.GROUP_SETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
} else {

View File

@ -42,6 +42,11 @@ public class GroupSetPermission extends GroupSubCommand {
try {
if (args.size() == 3) {
final String server = args.get(2).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server);
} else {

View File

@ -8,6 +8,7 @@ import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.DateUtil;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -46,6 +47,11 @@ public class GroupSetTempInherit extends GroupSubCommand {
try {
if (args.size() == 3) {
final String server = args.get(2).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.setPermission("group." + groupName, true, server, duration);
Message.GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server,
DateUtil.formatDateDiff(duration));

View File

@ -56,6 +56,11 @@ public class GroupSetTempPermission extends GroupSubCommand {
try {
if (args.size() == 4) {
final String server = args.get(3).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.setPermission(node, b, server, duration);
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server, DateUtil.formatDateDiff(duration));
} else {

View File

@ -34,6 +34,11 @@ public class GroupUnSetPermission extends GroupSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server);
} else {

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -28,6 +29,11 @@ public class GroupUnsetInherit extends GroupSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.unsetPermission("group." + groupName, server);
Message.GROUP_UNSETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
} else {

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -28,6 +29,11 @@ public class GroupUnsetTempInherit extends GroupSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.unsetPermission("group." + groupName, server, true);
Message.GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
} else {

View File

@ -34,6 +34,11 @@ public class GroupUnsetTempPermission extends GroupSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
group.unsetPermission(node, server);
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server, true);
} else {

View File

@ -6,6 +6,7 @@ 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.LPConfiguration;
import java.util.Collections;
import java.util.List;
@ -17,7 +18,9 @@ public class InfoCommand extends MainCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.INFO.send(sender, plugin.getVersion(), plugin.getDatastore().getName());
final LPConfiguration c = plugin.getConfiguration();
Message.INFO.send(sender, plugin.getVersion(), plugin.getDatastore().getName(), c.getServer(),
c.getDefaultGroupName(), c.getSyncTime(), c.getIncludeGlobalPerms());
}
@Override

View File

@ -7,6 +7,7 @@ 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 me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.Collections;
@ -27,6 +28,11 @@ public class DeleteTrack extends MainCommand {
String trackName = args.get(0).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(trackName).find()) {
Message.TRACK_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_DOES_NOT_EXIST.send(sender);

View File

@ -6,6 +6,7 @@ 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 me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.List;
@ -51,6 +52,12 @@ public class TrackMainCommand extends MainCommand {
}
final String trackName = args.get(0).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(trackName).find()) {
Message.TRACK_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadTrack(trackName, success -> {
if (!success) {
Message.TRACK_NOT_FOUND.send(sender);

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.ArrayList;
import java.util.List;
@ -54,6 +55,12 @@ public class UserMainCommand extends MainCommand {
}
final String user = args.get(0);
if (Patterns.NON_USERNAME.matcher(user).find()) {
Message.USER_INVALID_ENTRY.send(sender, user);
return;
}
UUID u = Util.parseUuid(user);
if (u != null) {
runSub(plugin, sender, u, sub, strippedArgs, label);

View File

@ -8,6 +8,7 @@ import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -38,6 +39,11 @@ public class UserAddGroup extends UserSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.addGroup(group, server);
Message.USER_ADDGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server);
} else {

View File

@ -9,6 +9,7 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.DateUtil;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -53,6 +54,11 @@ public class UserAddTempGroup extends UserSubCommand {
try {
if (args.size() == 3) {
final String server = args.get(2).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.addGroup(group, server, duration);
Message.USER_ADDTEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server,
DateUtil.formatDateDiff(duration));

View File

@ -4,8 +4,10 @@ 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.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -18,6 +20,11 @@ public class UserHasPerm extends UserSubCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
if (args.size() >= 2) {
if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
Util.sendBoolean(sender, args.get(0), user.hasPermission(args.get(0), true, args.get(1)));
} else {
Util.sendBoolean(sender, args.get(0), user.hasPermission(args.get(0), true, "global"));

View File

@ -4,8 +4,10 @@ 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.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -18,6 +20,11 @@ public class UserInheritsPerm extends UserSubCommand {
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) {
if (args.size() >= 2) {
if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
Util.sendBoolean(sender, args.get(0), user.inheritsPermission(args.get(0), true, args.get(1)));
} else {
Util.sendBoolean(sender, args.get(0), user.inheritsPermission(args.get(0), true));

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -33,6 +34,11 @@ public class UserRemoveGroup extends UserSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.unsetPermission("group." + groupName, server);
Message.USER_REMOVEGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server);
} else {

View File

@ -7,6 +7,7 @@ import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
@ -27,6 +28,11 @@ public class UserRemoveTempGroup extends UserSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.unsetPermission("group." + groupName, server, true);
Message.USER_REMOVETEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server);
} else {

View File

@ -42,6 +42,11 @@ public class UserSetPermission extends UserSubCommand {
try {
if (args.size() == 3) {
final String server = args.get(2).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, user.getName(), server);
} else {

View File

@ -56,6 +56,11 @@ public class UserSetTempPermission extends UserSubCommand {
try {
if (args.size() == 4) {
final String server = args.get(3).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.setPermission(node, b, server, duration);
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, user.getName(), server, DateUtil.formatDateDiff(duration));
} else {

View File

@ -34,6 +34,11 @@ public class UserUnSetPermission extends UserSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, user.getName(), server);
} else {

View File

@ -34,6 +34,11 @@ public class UserUnsetTempPermission extends UserSubCommand {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) {
Message.SERVER_INVALID_ENTRY.send(sender);
return;
}
user.unsetPermission(node, server, true);
Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, user.getName(), server);
} else {

View File

@ -52,9 +52,11 @@ public enum Message {
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),
GROUP_INVALID_ENTRY("Group names can only contain alphanumeric characters.", true),
TRACK_INVALID_ENTRY("Track names can only contain alphanumeric charcters.", true),
TRACK_INVALID_ENTRY("Track names can only contain alphanumeric characters.", true),
SERVER_INVALID_ENTRY("Server names can only contain alphanumeric characters.", true),
/**
@ -93,7 +95,11 @@ public enum Message {
INFO(
PREFIX + "&6Running &bLuckPerms %s&6." + "\n" +
PREFIX + "&eAuthor: &6Luck" + "\n" +
PREFIX + "&eStorage Method: &6%s",
PREFIX + "&eStorage Method: &6%s" + "\n" +
PREFIX + "&eServer Name: &6%s" + "\n" +
PREFIX + "&eDefault Group: &6%s" + "\n" +
PREFIX + "&eSync Interval: &6%s minutes" + "\n" +
PREFIX + "&eInclude Global Perms: &6%s",
false
),
DEBUG(

View File

@ -1,6 +1,8 @@
package me.lucko.luckperms.data;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.groups.Group;
@ -9,6 +11,7 @@ import me.lucko.luckperms.users.User;
import java.util.UUID;
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class Datastore {
protected final LuckPermsPlugin plugin;
@ -17,13 +20,7 @@ public abstract class Datastore {
@Getter
@Setter
private boolean acceptingLogins;
protected Datastore(LuckPermsPlugin plugin, String name) {
this.plugin = plugin;
this.name = name;
this.acceptingLogins = false;
}
private boolean acceptingLogins = false;
/**
* Execute a runnable asynchronously

View File

@ -2,6 +2,7 @@ package me.lucko.luckperms.data.methods;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import lombok.Cleanup;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.groups.Group;
@ -31,61 +32,32 @@ public class FlatfileDatastore extends Datastore {
private boolean doWrite(File file, WriteOperation writeOperation) {
boolean success = false;
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
JsonWriter jsonWriter = null;
try {
fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
jsonWriter = new JsonWriter(bufferedWriter);
@Cleanup FileWriter fileWriter = new FileWriter(file);
@Cleanup BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
@Cleanup JsonWriter jsonWriter = new JsonWriter(bufferedWriter);
jsonWriter.setIndent(" ");
success = writeOperation.onRun(jsonWriter);
jsonWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
close(jsonWriter);
close(bufferedWriter);
close(fileWriter);
}
return success;
}
private boolean doRead(File file, ReadOperation readOperation) {
boolean success = false;
FileReader fileReader = null;
BufferedReader bufferedReader = null;
JsonReader jsonReader = null;
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
jsonReader = new JsonReader(bufferedReader);
@Cleanup FileReader fileReader = new FileReader(file);
@Cleanup BufferedReader bufferedReader = new BufferedReader(fileReader);
@Cleanup JsonReader jsonReader = new JsonReader(bufferedReader);
success = readOperation.onRun(jsonReader);
} catch (IOException e) {
e.printStackTrace();
} finally {
close(jsonReader);
close(bufferedReader);
close(fileReader);
}
return success;
}
private static void close(AutoCloseable closeable) {
if (closeable == null) return;
try {
closeable.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void init() {
try {
@ -499,12 +471,9 @@ public class FlatfileDatastore extends Datastore {
private Map<String, String> getUUIDCache() {
Map<String, String> cache = new HashMap<>();
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try {
fileReader = new FileReader(uuidData);
bufferedReader = new BufferedReader(fileReader);
@Cleanup FileReader fileReader = new FileReader(uuidData);
@Cleanup BufferedReader bufferedReader = new BufferedReader(fileReader);
Properties props = new Properties();
props.load(bufferedReader);
@ -514,21 +483,14 @@ public class FlatfileDatastore extends Datastore {
} catch (IOException e) {
e.printStackTrace();
} finally {
close(bufferedReader);
close(fileReader);
}
return cache;
}
private void saveUUIDCache(Map<String, String> cache) {
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter(uuidData);
bufferedWriter = new BufferedWriter(fileWriter);
@Cleanup FileWriter fileWriter = new FileWriter(uuidData);
@Cleanup BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
Properties properties = new Properties();
properties.putAll(cache);
@ -536,9 +498,6 @@ public class FlatfileDatastore extends Datastore {
} catch (IOException e) {
e.printStackTrace();
} finally {
close(bufferedWriter);
close(fileWriter);
}
}

View File

@ -3,6 +3,7 @@ package me.lucko.luckperms.data.methods;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.AllArgsConstructor;
import lombok.Cleanup;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.data.Datastore;
@ -57,66 +58,40 @@ abstract class SQLDatastore extends Datastore {
abstract Connection getConnection() throws SQLException;
private static void close(AutoCloseable closeable) {
if (closeable == null) return;
try {
closeable.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean runQuery(QueryPS queryPS) {
boolean success = false;
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
@Cleanup Connection connection = getConnection();
if (connection == null) {
throw new IllegalStateException("SQL connection is null");
}
preparedStatement = connection.prepareStatement(queryPS.getQuery());
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(queryPS.getQuery());
queryPS.onRun(preparedStatement);
preparedStatement.execute();
success = true;
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(preparedStatement);
close(connection);
}
return success;
}
private boolean runQuery(QueryRS queryRS) {
boolean success = false;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
@Cleanup Connection connection = getConnection();
if (connection == null) {
throw new IllegalStateException("SQL connection is null");
}
preparedStatement = connection.prepareStatement(queryRS.getQuery());
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(queryRS.getQuery());
queryRS.onRun(preparedStatement);
preparedStatement.execute();
resultSet = preparedStatement.executeQuery();
@Cleanup ResultSet resultSet = preparedStatement.executeQuery();
success = queryRS.onResult(resultSet);
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(resultSet);
close(preparedStatement);
close(connection);
}
return success;
}

View File

@ -1,9 +1,13 @@
package me.lucko.luckperms.groups;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.utils.PermissionObject;
@ToString(of = {"name"})
@EqualsAndHashCode(of = {"name"}, callSuper = false)
public class Group extends PermissionObject {
/**
@ -13,7 +17,7 @@ public class Group extends PermissionObject {
private final String name;
Group(String name, LuckPermsPlugin plugin) {
super(plugin, name);
super(name, plugin);
this.name = name;
}
@ -23,9 +27,4 @@ public class Group extends PermissionObject {
public void clearNodes() {
getNodes().clear();
}
@Override
public String toString() {
return getName();
}
}

View File

@ -1,11 +1,13 @@
package me.lucko.luckperms.groups;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.LuckPermsPlugin;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class GroupManager {
private final LuckPermsPlugin plugin;
@ -15,10 +17,6 @@ public class GroupManager {
@Getter
private final Map<String, Group> groups = new ConcurrentHashMap<>();
public GroupManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
/**
* Get a group object by name
* @param name The name to search by
@ -75,19 +73,6 @@ public class GroupManager {
groups.clear();
}
/**
* Load all groups from the datastore
*/
public void loadAllGroups() {
plugin.getDatastore().loadAllGroups(success -> {
String defaultGroup = plugin.getConfiguration().getDefaultGroupName();
if (!groups.keySet().contains(defaultGroup)) {
plugin.getDatastore().createAndLoadGroup(defaultGroup, success1 -> {});
}
});
}
/**
* Makes a new group object
* @param name The name of the group

View File

@ -1,6 +1,9 @@
package me.lucko.luckperms.tracks;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
@ -9,6 +12,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ToString(of = {"name"})
@EqualsAndHashCode(of = {"name"}, callSuper = false)
@RequiredArgsConstructor
public class Track {
/**
@ -20,11 +26,7 @@ public class Track {
/**
* The groups within this track
*/
private List<String> groups = new ArrayList<>();
Track(String name) {
this.name = name;
}
private List<String> groups = Collections.synchronizedList(new ArrayList<>());
/**
* Gets an ordered list of the groups on this track
@ -165,12 +167,6 @@ public class Track {
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();
@ -182,16 +178,4 @@ public class Track {
throw new ObjectLacksException();
}
}
private void assertNotContains(String g) throws ObjectAlreadyHasException {
if (containsGroup(g)) {
throw new ObjectAlreadyHasException();
}
}
@Override
public String toString() {
return name;
}
}

View File

@ -1,7 +1,6 @@
package me.lucko.luckperms.tracks;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import java.util.Map;
import java.util.Set;
@ -9,7 +8,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class TrackManager {
private final LuckPermsPlugin plugin;
/**
* A {@link Map} containing all loaded tracks
@ -17,10 +15,6 @@ public class TrackManager {
@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
@ -86,13 +80,6 @@ public class TrackManager {
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

View File

@ -1,7 +1,9 @@
package me.lucko.luckperms.users;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
@ -12,6 +14,8 @@ import me.lucko.luckperms.utils.PermissionObject;
import java.util.*;
import java.util.stream.Collectors;
@ToString(of = {"uuid"})
@EqualsAndHashCode(of = {"uuid"}, callSuper = false)
public abstract class User extends PermissionObject {
/**
@ -35,13 +39,13 @@ public abstract class User extends PermissionObject {
private String primaryGroup = null;
User(UUID uuid, LuckPermsPlugin plugin) {
super(plugin, uuid.toString());
super(uuid.toString(), plugin);
this.uuid = uuid;
this.name = null;
}
User(UUID uuid, String name, LuckPermsPlugin plugin) {
super(plugin, uuid.toString());
super(uuid.toString(), plugin);
this.uuid = uuid;
this.name = name;
}
@ -193,7 +197,8 @@ public abstract class User extends PermissionObject {
}
/**
* Get a {@link List} of the groups the user is a member of on a specific server with the option to include global groups or all groups
* Get a {@link List} of the groups the user is a member of on a specific server with the option to include global
* groups or all groups
* @param server Which server to check on
* @param excludedGroups groups to exclude (prevents circular inheritance issues)
* @param includeGlobal Whether to include global groups
@ -274,9 +279,4 @@ public abstract class User extends PermissionObject {
);
return groups;
}
@Override
public String toString() {
return getUuid().toString();
}
}

View File

@ -1,6 +1,7 @@
package me.lucko.luckperms.users;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
@ -10,6 +11,7 @@ import java.util.NoSuchElementException;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public abstract class UserManager {
/**
@ -23,10 +25,6 @@ public abstract class UserManager {
*/
private final LuckPermsPlugin plugin;
public UserManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
/**
* Get a user object by UUID
* @param uuid The uuid to search by

View File

@ -1,5 +1,8 @@
package me.lucko.luckperms.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
@ -10,12 +13,11 @@ import java.util.regex.Pattern;
* https://github.com/drtshock/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java
* https://github.com/essentials/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtil {
private static final Pattern TIME_PATTERN = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
private static final int MAX_YEARS = 100000;
private DateUtil() {}
public static boolean shouldExpire(long unixTime) {
return unixTime < (System.currentTimeMillis() / 1000);
}

View File

@ -1,13 +1,71 @@
package me.lucko.luckperms.utils;
public interface LPConfiguration {
import lombok.AccessLevel;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
String getServer();
int getSyncTime();
String getDefaultGroupNode();
String getDefaultGroupName();
boolean getIncludeGlobalPerms();
String getDatabaseValue(String value);
String getStorageMethod();
public abstract class LPConfiguration<T extends LuckPermsPlugin> {
@Getter(AccessLevel.PROTECTED)
private final T plugin;
private final String defaultServerName;
private final boolean defaultIncludeGlobal;
private final String defaultStorage;
public LPConfiguration(T plugin, String defaultServerName, boolean defaultIncludeGlobal, String defaultStorage) {
this.plugin = plugin;
this.defaultServerName = defaultServerName;
this.defaultIncludeGlobal = defaultIncludeGlobal;
this.defaultStorage = defaultStorage;
init();
if (Patterns.NON_ALPHA_NUMERIC.matcher(getServer()).find()) {
plugin.getLogger().severe("Server name defined in config.yml contains invalid characters. Server names can " +
"only contain alphanumeric characters.\nDefined server name '" + getServer() + "' will be replaced with '" +
defaultServerName + "' (the default)");
set("server", defaultServerName);
}
if (Patterns.NON_ALPHA_NUMERIC.matcher(getDefaultGroupName()).find()) {
plugin.getLogger().severe("Default group defined in config.yml contains invalid characters. Group names can " +
"only contain alphanumeric characters.\nDefined default group name '" + getDefaultGroupName() +
"' will be replaced with 'default' (the default)");
set("default-group", "default");
}
}
protected abstract void init();
protected abstract void set(String path, Object value);
protected abstract String getString(String path, String def);
protected abstract int getInt(String path, int def);
protected abstract boolean getBoolean(String path, boolean def);
public String getServer() {
return getString("server", defaultServerName);
}
public int getSyncTime() {
return getInt("sql.sync-minutes", 3);
}
public String getDefaultGroupNode() {
return "group." + getDefaultGroupName();
}
public String getDefaultGroupName() {
return getString("default-group", "default");
}
public boolean getIncludeGlobalPerms() {
return getBoolean("include-global", defaultIncludeGlobal);
}
public String getDatabaseValue(String value) {
return getString("sql." + value, null);
}
public String getStorageMethod() {
return getString("storage-method", defaultStorage);
}
}

View File

@ -1,15 +1,17 @@
package me.lucko.luckperms.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.regex.Pattern;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Patterns {
public static final Pattern SERVER_SPLIT = Pattern.compile("\\/");
public static final Pattern TEMP_SPLIT = Pattern.compile("\\$");
public static final Pattern DOT_SPLIT = Pattern.compile("\\.");
public static final Pattern GROUP_MATCH = Pattern.compile("group\\..*");
public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[^A-Za-z0-9]");
private Patterns() {}
public static final Pattern NON_USERNAME = Pattern.compile("[^A-Za-z0-9_]");
}

View File

@ -1,52 +1,46 @@
package me.lucko.luckperms.utils;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* Represents an object that can hold permissions
* For example a User or a Group
*/
@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class PermissionObject {
/**
* The UUID of the user / name of the group.
* Used to prevent circular inheritance issues
*/
@Getter
private final String objectName;
/**
* Reference to the main plugin instance
*/
@Getter(AccessLevel.PROTECTED)
private final LuckPermsPlugin plugin;
/**
* If false, only permissions specific to the server are applied
*/
@Setter
private boolean includeGlobalPermissions;
/**
* The user/group's permissions
*/
private Map<String, Boolean> nodes = new HashMap<>();
protected PermissionObject(LuckPermsPlugin plugin, String objectName) {
this.objectName = objectName;
this.plugin = plugin;
this.includeGlobalPermissions = plugin.getConfiguration().getIncludeGlobalPerms();
}
@Getter
private Map<String, Boolean> nodes = new ConcurrentHashMap<>();
public void setNodes(Map<String, Boolean> nodes) {
this.nodes = nodes;
this.nodes.clear();
this.nodes.putAll(nodes);
auditTemporaryPermissions();
}
@ -81,7 +75,7 @@ public abstract class PermissionObject {
*/
public boolean hasPermission(String node, boolean b) {
if (node.startsWith("global/")) node = node.replace("global/", "");
return hasPermission(getNodes(), node, b);
return hasPermission(this.nodes, node, b);
}
/**
@ -156,7 +150,7 @@ public abstract class PermissionObject {
if (hasPermission(node, value)) {
throw new ObjectAlreadyHasException();
}
getNodes().put(node, value);
this.nodes.put(node, value);
}
/**
@ -201,26 +195,21 @@ public abstract class PermissionObject {
*/
public void unsetPermission(String node, boolean temporary) throws ObjectLacksException {
if (node.startsWith("global/")) node = node.replace("global/", "");
String match = null;
final String fNode = node;
Optional<String> match = Optional.empty();
if (!temporary) {
if (getNodes().containsKey(node)) {
match = node;
}
if (temporary) {
match = this.nodes.keySet().stream()
.filter(n -> n.contains("$")).filter(n -> Patterns.TEMP_SPLIT.split(n)[0].equalsIgnoreCase(fNode))
.findFirst();
} else {
for (String n : getNodes().keySet()) {
if (n.contains("$")) {
String[] parts = Patterns.TEMP_SPLIT.split(n);
if (parts[0].equalsIgnoreCase(node)) {
match = n;
break;
}
}
if (this.nodes.containsKey(fNode)) {
match = Optional.of(fNode);
}
}
if (match != null) {
getNodes().remove(match);
if (match.isPresent()) {
this.nodes.remove(match.get());
} else {
throw new ObjectLacksException();
}
@ -263,7 +252,7 @@ public abstract class PermissionObject {
* @return a {@link Map} of the permissions
*/
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
return getPermissions(server, excludedGroups, includeGlobalPermissions);
return getPermissions(server, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms());
}
/**
@ -271,19 +260,12 @@ public abstract class PermissionObject {
* @return a map of temporary nodes
*/
public Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes() {
Map<Map.Entry<String, Boolean>, Long> temps = new HashMap<>();
for (Map.Entry<String, Boolean> e : getNodes().entrySet()) {
if (!e.getKey().contains("$")) {
continue;
}
String[] parts = Patterns.TEMP_SPLIT.split(e.getKey());
return this.nodes.entrySet().stream().filter(e -> e.getKey().contains("$")).map(e -> {
final String[] parts = Patterns.TEMP_SPLIT.split(e.getKey());
final long expiry = Long.parseLong(parts[1]);
temps.put(new AbstractMap.SimpleEntry<>(parts[0], e.getValue()), expiry);
}
return new AbstractMap.SimpleEntry<Map.Entry<String, Boolean>, Long>(new AbstractMap.SimpleEntry<>(parts[0], e.getValue()), expiry);
return temps;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
/**
@ -291,37 +273,18 @@ public abstract class PermissionObject {
* @return a map of permanent nodes
*/
public Map<String, Boolean> getPermanentNodes() {
Map<String, Boolean> permas = new HashMap<>();
for (Map.Entry<String, Boolean> e : getNodes().entrySet()) {
if (e.getKey().contains("$")) {
continue;
}
permas.put(e.getKey(), e.getValue());
}
return permas;
return this.nodes.entrySet().stream().filter(e -> !e.getKey().contains("$"))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
/**
* Removes temporary permissions that have expired
* @return true if permissions had expired and had to be removed
*/
public boolean auditTemporaryPermissions() {
Set<String> toRemove = getNodes().keySet().stream()
public void auditTemporaryPermissions() {
this.nodes.keySet().stream()
.filter(s -> s.contains("$"))
.filter(s -> DateUtil.shouldExpire(Long.parseLong(Patterns.TEMP_SPLIT.split(s)[1])))
.collect(Collectors.toSet());
toRemove.forEach(s -> getNodes().remove(s));
return !toRemove.isEmpty();
}
private String stripTime(String s) {
if (s.contains("$")) {
return Patterns.TEMP_SPLIT.split(s)[0];
}
return s;
.forEach(s -> this.nodes.remove(s));
}
protected Map<String, Boolean> convertTemporaryPerms() {
@ -330,7 +293,7 @@ public abstract class PermissionObject {
Map<String, Boolean> nodes = new HashMap<>();
Map<String, Boolean> tempNodes = new HashMap<>();
for (Map.Entry<String, Boolean> e : getNodes().entrySet()) {
for (Map.Entry<String, Boolean> e : this.nodes.entrySet()) {
if (e.getKey().contains("$")) {
tempNodes.put(e.getKey(), e.getValue());
} else {
@ -469,4 +432,11 @@ public abstract class PermissionObject {
return perms;
}
private static String stripTime(String s) {
if (s.contains("$")) {
return Patterns.TEMP_SPLIT.split(s)[0];
}
return s;
}
}