/* * PermissionsEx - Permissions plugin for Bukkit * Copyright (C) 2011 t3hk0d3 http://www.tehkode.ru * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package pex.permissions; import java.io.IOException; import java.io.OutputStreamWriter; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import net.minecraft.server.MinecraftServer; import net.minecraft.world.WorldServer; import net.minecraftforge.common.Configuration; import pex.permissions.bukkit.PermissionsEx; /** * * @author t3hk0d3 */ public abstract class PermissionBackend { protected final static String defaultBackend = "file"; protected PermissionManager manager; protected Configuration config; protected boolean createUserRecords = false; protected PermissionBackend(PermissionManager manager, Configuration config) { this.manager = manager; this.config = config; createUserRecords = config.get("permissions", "createUserRecords", createUserRecords).getBoolean(createUserRecords); } /** * Backend initialization should be done here */ public abstract void initialize(); /** * Returns new PermissionUser object for specified player name * * @param name * Player name * @return PermissionUser for specified player, or null on error. */ public abstract PermissionUser getUser(String name); /** * Returns new PermissionGroup object for specified group name * * @param name * Group name * @return PermissionGroup object, or null on error */ public abstract PermissionGroup getGroup(String name); /* * Creates new group with specified name, or returns PermissionGroup object, * if there is such group already exists. * * @param name Group name * * @returns PermissionGroup instance for specified group */ public PermissionGroup createGroup(String name) { return manager.getGroup(name); } /** * Removes the specified group * * @param groupName * Name of the group which should be removed * @return true if group was removed, false if group has child groups */ public boolean removeGroup(String groupName) { if (this.getGroups(groupName).length > 0) { return false; } for (PermissionUser user : this.getUsers(groupName)) { user.removeGroup(groupName); } manager.getGroup(groupName).remove(); return true; } /** * Returns default group, a group that is assigned to a user without a group * set * * @return Default group instance */ public abstract PermissionGroup getDefaultGroup(String worldName); /** * Set group as default group * * @param group */ public abstract void setDefaultGroup(PermissionGroup group, String worldName); /** * Returns an array of world names of specified world name * * @param world * world name * @return Array of parent worlds. If there is no parent world return empty * array */ public abstract String[] getWorldInheritance(String world); /** * Set world inheritance parents for specified world * * @param world * world name which inheritance should be set * @param parentWorlds * array of parent world names */ public abstract void setWorldInheritance(String world, String[] parentWorlds); /** * Return all registered groups * * @return */ public abstract PermissionGroup[] getGroups(); /** * Return child groups of specified group * * @param groupName * @return empty array if group has no children, empty or not exist */ public PermissionGroup[] getGroups(String groupName) { return this.getGroups(groupName, null); } public PermissionGroup[] getGroups(String groupName, String worldName) { return this.getGroups(groupName, worldName, false); } /** * Return child groups of specified group. * * @param groupName * @param inheritance * - If true a full list of descendants will be returned * * @return empty array if group has no children, empty or not exist */ public PermissionGroup[] getGroups(String groupName, boolean inheritance) { Set<PermissionGroup> groups = new HashSet<PermissionGroup>(); for (WorldServer world : MinecraftServer.getServer().worldServers) { groups.addAll(Arrays.asList(getGroups(groupName, String.valueOf(world.provider.dimensionId), inheritance))); } // Common space users groups.addAll(Arrays.asList(getGroups(groupName, null, inheritance))); return groups.toArray(new PermissionGroup[0]); } public PermissionGroup[] getGroups(String groupName, String worldName, boolean inheritance) { List<PermissionGroup> groups = new LinkedList<PermissionGroup>(); for (PermissionGroup group : this.getGroups()) { if (!groups.contains(group) && group.isChildOf(groupName, worldName, inheritance)) { groups.add(group); } } return groups.toArray(new PermissionGroup[0]); } /** * Return all registered and online users * * @return */ public PermissionUser[] getUsers() { Set<PermissionUser> users = new HashSet<PermissionUser>(); for (String player : MinecraftServer.getServer().getConfigurationManager().getAllUsernames()) { users.add(manager.getUser(player)); } users.addAll(Arrays.asList(getRegisteredUsers())); return users.toArray(new PermissionUser[0]); } /** * Return all registered users * * @return */ public abstract PermissionUser[] getRegisteredUsers(); /** * Return users of specified group. * * @param groupName * @return null if there is no such group */ public PermissionUser[] getUsers(String groupName) { return getUsers(groupName, false); } public PermissionUser[] getUsers(String groupName, String worldName) { return getUsers(groupName, worldName, false); } /** * Return users of specified group (and child groups) * * @param groupName * @param inheritance * - If true return users list of descendant groups too * @return */ public PermissionUser[] getUsers(String groupName, boolean inheritance) { Set<PermissionUser> users = new HashSet<PermissionUser>(); for (PermissionUser user : this.getUsers()) { if (user.inGroup(groupName, inheritance)) { users.add(user); } } return users.toArray(new PermissionUser[0]); } public PermissionUser[] getUsers(String groupName, String worldName, boolean inheritance) { Set<PermissionUser> users = new HashSet<PermissionUser>(); for (PermissionUser user : this.getUsers()) { if (user.inGroup(groupName, worldName, inheritance)) { users.add(user); } } return users.toArray(new PermissionUser[0]); } /** * Reload backend (reread permissions file, reconnect to database, etc) */ public abstract void reload(); /** * Dump data to native backend format * * @param writer * Writer where dumped data should be written to * @throws IOException */ public abstract void dumpData(OutputStreamWriter writer) throws IOException; /** * Array of backend aliases */ protected static Map<String, Class<? extends PermissionBackend>> registedAliases = new HashMap<String, Class<? extends PermissionBackend>>(); /** * Return class name for alias * * @param alias * @return Class name if found or alias if there is no such class name * present */ public static String getBackendClassName(String alias) { if (registedAliases.containsKey(alias)) { return registedAliases.get(alias).getName(); } return alias; } /** * Returns Class object for specified alias, if there is no alias registered * then try to find it using Class.forName(alias) * * @param alias * @return * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") public static Class<? extends PermissionBackend> getBackendClass(String alias) throws ClassNotFoundException { if (!registedAliases.containsKey(alias)) { return (Class<? extends PermissionBackend>) Class.forName(alias); } return registedAliases.get(alias); } /** * Register new alias for specified backend class * * @param alias * @param backendClass */ public static void registerBackendAlias(String alias, Class<? extends PermissionBackend> backendClass) { if (!PermissionBackend.class.isAssignableFrom(backendClass)) { throw new RuntimeException("Provided class should be subclass of PermissionBackend"); } registedAliases.put(alias, backendClass); Logger.getLogger("Minecraft").info("[PermissionsEx] " + alias + " backend registered!"); } /** * Return alias for specified backend class If there is no such class * registered the fullname of this class would be returned using * backendClass.getName(); * * @param backendClass * @return alias or class fullname when not found using * backendClass.getName() */ public static String getBackendAlias(Class<? extends PermissionBackend> backendClass) { if (registedAliases.containsValue(backendClass)) { for (String alias : registedAliases.keySet()) { // Is there better // way to find key // by value? if (registedAliases.get(alias).equals(backendClass)) { return alias; } } } return backendClass.getName(); } /** * Returns new backend class instance for specified backendName * * @param backendName * Class name or alias of backend * @param config * Configuration object to access backend settings * @return new instance of PermissionBackend object */ public static PermissionBackend getBackend(String backendName, Configuration config) { return getBackend(backendName, PermissionsEx.getPermissionManager(), config, defaultBackend); } /** * Returns new Backend class instance for specified backendName * * @param backendName * Class name or alias of backend * @param manager * PermissionManager object * @param config * Configuration object to access backend settings * @return new instance of PermissionBackend object */ public static PermissionBackend getBackend(String backendName, PermissionManager manager, Configuration config) { return getBackend(backendName, manager, config, defaultBackend); } /** * Returns new Backend class instance for specified backendName * * @param backendName * Class name or alias of backend * @param manager * PermissionManager object * @param config * Configuration object to access backend settings * @param fallBackBackend * name of backend that should be used if specified backend was * not found or failed to initialize * @return new instance of PermissionBackend object */ public static PermissionBackend getBackend(String backendName, PermissionManager manager, Configuration config, String fallBackBackend) { if (backendName == null || backendName.isEmpty()) { backendName = defaultBackend; } String className = getBackendClassName(backendName); try { Class<? extends PermissionBackend> backendClass = getBackendClass(backendName); Logger.getLogger("Minecraft").info("[PermissionsEx] Initializing " + backendName + " backend"); Constructor<? extends PermissionBackend> constructor = backendClass.getConstructor(PermissionManager.class, Configuration.class); return constructor.newInstance(manager, config); } catch (ClassNotFoundException e) { Logger.getLogger("Minecraft").warning("[PermissionsEx] Specified backend \"" + backendName + "\" are not found."); if (fallBackBackend == null) { throw new RuntimeException(e); } if (!className.equals(getBackendClassName(fallBackBackend))) { return getBackend(fallBackBackend, manager, config, null); } else { throw new RuntimeException(e); } } catch (Exception e) { throw new RuntimeException(e); } } public boolean isCreateUserRecords() { return createUserRecords; } }