From 9a5b488741e38f6d3a175dcfa951c67d422c454e Mon Sep 17 00:00:00 2001 From: Stanislav Usenkov Date: Tue, 17 Feb 2015 19:49:50 +0600 Subject: [PATCH] End of day commit. It not works and even not compiles right now. --- .../Resolution of permission tree New.pptx | Bin 0 -> 52672 bytes .../API/BridgeForBukkitAPI.java | 8 + .../rscPermissions/API/PlayerType.java | 113 +++++++++ .../rscPermissions/API/RowEntity.java | 3 + .../rscPermissions/API/RowInheritance.java | 19 +- .../rscPermissions/API/RowPermission.java | 10 +- .../Backends/DatabaseContents.java | 27 +++ .../Bukkit/BukkitEventListener.java | 19 +- .../Bukkit/BukkitPermissionManager.java | 10 +- .../rscPermissions/Bukkit/VaultChat.java | 7 +- .../Bukkit/VaultPermission.java | 6 +- .../rscPermissions/BukkitPluginMain.java | 2 +- .../rscPermissions/IndependentMain.java | 2 +- .../InternalCache/InternalCache.java | 227 ++++++++++++------ .../InternalCache/ResolutionParams.java | 4 +- 15 files changed, 359 insertions(+), 98 deletions(-) create mode 100644 Figures for documentation/Resolution of permission tree New.pptx create mode 100644 src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java diff --git a/Figures for documentation/Resolution of permission tree New.pptx b/Figures for documentation/Resolution of permission tree New.pptx new file mode 100644 index 0000000000000000000000000000000000000000..9eb47d069dc8a9a3acd70e5e78a743120b13561b GIT binary patch literal 52672 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 public Destination destination; public int expirience; public Timestamp lifetime; - public transient String destinationSource; + public transient PlayerType playerType; + public transient String destinationSource; public void deriveInstance() { if(parent != null) @@ -39,4 +40,20 @@ public class RowInheritance implements Cloneable, Comparable { return (priority != t.priority) ? priority - t.priority : parent.compareTo(t.parent); } + public boolean isEntityApplicable(String identifier) + { + if(EntityType.group.equals(childType)) + return entity.equalsIgnoreCase(identifier); + switch(playerType) + { + case name: + return entity.equals(identifier); + case hyphenatedUUID: + identifier = identifier.replace("-", ""); + case dehyphenatedUUID: + return entity.equals(identifier); + } + // TO DO + return false; + } } diff --git a/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java b/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java index e0262ff..31225d1 100644 --- a/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java +++ b/src/main/java/ru/simsonic/rscPermissions/API/RowPermission.java @@ -11,10 +11,18 @@ public class RowPermission implements Cloneable public Destination destination; public int expirience; public Timestamp lifetime; - public transient String destinationSource; + public transient PlayerType playerType; + public transient String destinationSource; @Override public RowPermission clone() throws CloneNotSupportedException { return (RowPermission)super.clone(); } + public boolean isEntityApplicable(String identifier) + { + if(EntityType.group.equals(entityType)) + return entity.equalsIgnoreCase(identifier); + // TO DO + return false; + } } diff --git a/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java b/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java index 3519047..6ca0b55 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java +++ b/src/main/java/ru/simsonic/rscPermissions/Backends/DatabaseContents.java @@ -1,5 +1,6 @@ package ru.simsonic.rscPermissions.Backends; import java.util.ArrayList; +import java.util.Date; import ru.simsonic.rscPermissions.API.Destination; import ru.simsonic.rscPermissions.API.RowEntity; import ru.simsonic.rscPermissions.API.RowInheritance; @@ -85,6 +86,32 @@ public class DatabaseContents inheritance = li.toArray(new RowInheritance[li.size()]); return this; } + public DatabaseContents filterLifetime() + { + if(entities == null) + entities = new RowEntity[] {}; + if(permissions == null) + permissions = new RowPermission[] {}; + if(inheritance == null) + inheritance = new RowInheritance[] {}; + final Date date = new Date(); + final ArrayList le = new ArrayList<>(); + final ArrayList lp = new ArrayList<>(); + final ArrayList li = new ArrayList<>(); + for(RowEntity row : entities) + if(!(row.lifetime != null && row.lifetime.after(date))) + le.add(row); + for(RowPermission row : permissions) + if(!(row.lifetime != null && row.lifetime.after(date))) + lp.add(row); + for(RowInheritance row : inheritance) + if(!(row.lifetime != null && row.lifetime.after(date))) + li.add(row); + entities = le.toArray(new RowEntity[le.size()]); + permissions = lp.toArray(new RowPermission[lp.size()]); + inheritance = li.toArray(new RowInheritance[li.size()]); + return this; + } public DatabaseContents filterServerId(String serverId) { if(permissions == null) diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitEventListener.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitEventListener.java index 27cec83..5a8f830 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitEventListener.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitEventListener.java @@ -1,4 +1,5 @@ package ru.simsonic.rscPermissions.Bukkit; +import java.util.ArrayList; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -25,12 +26,20 @@ public class BukkitEventListener implements Listener @EventHandler public void onPlayerAsyncPreLogin(AsyncPlayerPreLoginEvent event) { - final ResolutionResult resolution = rscp.internalCache.resolvePlayer(new String[] + final ArrayList identifiers = new ArrayList<>(); + try { - event.getName(), - event.getUniqueId().toString(), - event.getAddress().getHostAddress(), - }, rscp.getServer().getServerId()); + identifiers.add(event.getName()); + } catch(RuntimeException | NoSuchMethodError ex) { + } + try + { + identifiers.add(event.getUniqueId().toString().toLowerCase()); + } catch(RuntimeException | NoSuchMethodError ex) { + } + identifiers.add(event.getAddress().getHostAddress()); + // Resolution + final ResolutionResult resolution = rscp.internalCache.resolvePlayer(identifiers.toArray(new String[identifiers.size()])); processMaintenanceLogin(event, resolution); } @EventHandler(priority = EventPriority.LOWEST) diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java index e4e5315..6818bad 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/BukkitPermissionManager.java @@ -117,31 +117,23 @@ public class BukkitPermissionManager extends RestartableThread } else params.destRegions = new String[] {}; params.destWorld = player.getLocation().getWorld().getName(); - params.destServerId = rscp.getServer().getServerId(); params.expirience = player.getLevel(); return rscp.internalCache.resolvePlayer(params); } private static String[] getPlayerIdentifiers(Player player) { final ArrayList result = new ArrayList<>(); - // For old servers Player's name can be used as entity name try { - // minecraft <= 1.7.x result.add(player.getName()); } catch(RuntimeException | NoSuchMethodError ex) { - // minecraft >= 1.8 } - // For newest servers Player's UUID is used as entity name try { - // minecraft >= 1.8 result.add(player.getUniqueId().toString().toLowerCase()); } catch(RuntimeException | NoSuchMethodError ex) { - // minecraft <= 1.7.x } - // IP address of a Player can be used as entity name too - InetSocketAddress socketAddress = player.getAddress(); + final InetSocketAddress socketAddress = player.getAddress(); if(socketAddress != null) result.add(socketAddress.getAddress().getHostAddress()); return result.toArray(new String[result.size()]); diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java index 319a7d8..b7f0a62 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultChat.java @@ -1,5 +1,4 @@ package ru.simsonic.rscPermissions.Bukkit; -import net.milkbowl.vault.permission.Permission; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; @@ -8,7 +7,7 @@ import ru.simsonic.rscPermissions.API.BridgeForBukkitAPI; public final class VaultChat extends net.milkbowl.vault.chat.Chat { private final BridgeForBukkitAPI bridge; - public VaultChat(BridgeForBukkitAPI bridge, Permission perms) + public VaultChat(BridgeForBukkitAPI bridge, net.milkbowl.vault.permission.Permission perms) { super(perms); this.bridge = bridge; @@ -16,12 +15,12 @@ public final class VaultChat extends net.milkbowl.vault.chat.Chat @Override public String getName() { - throw new UnsupportedOperationException("This method is still unsupported. Sorry."); + return bridge.getName(); } @Override public boolean isEnabled() { - throw new UnsupportedOperationException("This method is still unsupported. Sorry."); + return bridge.isEnabled(); } @Override public String getPlayerPrefix(String world, String player) diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java index 70ec805..d7bfab4 100644 --- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java +++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/VaultPermission.java @@ -15,17 +15,17 @@ public class VaultPermission extends net.milkbowl.vault.permission.Permission @Override public String getName() { - throw new UnsupportedOperationException("This method is still unsupported. Sorry."); + return bridge.getName(); } @Override public boolean isEnabled() { - throw new UnsupportedOperationException("This method is still unsupported. Sorry."); + return bridge.isEnabled(); } @Override public boolean hasSuperPermsCompat() { - throw new UnsupportedOperationException("This method is still unsupported. Sorry."); + return true; } @Override public boolean playerHas(String world, String player, String permission) diff --git a/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java b/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java index be7d734..4e0ff33 100644 --- a/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java +++ b/src/main/java/ru/simsonic/rscPermissions/BukkitPluginMain.java @@ -57,7 +57,7 @@ public final class BukkitPluginMain extends JavaPlugin // Restore temporary cached data from json files internalCache.setDefaultGroup(settings.getDefaultGroup()); final DatabaseContents contents = fileCache.retrieveContents(); - contents.filterServerId(getServer().getServerId()); + contents.filterServerId(getServer().getServerId()).filterLifetime(); internalCache.fill(contents); consoleLog.log(Level.INFO, "[rscp] Loaded {0} entity, {1} permission and {2} inheritance rows from local cache.", new Integer[] diff --git a/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java b/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java index c8af30c..0274a91 100644 --- a/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java +++ b/src/main/java/ru/simsonic/rscPermissions/IndependentMain.java @@ -33,7 +33,7 @@ public class IndependentMain System.out.println("Loading permissions from json files."); final DatabaseContents contents = localJsn.retrieveContents(); System.out.println("Filter and calculating permission tree."); - contents.filterServerId("localtest"); + contents.filterServerId("localtest").filterLifetime(); intCache.fill(contents); 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 1d2f900..474b13e 100644 --- a/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java +++ b/src/main/java/ru/simsonic/rscPermissions/InternalCache/InternalCache.java @@ -1,9 +1,12 @@ package ru.simsonic.rscPermissions.InternalCache; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Map.Entry; import ru.simsonic.rscPermissions.API.EntityType; +import ru.simsonic.rscPermissions.API.PlayerType; import ru.simsonic.rscPermissions.API.RowEntity; import ru.simsonic.rscPermissions.API.RowInheritance; import ru.simsonic.rscPermissions.API.RowPermission; @@ -19,55 +22,160 @@ public class InternalCache defaultInheritance.deriveInstance(); } private final HashMap entities_g = new HashMap<>(); - private final HashMap entities_u = 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 static class InheritanceLeaf implements Comparable - { - public RowInheritance node; - public String instantiator; - public InheritanceLeaf[] subleafs; - public String prefix; - public String suffix; - @Override - public int compareTo(InheritanceLeaf other) + 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) + { + final HashSet names_u = new HashSet<>(); + final HashSet names_g = new HashSet<>(); + for(RowEntity row : contents.entities) + if(row.entityType == EntityType.group) + { + 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); + } + for(RowPermission row : contents.permissions) + if(row.entityType == EntityType.group) + names_g.add(row.entity.toLowerCase()); + else + names_u.add(row.entity); + for(RowInheritance row : contents.inheritance) { - return (other.node != null && node != null) ? other.node.compareTo(node) : 0; + names_g.add(row.parent.toLowerCase()); + if(row.childType == EntityType.group) + names_g.add(row.entity.toLowerCase()); + else + names_u.add(row.entity); } + for(String name : names_g) + if(!entities_g.containsKey(name)) + entities_g.put(name, new RowEntity()); + for(String name : names_u) + if(!entities_u.containsKey(name)) + entities_u.put(name, new RowEntity()); } - private final HashMap entityTrees = new HashMap<>(); - private final HashMap permissionsTreesG = new HashMap<>(); - private final HashMap permissionsTreesU = new HashMap<>(); - private final HashMap inheritanceTreesG = new HashMap<>(); - private final HashMap inheritanceTreesU = new HashMap<>(); - public synchronized void fill(DatabaseContents contents) + private void importPermissions(RowPermission[] rows) { - clear(); - if(contents.entities != null) - importEntities(contents.entities); - if(contents.permissions != null) - importPermissions(contents.permissions); - if(contents.inheritance != null) - importInheritance(contents.inheritance); - buildInheritanceForest(); + final ArrayList permissions_p2g = new ArrayList<>(); + final ArrayList permissions_p2u = new ArrayList<>(); + for(RowPermission row : rows) + if(row.entityType == EntityType.group) + permissions_p2g.add(row); + else + permissions_p2u.add(row); + for(String entry : entities_g.keySet()) + { + final ArrayList permissions = new ArrayList<>(); + for(RowPermission row : permissions_p2g) + if(row.entity.toLowerCase().equals(entry)) + permissions.add(row); + entities_g.get(entry).permissions = permissions.toArray(new RowPermission[permissions.size()]); + } + for(String entry : entities_u.keySet()) + { + final ArrayList permissions = new ArrayList<>(); + for(RowPermission row : permissions_p2u) + if(row.entity.equals(entry)) + permissions.add(row); + entities_u.get(entry).permissions = permissions.toArray(new RowPermission[permissions.size()]); + } + } + private void importInheritance(RowInheritance[] rows) + { + final ArrayList inheritance_g2g = new ArrayList<>(); + final ArrayList inheritance_g2u = new ArrayList<>(); + for(RowInheritance row : rows) + if(row.childType == EntityType.group) + inheritance_g2g.add(row); + else + inheritance_g2u.add(row); + for(Entry entry : entities_g.entrySet()) + { + final ArrayList inheritances = new ArrayList<>(); + final String name = entry.getKey(); + for(RowInheritance row : inheritance_g2g) + if(row.entity.toLowerCase().equals(name)) + inheritances.add(row); + entry.getValue().inheritance = inheritances.toArray(new RowInheritance[inheritances.size()]); + } + for(Entry entry : entities_u.entrySet()) + { + final ArrayList inheritance = 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()]); + } } - public synchronized ResolutionResult resolvePlayer(String player, String serverId) + public synchronized ResolutionResult resolvePlayer(String player) { - return resolvePlayer(new String[] { player }, serverId); + return resolvePlayer(new String[] { player }); } - public synchronized ResolutionResult resolvePlayer(String[] player, String serverId) + public synchronized ResolutionResult resolvePlayer(String[] player) { final ResolutionParams params = new ResolutionParams(); params.applicableIdentifiers = player; params.destRegions = new String[] {}; // params.destWorld = ""; - params.destServerId = serverId; // 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)); + } + 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; + } + 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 @@ -85,34 +193,6 @@ public class InternalCache intermediateResults.clear(); return result; } - private void importEntities(RowEntity[] rows) - { - for(RowEntity row : rows) - { - if(row.entityType == EntityType.group) - entities_g.put(row.entity.toLowerCase(), row); - else - entities_u.put(row.entity.toLowerCase(), row); - } - } - private void importPermissions(RowPermission[] rows) - { - for(RowPermission row : rows) - { - if(row.entityType == EntityType.group) - permissions_p2g.add(row); - else - permissions_p2u.add(row); - } - } - private void importInheritance(RowInheritance[] rows) - { - for(RowInheritance row : rows) - if(row.childType == EntityType.group) - inheritance_g2g.add(row); - else - inheritance_g2u.add(row); - } // FROM HERE I SHOULD MAKE IT WORKING private void buildInheritanceForest() { @@ -143,7 +223,7 @@ public class InternalCache } final ArrayList parents = new ArrayList<>(); for(RowInheritance row : inheritance_g2g) - if(row.parent.equalsIgnoreCase(source.entity)) + if(row.parentEntity.equalsIgnoreCase(source.entity)) parents.add(row); Collections.sort(parents); final ArrayList subleafs = new ArrayList<>(); @@ -152,7 +232,7 @@ public class InternalCache result.subleafs = subleafs.toArray(new InheritanceLeaf[subleafs.size()]); return result; } - private ResolutionResult resolveBranch(ResolutionParams params, InheritanceLeaf branch, String instantiator) + private ResolutionResult resolveBranch(ResolutionParams params, RowInheritance[] rows, String instantiator) { final ArrayList intermediateResults = new ArrayList<>(); for(InheritanceLeaf subleaf : branch.subleafs) @@ -166,31 +246,32 @@ public class InternalCache intermediateResults.clear(); return result; } - private ResolutionResult processResultColumn(ResolutionParams params, ArrayList resultList, String instantiator) + */ + private ResolutionResult processResultColumn(ResolutionParams params, ArrayList intermediate) { - switch(resultList.size()) + switch(intermediate.size()) { case 0: return new ResolutionResult(); case 1: - return resultList.get(0); + return intermediate.get(0); default: final ResolutionResult result = new ResolutionResult(); final ArrayList permissions = new ArrayList<>(); result.prefix = ""; result.suffix = ""; - for(ResolutionResult intermediate : resultList) + for(ResolutionResult oneOf : intermediate) { // Prefixes & suffixes - if(intermediate.prefix != null && !"".equals(intermediate.prefix)) - result.prefix = result.prefix.replace("%", result.prefix); - if(intermediate.suffix != null && !"".equals(intermediate.suffix)) - result.suffix = result.suffix.replace("%", result.suffix); - result.prefix = result.prefix.replace(Settings.instantiator, instantiator); - result.suffix = result.suffix.replace(Settings.instantiator, instantiator); + 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 : intermediate.permissions) - if(isPermissionApplicable(params, permission, instantiator)) + for(RowPermission permission : oneOf.permissions) + if(isPermissionApplicable(params, permission, params.instantiator)) permissions.add(permission); } result.permissions = permissions.toArray(new RowPermission[permissions.size()]); @@ -217,9 +298,11 @@ public class InternalCache { 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 29f0582..0bef1a5 100644 --- a/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java +++ b/src/main/java/ru/simsonic/rscPermissions/InternalCache/ResolutionParams.java @@ -1,10 +1,12 @@ package ru.simsonic.rscPermissions.InternalCache; +import ru.simsonic.rscPermissions.API.RowEntity; public class ResolutionParams { public String[] applicableIdentifiers; public String[] destRegions; public String destWorld; - public String destServerId; public int expirience; + protected transient RowEntity parentEntity; + protected transient String instantiator; }