Added basic permission management support.

master
James T. Martin 2020-11-22 21:02:31 -08:00
parent 9b10220d74
commit 261dc583df
Signed by: james
GPG Key ID: 4B7F3DA9351E577C
9 changed files with 217 additions and 5 deletions

View File

@ -4,6 +4,7 @@ import me.jamestmartin.wasteland.chat.ChatConfig;
import me.jamestmartin.wasteland.kills.KillsConfig;
import me.jamestmartin.wasteland.kit.KitConfig;
import me.jamestmartin.wasteland.manual.ManualConfig;
import me.jamestmartin.wasteland.permissions.PermissionsConfig;
import me.jamestmartin.wasteland.ranks.AllRanks;
import me.jamestmartin.wasteland.spawns.SpawnsConfig;
@ -15,6 +16,7 @@ public class WastelandConfig {
private final SpawnsConfig spawnsConfig;
private final KitConfig kitConfig;
private final ManualConfig manualConfig;
private final PermissionsConfig permissionsConfig;
public WastelandConfig(
String databaseFilename,
@ -23,7 +25,8 @@ public class WastelandConfig {
AllRanks ranks,
SpawnsConfig spawnsConfig,
KitConfig kitConfig,
ManualConfig manualConfig) {
ManualConfig manualConfig,
PermissionsConfig permissionsConfig) {
this.databaseFilename = databaseFilename;
this.chatConfig = chatConfig;
this.killsConfig = killsConfig;
@ -31,6 +34,7 @@ public class WastelandConfig {
this.spawnsConfig = spawnsConfig;
this.kitConfig = kitConfig;
this.manualConfig = manualConfig;
this.permissionsConfig = permissionsConfig;
}
public String getDatabaseFilename() {
@ -60,4 +64,8 @@ public class WastelandConfig {
public ManualConfig getManualConfig() {
return manualConfig;
}
public PermissionsConfig getPermissionsConfig() {
return permissionsConfig;
}
}

View File

@ -9,6 +9,7 @@ import me.jamestmartin.wasteland.chat.ChatState;
import me.jamestmartin.wasteland.kills.KillsState;
import me.jamestmartin.wasteland.kit.KitState;
import me.jamestmartin.wasteland.manual.ManualState;
import me.jamestmartin.wasteland.permissions.PermissionsState;
import me.jamestmartin.wasteland.ranks.PermissionsPlayerRankProvider;
import me.jamestmartin.wasteland.ranks.PlayerRankProvider;
import me.jamestmartin.wasteland.ranks.RanksState;
@ -26,6 +27,7 @@ public class WastelandState implements Substate {
private final SpawnsState spawnsState;
private final KitState kitState;
private final ManualState manualState;
private final PermissionsState permissionsState;
public WastelandState(WastelandConfig config) throws IOException, ClassNotFoundException, SQLException {
this.commandWasteland = new CommandWasteland();
@ -38,10 +40,20 @@ public class WastelandState implements Substate {
this.spawnsState = new SpawnsState(config.getSpawnsConfig());
this.kitState = new KitState(config.getKitConfig(), storeState.getKitStore());
this.manualState = new ManualState(config.getManualConfig());
this.permissionsState = new PermissionsState(config.getPermissionsConfig());
}
private Substate[] getSubstates() {
Substate[] substates = { storeState, chatState, killsState, ranksState, spawnsState, kitState, manualState };
Substate[] substates = {
storeState,
chatState,
killsState,
ranksState,
spawnsState,
kitState,
manualState,
permissionsState
};
return substates;
}

View File

@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.ChatColor;
@ -28,6 +29,7 @@ import me.jamestmartin.wasteland.kills.KillsConfig;
import me.jamestmartin.wasteland.kit.KitConfig;
import me.jamestmartin.wasteland.manual.ManualConfig;
import me.jamestmartin.wasteland.manual.ManualSection;
import me.jamestmartin.wasteland.permissions.PermissionsConfig;
import me.jamestmartin.wasteland.ranks.AllRanks;
import me.jamestmartin.wasteland.ranks.EnlistedRank;
import me.jamestmartin.wasteland.ranks.EnlistedRanks;
@ -59,6 +61,8 @@ public class ConfigParser {
parseManualSectionList(castToSectionList(c.getMapList("faq"))));
ManualConfig manualConfig = new ManualConfig(rules, faq);
PermissionsConfig permissionsConfig = parsePermissionsConfig(c.getConfigurationSection("permissions"));
return new WastelandConfig(
databaseFilename,
chatConfig,
@ -66,7 +70,8 @@ public class ConfigParser {
ranks,
spawnsConfig,
kitConfig,
manualConfig);
manualConfig,
permissionsConfig);
}
private static ChatConfig parseChatConfig(ConfigurationSection c) {
@ -349,6 +354,39 @@ public class ConfigParser {
return sections;
}
public static PermissionsConfig parsePermissionsConfig(ConfigurationSection c) {
Map<String, Map<String, Boolean>> groupPermissions = new HashMap<>();
ConfigurationSection groupsSection = c.getConfigurationSection("groups");
for (String group : groupsSection.getKeys(false)) {
groupPermissions.put(group, parsePermissions(groupsSection.getConfigurationSection(group)));
}
Map<UUID, Set<String>> playerGroups = new HashMap<>();
ConfigurationSection playersSection = c.getConfigurationSection("players");
for (String player : playersSection.getKeys(false)) {
UUID uuid = UUID.fromString(player);
Set<String> groups = playersSection.getList(player).stream().map(x -> (String) x)
.collect(Collectors.toUnmodifiableSet());
playerGroups.put(uuid, groups);
}
return new PermissionsConfig(groupPermissions, playerGroups);
}
public static Map<String, Boolean> parsePermissions(ConfigurationSection c) {
Map<String, Boolean> permissions = new HashMap<>();
for (String node : c.getKeys(false)) {
if (c.isBoolean(node)) {
permissions.put(node, c.getBoolean(node));
} else {
for (Entry<String, Boolean> entry : parsePermissions(c.getConfigurationSection(node)).entrySet()) {
permissions.put(node + "." + entry.getKey(), entry.getValue());
}
}
}
return permissions;
}
/** Orphaned method. */
private static Optional<ChatColor> readColor(ConfigurationSection c, String path) {
return (Optional<ChatColor>) Optional.ofNullable(c.getString(path)).map(ChatColor::valueOf);

View File

@ -0,0 +1,60 @@
package me.jamestmartin.wasteland.permissions;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionAttachment;
import me.jamestmartin.wasteland.Wasteland;
class PermissionsAttachments {
private final PermissionsConfig config;
private final Map<UUID, PermissionAttachment> attachments = new ConcurrentHashMap<>();
public PermissionsAttachments(PermissionsConfig config) {
this.config = config;
}
void removeAttachment(Player player) {
PermissionAttachment attachment = attachments.remove(player.getUniqueId());
if (attachment != null) {
player.removeAttachment(attachment);
}
}
void createAttachment(Player player) {
Map<String, Boolean> permissions = config.getPermissions(player);
if (permissions.isEmpty()) {
return;
}
PermissionAttachment attachment = player.addAttachment(Wasteland.getInstance());
attachments.put(player.getUniqueId(), attachment);
for (Entry<String, Boolean> permission : permissions.entrySet()) {
attachment.setPermission(permission.getKey(), permission.getValue());
}
}
void updateAttachment(Player player) {
removeAttachment(player);
createAttachment(player);
}
void register() {
for (Player player : Wasteland.getInstance().getServer().getOnlinePlayers()) {
createAttachment(player);
}
}
void unregister() {
for(Map.Entry<UUID, PermissionAttachment> attachment : attachments.entrySet()) {
Wasteland.getInstance().getServer().getPlayer(attachment.getKey())
.removeAttachment(attachment.getValue());
attachments.remove(attachment.getKey());
}
attachments.clear();
}
}

View File

@ -0,0 +1,27 @@
package me.jamestmartin.wasteland.permissions;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
class PermissionsAttachmentsListener implements Listener {
private final PermissionsAttachments attachments;
public PermissionsAttachmentsListener(PermissionsAttachments attachments) {
this.attachments = attachments;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
attachments.createAttachment(player);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLeave(PlayerQuitEvent event) {
attachments.removeAttachment(event.getPlayer());
}
}

View File

@ -0,0 +1,35 @@
package me.jamestmartin.wasteland.permissions;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.entity.Player;
public class PermissionsConfig {
private final Map<String, Map<String, Boolean>> groups;
private final Map<UUID, Set<String>> players;
public PermissionsConfig(Map<String, Map<String, Boolean>> groups, Map<UUID, Set<String>> players) {
this.groups = groups;
this.players = players;
}
public Map<String, Boolean> getPermissions(Player player) {
Set<String> playerGroups = players.get(player.getUniqueId());
if (playerGroups == null) {
return getDefaultPermissions();
}
Map<String, Boolean> permissions = new HashMap<>();
for (String group : playerGroups) {
permissions.putAll(groups.get(group));
}
return permissions;
}
public Map<String, Boolean> getDefaultPermissions() {
return groups.getOrDefault("default", Map.of());
}
}

View File

@ -0,0 +1,28 @@
package me.jamestmartin.wasteland.permissions;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import me.jamestmartin.wasteland.Substate;
public class PermissionsState implements Substate {
private final PermissionsAttachments attachments;
private final PermissionsAttachmentsListener listener;
public PermissionsState(PermissionsConfig config) {
this.attachments = new PermissionsAttachments(config);
this.listener = new PermissionsAttachmentsListener(attachments);
}
@Override
public void register(JavaPlugin plugin) {
attachments.register();
plugin.getServer().getPluginManager().registerEvents(listener, plugin);
}
@Override
public void unregister(JavaPlugin plugin) {
PlayerQuitEvent.getHandlerList().unregister(listener);
attachments.unregister();
}
}

View File

@ -62,7 +62,6 @@ public class RankAttachments {
}
public void unregister() {
// Trying to remove attachments throws an error. Perhaps it's done automatically?
for(Map.Entry<UUID, PermissionAttachment> attachment : attachments.entrySet()) {
Wasteland.getInstance().getServer().getPlayer(attachment.getKey())
.removeAttachment(attachment.getValue());

View File

@ -412,4 +412,9 @@ rules:
faq:
- summary: Nothing to see here.
details: The server administrator has not set an FAQ.
details: The server administrator has not set an FAQ.
permissions:
default: {}
groups: {}
players: {}