You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
8.8 KiB
238 lines
8.8 KiB
package ru.simsonic.rscPermissions.InternalCache; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.HashMap; |
|
import java.util.HashSet; |
|
import ru.simsonic.rscPermissions.API.EntityType; |
|
import ru.simsonic.rscPermissions.API.RowEntity; |
|
import ru.simsonic.rscPermissions.API.RowInheritance; |
|
import ru.simsonic.rscPermissions.API.RowPermission; |
|
import ru.simsonic.rscPermissions.API.Settings; |
|
import ru.simsonic.rscPermissions.Backends.DatabaseContents; |
|
|
|
public class InternalCache |
|
{ |
|
public InternalCache() |
|
{ |
|
} |
|
protected final RowInheritance defaultInheritance = new RowInheritance(); |
|
public void setDefaultGroup(String defaultGroup) |
|
{ |
|
defaultInheritance.parent = defaultGroup; |
|
defaultInheritance.deriveInstance(); |
|
} |
|
protected final HashMap<String, RowEntity> entities_g = new HashMap<>(); |
|
protected final HashMap<String, RowEntity> entities_u = new HashMap<>(); |
|
protected final ArrayList<RowPermission> permissions_p2g = new ArrayList<>(); |
|
protected final ArrayList<RowPermission> permissions_p2u = new ArrayList<>(); |
|
protected final ArrayList<RowInheritance> inheritance_g2g = new ArrayList<>(); |
|
protected final ArrayList<RowInheritance> inheritance_g2u = new ArrayList<>(); |
|
public static class InheritanceLeaf implements Comparable<InheritanceLeaf> |
|
{ |
|
public RowInheritance node; |
|
public String instantiator; |
|
public InheritanceLeaf[] subleafs; |
|
public String prefix; |
|
public String suffix; |
|
@Override |
|
public int compareTo(InheritanceLeaf other) |
|
{ |
|
return (other.node != null && node != null) ? other.node.compareTo(node) : 0; |
|
} |
|
} |
|
final HashMap<String, InheritanceLeaf> entityTrees = new HashMap<>(); |
|
// Права по сущностям |
|
final HashMap<String, RowPermission[]> groupPermissions = new HashMap<>(); |
|
final HashMap<String, RowPermission[]> playerPermissions = new HashMap<>(); |
|
private void buildEntityTree() |
|
{ |
|
final HashSet<String> entitiesWhichInherits = new HashSet<>(); |
|
for(RowInheritance row : inheritance_g2u) |
|
entitiesWhichInherits.add(row.entity); |
|
for(String inheritingEntity : entitiesWhichInherits) |
|
{ |
|
final ArrayList<RowInheritance> 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)); |
|
} |
|
} |
|
private InheritanceLeaf buildBranch(RowInheritance source) |
|
{ |
|
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<RowInheritance> parents = new ArrayList<>(); |
|
for(RowInheritance row : inheritance_g2g) |
|
if(row.parent.equalsIgnoreCase(source.entity)) |
|
parents.add(row); |
|
Collections.sort(parents); |
|
final ArrayList<InheritanceLeaf> subleafs = new ArrayList<>(); |
|
for(RowInheritance row : parents) |
|
subleafs.add(buildBranch(row)); |
|
result.subleafs = subleafs.toArray(new InheritanceLeaf[subleafs.size()]); |
|
return result; |
|
} |
|
public synchronized ResolutionResult resolvePlayer(String player, String serverId) |
|
{ |
|
return resolvePlayer(new String[] { player }, serverId); |
|
} |
|
public synchronized ResolutionResult resolvePlayer(String[] player, String serverId) |
|
{ |
|
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<InheritanceLeaf> 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<ResolutionResult> 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; |
|
} |
|
private ResolutionResult resolveBranch(ResolutionParams params, InheritanceLeaf branch, String instantiator) |
|
{ |
|
final ArrayList<ResolutionResult> intermediateResults = new ArrayList<>(); |
|
for(InheritanceLeaf subleaf : branch.subleafs) |
|
{ |
|
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 ResolutionResult result = processResultColumn(params, intermediateResults, branch.instantiator); |
|
intermediateResults.clear(); |
|
return result; |
|
} |
|
private ResolutionResult processResultColumn(ResolutionParams params, ArrayList<ResolutionResult> resultList, String instantiator) |
|
{ |
|
switch(resultList.size()) |
|
{ |
|
case 0: |
|
return new ResolutionResult(); |
|
case 1: |
|
return resultList.get(0); |
|
default: |
|
final ResolutionResult result = new ResolutionResult(); |
|
final ArrayList<RowPermission> permissions = new ArrayList<>(); |
|
result.prefix = ""; |
|
result.suffix = ""; |
|
for(ResolutionResult intermediate : resultList) |
|
{ |
|
// 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); |
|
// Permissions |
|
for(RowPermission permission : intermediate.permissions) |
|
if(isPermissionApplicable(params, permission, instantiator)) |
|
permissions.add(permission); |
|
} |
|
result.permissions = permissions.toArray(new RowPermission[permissions.size()]); |
|
return result; |
|
} |
|
} |
|
private boolean isPermissionApplicable(ResolutionParams params, RowPermission row, String instantiator) |
|
{ |
|
if(params.expirience < row.expirience) |
|
return false; |
|
return row.destination.isWorldApplicable(params.destWorld, instantiator) |
|
? row.destination.isRegionApplicable(params.destRegions, instantiator) |
|
: false; |
|
} |
|
private boolean isInheritanceApplicable(ResolutionParams params, RowInheritance row, String instantiator) |
|
{ |
|
if(params.expirience < row.expirience) |
|
return false; |
|
return row.destination.isWorldApplicable(params.destWorld, instantiator) |
|
? row.destination.isRegionApplicable(params.destRegions, instantiator) |
|
: false; |
|
} |
|
public synchronized void fill(DatabaseContents contents) |
|
{ |
|
importEntities(contents.entities); |
|
importPermissions(contents.permissions); |
|
importInheritance(contents.inheritance); |
|
} |
|
private int importEntities(RowEntity[] rows) |
|
{ |
|
entities_g.clear(); |
|
entities_u.clear(); |
|
if(rows == null) |
|
return 0; |
|
for(RowEntity row : rows) |
|
{ |
|
if(row.entityType == EntityType.group) |
|
entities_g.put(row.entity.toLowerCase(), row); |
|
else |
|
entities_u.put(row.entity.toLowerCase(), row); |
|
} |
|
return entities_g.size() + entities_u.size(); |
|
} |
|
private int importPermissions(RowPermission[] rows) |
|
{ |
|
permissions_p2g.clear(); |
|
permissions_p2u.clear(); |
|
if(rows == null) |
|
return 0; |
|
for(RowPermission row : rows) |
|
{ |
|
if(row.entityType == EntityType.group) |
|
permissions_p2g.add(row); |
|
else |
|
permissions_p2u.add(row); |
|
} |
|
return permissions_p2g.size() + permissions_p2u.size(); |
|
} |
|
private int importInheritance(RowInheritance[] rows) |
|
{ |
|
inheritance_g2g.clear(); |
|
inheritance_g2u.clear(); |
|
if(rows == null) |
|
return 0; |
|
for(RowInheritance row : rows) |
|
{ |
|
if(row.childType == EntityType.group) |
|
inheritance_g2g.add(row); |
|
else |
|
inheritance_g2u.add(row); |
|
} |
|
return inheritance_g2g.size() + inheritance_g2u.size(); |
|
} |
|
public synchronized void clear() |
|
{ |
|
entities_g.clear(); |
|
entities_u.clear(); |
|
permissions_p2g.clear(); |
|
permissions_p2u.clear(); |
|
inheritance_g2g.clear(); |
|
inheritance_g2u.clear(); |
|
} |
|
}
|
|
|