diff --git a/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java b/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java index be44f75..5c51116 100644 --- a/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java +++ b/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java @@ -38,7 +38,7 @@ public enum PlayerType + "(?:/([0-9]|[1-2][0-9]|3[0-2]))$"); public static PlayerType scanPlayerEntity(String entity) { - if("".equals(entity)) + if(entity == null || "".equals(entity)) return name; if(nicknameRegExp.matcher(entity).matches()) return name; @@ -102,7 +102,7 @@ public enum PlayerType switch(this) { case name: - return entity.equals(identifier); + return identifier.equals(entity); case hyphenatedUUID: identifier = identifier.replace("-", "").toLowerCase(); case dehyphenatedUUID: diff --git a/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java b/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java index 197c765..1d47286 100644 --- a/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java +++ b/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java @@ -16,6 +16,8 @@ public class RowInheritance implements Cloneable, Comparable public Timestamp lifetime; public transient PlayerType playerType; public transient String destinationSource; + public transient RowEntity entityChild; + public transient RowEntity entityParent; public void deriveInstance() { if(parent != null) @@ -38,7 +40,9 @@ public class RowInheritance implements Cloneable, Comparable @Override public int compareTo(RowInheritance t) { - return (priority != t.priority) ? priority - t.priority : parent.compareTo(t.parent); + return (priority != t.priority) + ? priority - t.priority + : parent.compareTo(t.parent); } public boolean isEntityApplicable(String identifier) { diff --git a/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java b/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java index 31225d1..667027e 100644 --- a/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java +++ b/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java @@ -13,6 +13,7 @@ public class RowPermission implements Cloneable public Timestamp lifetime; public transient PlayerType playerType; public transient String destinationSource; + public transient RowEntity entityObject; @Override public RowPermission clone() throws CloneNotSupportedException { diff --git a/src/main/java/ru/simsonic/rscPermissions/API/Settings.java b/src/main/java/ru/simsonic/rscPermissions/API/Settings.java index a8a0b04..00da76d 100644 --- a/src/main/java/ru/simsonic/rscPermissions/API/Settings.java +++ b/src/main/java/ru/simsonic/rscPermissions/API/Settings.java @@ -3,9 +3,10 @@ import ru.simsonic.rscUtilityLibrary.ConnectionMySQL.ConnectionParams; public interface Settings { - public static final String instantiator = "?"; - public static final String separator = "."; + public static final String separator = "."; public static final String separatorRegExp = "\\."; + public static final String instantiator = "?"; + public static final String textInheriter = "%"; public void onLoad(); public void readSettings(); public String getDefaultGroup(); diff --git a/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java b/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java index 6ca0b55..6e9b7eb 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java +++ b/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java @@ -131,4 +131,10 @@ public class DatabaseContents inheritance = li.toArray(new RowInheritance[li.size()]); return this; } + public boolean isEmpty() + { + return !((entities != null && entities.length > 0) + && (permissions != null && permissions.length > 0) + && (inheritance != null && inheritance.length > 0)); + } } diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitCommands.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitCommands.java index 50777a0..6ee9093 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitCommands.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitCommands.java @@ -7,8 +7,8 @@ import java.util.logging.Level; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import ru.simsonic.rscPermissions.BukkitPluginMain; import ru.simsonic.rscPermissions.Backends.DatabaseContents; +import ru.simsonic.rscPermissions.BukkitPluginMain; import ru.simsonic.rscUtilityLibrary.CommandProcessing.CommandAnswerException; import ru.simsonic.rscUtilityLibrary.RestartableThread; @@ -108,7 +108,7 @@ public class BukkitCommands }); } }; - threadInsertExampleRows.start(); + threadInsertExampleRows.startDeamon(); return threadInsertExampleRows; } public void onCommand(CommandSender sender, Command cmd, String label, String[] args) throws CommandAnswerException @@ -193,7 +193,7 @@ public class BukkitCommands // TO DO HERE PermissionsEx_YAML importer_pex = new PermissionsEx_YAML( new File(rscp.getDataFolder(), args[2])); - threadFetchDatabaseContents.start(); + threadFetchDatabaseContents.startDeamon(); throw new CommandAnswerException(new String[] { "Data has been imported successfully!", @@ -221,7 +221,7 @@ public class BukkitCommands /* rscp fetch */ if(sender.hasPermission("rscp.admin.reload")) { - threadFetchDatabaseContents.start(); + threadFetchDatabaseContents.startDeamon(); throw new CommandAnswerException("Tables have been fetched."); } return; diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java index 6818bad..dca02e8 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java @@ -8,7 +8,6 @@ import java.util.Set; import java.util.concurrent.LinkedBlockingQueue; import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachment; -import ru.simsonic.rscPermissions.API.RowPermission; import ru.simsonic.rscPermissions.BukkitPluginMain; import ru.simsonic.rscPermissions.InternalCache.ResolutionParams; import ru.simsonic.rscPermissions.InternalCache.ResolutionResult; @@ -23,8 +22,8 @@ public class BukkitPermissionManager extends RestartableThread } private final LinkedBlockingQueue updateQueue = new LinkedBlockingQueue<>(); private final HashMap attachments = new HashMap<>(); - private final HashMap persistentPermissions = new HashMap<>(); - private final HashMap transientPermissions = new HashMap<>(); + private final HashMap> persistentPermissions = new HashMap<>(); + private final HashMap> transientPermissions = new HashMap<>(); private final HashMap prefixes = new HashMap<>(); private final HashMap suffixes = new HashMap<>(); public void recalculateOnlinePlayers() @@ -76,25 +75,21 @@ public class BukkitPermissionManager extends RestartableThread public void run() { // Remove old - final PermissionAttachment previous = attachments.get(player); - if(previous != null) - { - player.removeAttachment(previous); - attachments.remove(player); - } + if(attachments.containsKey(player)) + attachments.remove(player).remove(); // Create new - final RowPermission[] pp = persistentPermissions.get(player); - final RowPermission[] tp = transientPermissions.get(player); + final Map pp = persistentPermissions.get(player); + final Map tp = transientPermissions.get(player); if(pp == null && tp == null) return; final PermissionAttachment attachment = player.addAttachment(rscp); attachments.put(player, attachment); if(pp != null) - for(RowPermission row : pp) - attachment.setPermission(row.permission, row.value); + for(Map.Entry row : pp.entrySet()) + attachment.setPermission(row.getKey(), row.getValue()); if(tp != null) - for(RowPermission row : tp) - attachment.setPermission(row.permission, row.value); + for(Map.Entry row : tp.entrySet()) + attachment.setPermission(row.getKey(), row.getValue()); // Server operator final Boolean asterisk = attachment.getPermissions().get("*"); if(rscp.settings.isAsteriskOP()) diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java index aa400a7..afc8b13 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPluginConfiguration.java @@ -1,7 +1,7 @@ package ru.simsonic.rscPermissions.Bukkit; import org.bukkit.configuration.file.FileConfiguration; -import ru.simsonic.rscPermissions.BukkitPluginMain; import ru.simsonic.rscPermissions.API.Settings; +import ru.simsonic.rscPermissions.BukkitPluginMain; import ru.simsonic.rscUtilityLibrary.ConnectionMySQL.ConnectionParams; public class BukkitPluginConfiguration implements Settings diff --git a/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java b/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java index 4e0ff33..cb0e840 100644 --- a/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java +++ b/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java @@ -1,9 +1,4 @@ package ru.simsonic.rscPermissions; -import ru.simsonic.rscPermissions.API.BridgeForBukkitAPI; -import ru.simsonic.rscPermissions.Bukkit.BukkitCommands; -import ru.simsonic.rscPermissions.Bukkit.BukkitRegionProviders; -import ru.simsonic.rscPermissions.Bukkit.RegionUpdateObserver; -import ru.simsonic.rscPermissions.API.Settings; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -13,12 +8,17 @@ import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitScheduler; import org.mcstats.MetricsLite; +import ru.simsonic.rscPermissions.API.BridgeForBukkitAPI; +import ru.simsonic.rscPermissions.API.Settings; import ru.simsonic.rscPermissions.Backends.BackendDatabase; import ru.simsonic.rscPermissions.Backends.BackendJson; import ru.simsonic.rscPermissions.Backends.DatabaseContents; +import ru.simsonic.rscPermissions.Bukkit.BukkitCommands; +import ru.simsonic.rscPermissions.Bukkit.BukkitEventListener; import ru.simsonic.rscPermissions.Bukkit.BukkitPermissionManager; import ru.simsonic.rscPermissions.Bukkit.BukkitPluginConfiguration; -import ru.simsonic.rscPermissions.Bukkit.BukkitEventListener; +import ru.simsonic.rscPermissions.Bukkit.BukkitRegionProviders; +import ru.simsonic.rscPermissions.Bukkit.RegionUpdateObserver; import ru.simsonic.rscPermissions.InternalCache.InternalCache; import ru.simsonic.rscUtilityLibrary.CommandProcessing.CommandAnswerException; import ru.simsonic.rscUtilityLibrary.TextProcessing.GenericChatCodes; @@ -67,11 +67,11 @@ public final class BukkitPluginMain extends JavaPlugin contents.inheritance.length, }); // Start all needed threads - permissionManager.start(); - regionUpdateObserver.start(); + permissionManager.startDeamon(); + regionUpdateObserver.startDeamon(); // Connect to database and fetch data connection.initialize(settings.getConnectionParams()); - commandHelper.threadFetchDatabaseContents.start(); + commandHelper.threadFetchDatabaseContents.startDeamon(); // Metrics if(settings.isUseMetrics()) { @@ -110,7 +110,7 @@ public final class BukkitPluginMain extends JavaPlugin @Override public void run() { - commandHelper.threadFetchDatabaseContents.start(); + commandHelper.threadFetchDatabaseContents.startDeamon(); } }, delay); } diff --git a/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java b/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java index 0274a91..03bdf23 100644 --- a/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java +++ b/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java @@ -1,10 +1,12 @@ package ru.simsonic.rscPermissions; import java.io.File; +import java.util.Map; import java.util.logging.Logger; import ru.simsonic.rscPermissions.Backends.BackendDatabase; import ru.simsonic.rscPermissions.Backends.BackendJson; import ru.simsonic.rscPermissions.Backends.DatabaseContents; import ru.simsonic.rscPermissions.InternalCache.InternalCache; +import ru.simsonic.rscPermissions.InternalCache.ResolutionResult; public class IndependentMain { @@ -34,7 +36,19 @@ public class IndependentMain final DatabaseContents contents = localJsn.retrieveContents(); System.out.println("Filter and calculating permission tree."); contents.filterServerId("localtest").filterLifetime(); + if(contents.isEmpty()) + { + System.out.println("Permission database is empty, stopping."); + return; + } intCache.fill(contents); + final ResolutionResult result = intCache.resolvePlayer("rscpTester"); + for(Map.Entry perm : result.permissions.entrySet()) + System.out.println(perm.getKey() + " = " + perm.getValue()); + if(result.prefix != null) + System.out.println("Prefix = " + result.prefix); + if(result.suffix != null) + System.out.println("Suffix = " + result.suffix); System.out.println("Done."); } } diff --git a/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java b/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java index 474b13e..94a77f0 100644 --- a/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java +++ b/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map.Entry; import ru.simsonic.rscPermissions.API.EntityType; import ru.simsonic.rscPermissions.API.PlayerType; @@ -15,28 +16,20 @@ import ru.simsonic.rscPermissions.Backends.DatabaseContents; public class InternalCache { - private final RowInheritance defaultInheritance = new RowInheritance(); + private final HashMap entities_g = new HashMap<>(); + private final HashMap entities_u = new HashMap<>(); + private final RowInheritance defaultInheritance = new RowInheritance(); public void setDefaultGroup(String defaultGroup) { defaultInheritance.parent = defaultGroup; defaultInheritance.deriveInstance(); } - private final HashMap entities_g = new HashMap<>(); - private final HashMap entities_u = new HashMap<>();/* - private final ArrayList permissions_p2g = new ArrayList<>(); - private final ArrayList permissions_p2u = new ArrayList<>(); - private final ArrayList inheritance_g2g = new ArrayList<>(); - private final ArrayList inheritance_g2u = new ArrayList<>();*/ public synchronized void fill(DatabaseContents contents) { clear(); - // Import data importEntities(contents); importPermissions(contents.permissions); importInheritance(contents.inheritance); - // Parse PlayerType's - for(RowEntity row : entities_u.values()) - row.playerType = PlayerType.scanPlayerEntity(row.entity); } private void importEntities(DatabaseContents contents) { @@ -45,31 +38,46 @@ public class InternalCache for(RowEntity row : contents.entities) if(row.entityType == EntityType.group) { + names_g.add(row.entity); entities_g.put(row.entity.toLowerCase(), row); - names_g.add(row.entity.toLowerCase()); } else { - entities_u.put(row.entity, row); names_u.add(row.entity); + entities_u.put(row.entity, row); } for(RowPermission row : contents.permissions) if(row.entityType == EntityType.group) - names_g.add(row.entity.toLowerCase()); + names_g.add(row.entity); else names_u.add(row.entity); for(RowInheritance row : contents.inheritance) { - names_g.add(row.parent.toLowerCase()); + names_g.add(row.parent); if(row.childType == EntityType.group) - names_g.add(row.entity.toLowerCase()); + names_g.add(row.entity); else names_u.add(row.entity); } for(String name : names_g) - if(!entities_g.containsKey(name)) - entities_g.put(name, new RowEntity()); + { + final String groupInternalName = name.toLowerCase(); + if(!entities_g.containsKey(groupInternalName)) + { + final RowEntity dummy = new RowEntity(); + dummy.entity = name; + dummy.entityType = EntityType.group; + entities_g.put(groupInternalName, dummy); + } + } for(String name : names_u) if(!entities_u.containsKey(name)) - entities_u.put(name, new RowEntity()); + { + final RowEntity dummy = new RowEntity(); + dummy.entity = name; + dummy.entityType = EntityType.player; + entities_u.put(name, dummy); + } + for(RowEntity row : entities_u.values()) + row.playerType = PlayerType.scanPlayerEntity(row.entity); } private void importPermissions(RowPermission[] rows) { @@ -77,9 +85,13 @@ public class InternalCache final ArrayList permissions_p2u = new ArrayList<>(); for(RowPermission row : rows) if(row.entityType == EntityType.group) + { + row.entityObject = entities_g.get(row.entity.toLowerCase()); permissions_p2g.add(row); - else + } else { + row.entityObject = entities_u.get(row.entity); permissions_p2u.add(row); + } for(String entry : entities_g.keySet()) { final ArrayList permissions = new ArrayList<>(); @@ -103,9 +115,15 @@ public class InternalCache final ArrayList inheritance_g2u = new ArrayList<>(); for(RowInheritance row : rows) if(row.childType == EntityType.group) + { + row.entityChild = entities_g.get(row.entity.toLowerCase()); + row.entityParent = entities_g.get(row.parent.toLowerCase()); inheritance_g2g.add(row); - else + } else { + row.entityChild = entities_u.get(row.entity); + row.entityParent = entities_g.get(row.parent.toLowerCase()); inheritance_g2u.add(row); + } for(Entry entry : entities_g.entrySet()) { final ArrayList inheritances = new ArrayList<>(); @@ -113,16 +131,18 @@ public class InternalCache for(RowInheritance row : inheritance_g2g) if(row.entity.toLowerCase().equals(name)) inheritances.add(row); + Collections.sort(inheritances); entry.getValue().inheritance = inheritances.toArray(new RowInheritance[inheritances.size()]); } for(Entry entry : entities_u.entrySet()) { - final ArrayList inheritance = new ArrayList<>(); + final ArrayList inheritances = new ArrayList<>(); final String name = entry.getKey(); for(RowInheritance row : inheritance_g2u) if(row.entity.equals(name)) - inheritance.add(row); - entry.getValue().inheritance = inheritance.toArray(new RowInheritance[inheritance.size()]); + inheritances.add(row); + Collections.sort(inheritances); + entry.getValue().inheritance = inheritances.toArray(new RowInheritance[inheritances.size()]); } } public synchronized ResolutionResult resolvePlayer(String player) @@ -134,175 +154,118 @@ public class InternalCache final ResolutionParams params = new ResolutionParams(); params.applicableIdentifiers = player; params.destRegions = new String[] {}; - // params.destWorld = ""; - // params.expirience = 0; return resolvePlayer(params); } public synchronized ResolutionResult resolvePlayer(ResolutionParams params) { - final ArrayList intermediate = new ArrayList<>(); - if(entities_g.containsKey("")) - { - params.parentEntity = entities_g.get(""); - params.instantiator = ""; - intermediate.add(resolveParent(params)); - } + final ArrayList applicablePermissions = new ArrayList<>(); + final ArrayList applicableInheritance = new ArrayList<>(); + params.groupList = new HashSet<>(); + params.finalPerms = new HashMap<>(); + params.instantiator = ""; for(RowEntity row : entities_u.values()) for(String identifier : params.applicableIdentifiers) if(row.playerType.isEntityApplicable(row.entity, identifier)) { - params.parentEntity = row; - params.instantiator = ""; - intermediate.add(resolveParent(params)); - break; + if(row.inheritance != null && row.inheritance.length > 0) + for(RowInheritance inheritance : row.inheritance) + if(isInheritanceApplicable(params, inheritance)) + applicableInheritance.add(inheritance); + applicablePermissions.addAll(Arrays.asList(row.permissions)); } - final ResolutionResult result = processResultColumn(params, intermediate); - - parents.addAll(Arrays.asList(implicitInheritance_u)); - parents.add(defaultInheritance); - for(Entry entity : inheritanceTrees_u.entrySet()) - { - for(RowInheritance row : entity.getValue()) - if(PlayerType.isEntityApplicable(entity, , entity)) - }; - final ResolutionResult result = new ResolutionResult(); - intermediate.addAll(Arrays.asList(implicitPermissions_u)); - final ArrayList inheritance = new ArrayList<>(); - return result; - } - public synchronized ResolutionResult resolveParent(ResolutionParams params) - { - return null; - } - /* - public synchronized ResolutionResult resolvePlayerOld(ResolutionParams params) - { - final ArrayList applicableBranches = new ArrayList<>(); - // Grab all inheritance rows applicable to this player - for(String identifier : params.applicableIdentifiers) - for(String tree : entityTrees.keySet()) - if(tree.equals(identifier)) - applicableBranches.add(entityTrees.get(tree)); - Collections.sort(applicableBranches); - // Begin resolution final ArrayList intermediateResults = new ArrayList<>(); - for(InheritanceLeaf branch : applicableBranches) - if(isInheritanceApplicable(params, branch.node, "")) - intermediateResults.add(resolveBranch(params, branch, "")); - final ResolutionResult result = processResultColumn(params, intermediateResults, ""); - intermediateResults.clear(); - return result; - } - // FROM HERE I SHOULD MAKE IT WORKING - private void buildInheritanceForest() - { - final HashSet entitiesWhichInherits = new HashSet<>(); - for(RowInheritance row : inheritance_g2u) - entitiesWhichInherits.add(row.entity); - for(String inheritingEntity : entitiesWhichInherits) + Collections.sort(applicableInheritance); + for(RowInheritance row : applicableInheritance) { - final ArrayList entityDirectParents = new ArrayList<>(); - for(RowInheritance row : inheritance_g2u) - if(row.entity.equalsIgnoreCase(inheritingEntity)) - entityDirectParents.add(row); - Collections.sort(entityDirectParents); - for(RowInheritance row : entityDirectParents) - this.entityTrees.put(inheritingEntity, buildBranch(row)); + params.instantiator = ""; + params.parentEntity = row.entityParent; + intermediateResults.add(resolveParent(params)); } + final ResolutionResult result = processPrefixesAndSuffixes(params, intermediateResults); + processPermissions(params, applicablePermissions); + result.permissions = params.finalPerms; + result.groups = params.groupList; + return result; } - private InheritanceLeaf buildBranch(RowInheritance source) + private ResolutionResult resolveParent(ResolutionParams params) { - final InheritanceLeaf result = new InheritanceLeaf(); - result.node = source; - result.instantiator = source.instance; - final String entityName = source.entity.toLowerCase(); - if(entities_g.containsKey(entityName)) - { - result.prefix = entities_g.get(entityName).prefix; - result.suffix = entities_g.get(entityName).suffix; - } - final ArrayList parents = new ArrayList<>(); - for(RowInheritance row : inheritance_g2g) - if(row.parentEntity.equalsIgnoreCase(source.entity)) - parents.add(row); - Collections.sort(parents); - final ArrayList subleafs = new ArrayList<>(); - for(RowInheritance row : parents) - subleafs.add(buildBranch(row)); - result.subleafs = subleafs.toArray(new InheritanceLeaf[subleafs.size()]); + final RowEntity currentParent = params.parentEntity; + final String instantiator = params.instantiator; + params.groupList.add(currentParent.entity + ("".equals(instantiator) ? "" : Settings.separator + instantiator)); + final ArrayList intermediateResults = new ArrayList<>(); + for(RowInheritance row : params.parentEntity.inheritance) + if(isInheritanceApplicable(params, row)) + { + params.parentEntity = row.entityParent; + params.instantiator = (row.instance != null && !"".equals(row.instance)) + ? row.instance + : instantiator; + intermediateResults.add(resolveParent(params)); + } + // Prefixes and suffixes + params.parentEntity = currentParent; + params.instantiator = instantiator; + final ResolutionResult result = processPrefixesAndSuffixes(params, intermediateResults); + // Permissions + if(currentParent.permissions != null) + processPermissions(params, Arrays.asList(currentParent.permissions)); return result; } - private ResolutionResult resolveBranch(ResolutionParams params, RowInheritance[] rows, String instantiator) + private ResolutionResult processPrefixesAndSuffixes(ResolutionParams params, ArrayList intermediate) { - final ArrayList intermediateResults = new ArrayList<>(); - for(InheritanceLeaf subleaf : branch.subleafs) + final ResolutionResult result = new ResolutionResult(); + result.prefix = params.parentEntity.prefix; + result.suffix = params.parentEntity.suffix; + if(result.prefix == null || "".equals(result.prefix)) + result.prefix = "%"; + if(result.suffix == null || "".equals(result.suffix)) + result.suffix = "%"; + if(intermediate.size() > 0) { - final String overloadedInstantiator = (subleaf.instantiator != null && !"".equals(subleaf.instantiator)) - ? subleaf.instantiator : instantiator; - if(isInheritanceApplicable(params, subleaf.node, overloadedInstantiator)) - intermediateResults.add(resolveBranch(params, subleaf, overloadedInstantiator)); + final StringBuilder sbp = new StringBuilder(); + final StringBuilder sbs = new StringBuilder(); + for(ResolutionResult inherited : intermediate) + { + if(inherited.prefix != null) + sbp.append(inherited.prefix); + if(inherited.suffix != null) + sbs.append(inherited.suffix); + } + intermediate.clear(); + result.prefix = result.prefix.replace(Settings.textInheriter, sbp.toString()); + result.suffix = result.suffix.replace(Settings.textInheriter, sbs.toString()); } - final ResolutionResult result = processResultColumn(params, intermediateResults, branch.instantiator); - intermediateResults.clear(); + result.prefix = result.prefix.replace(Settings.instantiator, params.instantiator); + result.suffix = result.suffix.replace(Settings.instantiator, params.instantiator); return result; } - */ - private ResolutionResult processResultColumn(ResolutionParams params, ArrayList intermediate) + private void processPermissions(ResolutionParams params, List permissions) { - switch(intermediate.size()) - { - case 0: - return new ResolutionResult(); - case 1: - return intermediate.get(0); - default: - final ResolutionResult result = new ResolutionResult(); - final ArrayList permissions = new ArrayList<>(); - result.prefix = ""; - result.suffix = ""; - for(ResolutionResult oneOf : intermediate) - { - // Prefixes & suffixes - if(oneOf.prefix != null && !"".equals(oneOf.prefix)) - result.prefix = result.prefix.replace("%", oneOf.prefix); - if(oneOf.suffix != null && !"".equals(oneOf.suffix)) - result.suffix = result.suffix.replace("%", oneOf.suffix); - result.prefix = result.prefix.replace(Settings.instantiator, params.instantiator); - result.suffix = result.suffix.replace(Settings.instantiator, params.instantiator); - // Permissions - for(RowPermission permission : oneOf.permissions) - if(isPermissionApplicable(params, permission, params.instantiator)) - permissions.add(permission); - } - result.permissions = permissions.toArray(new RowPermission[permissions.size()]); - return result; - } + for(RowPermission row : permissions) + if(isPermissionApplicable(params, row)) + params.finalPerms.put( + row.permission.replace(Settings.instantiator, params.instantiator), + row.value); } - private boolean isPermissionApplicable(ResolutionParams params, RowPermission row, String instantiator) + private boolean isPermissionApplicable(ResolutionParams params, RowPermission row) { if(params.expirience < row.expirience) return false; - return row.destination.isWorldApplicable(params.destWorld, instantiator) - ? row.destination.isRegionApplicable(params.destRegions, instantiator) + return row.destination.isWorldApplicable(params.destWorld, params.instantiator) + ? row.destination.isRegionApplicable(params.destRegions, params.instantiator) : false; } - private boolean isInheritanceApplicable(ResolutionParams params, RowInheritance row, String instantiator) + private boolean isInheritanceApplicable(ResolutionParams params, RowInheritance row) { if(params.expirience < row.expirience) return false; - return row.destination.isWorldApplicable(params.destWorld, instantiator) - ? row.destination.isRegionApplicable(params.destRegions, instantiator) + return row.destination.isWorldApplicable(params.destWorld, params.instantiator) + ? row.destination.isRegionApplicable(params.destRegions, params.instantiator) : false; } public synchronized void clear() { entities_g.clear(); entities_u.clear(); - /* - permissions_p2g.clear(); - permissions_p2u.clear(); - inheritance_g2g.clear(); - inheritance_g2u.clear(); - */ } } diff --git a/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java b/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java index 0bef1a5..c2b607a 100644 --- a/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java +++ b/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java @@ -1,4 +1,6 @@ package ru.simsonic.rscPermissions.InternalCache; +import java.util.Map; +import java.util.Set; import ru.simsonic.rscPermissions.API.RowEntity; public class ResolutionParams @@ -9,4 +11,6 @@ public class ResolutionParams public int expirience; protected transient RowEntity parentEntity; protected transient String instantiator; + protected transient Map finalPerms; + protected transient Set groupList; } diff --git a/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionResult.java b/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionResult.java index f2c9fbc..f70963e 100644 --- a/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionResult.java +++ b/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionResult.java @@ -1,16 +1,18 @@ package ru.simsonic.rscPermissions.InternalCache; -import ru.simsonic.rscPermissions.API.RowPermission; +import java.util.Map; +import java.util.Set; public class ResolutionResult { public String prefix; public String suffix; - public RowPermission[] permissions; + public Map permissions; + public Set groups; public boolean hasPermission(String permission) { - for(RowPermission row : permissions) - if(permission.equals(row.permission)) - return row.value; + for(Map.Entry entry : permissions.entrySet()) + if(entry.getKey().equals(permission)) + return entry.getValue(); return false; } }