diff --git a/Figures for documentation/ladders_explained.png b/Figures for documentation/ladders_explained.png
deleted file mode 100644
index 1de3ad5..0000000
Binary files a/Figures for documentation/ladders_explained.png and /dev/null differ
diff --git a/Figures for documentation/rscPermissions-WebUI Concept.png b/Figures for documentation/rscPermissions-WebUI Concept.png
deleted file mode 100644
index 286ac97..0000000
Binary files a/Figures for documentation/rscPermissions-WebUI Concept.png and /dev/null differ
diff --git a/pom.xml b/pom.xml
index a6b9524..32eaf42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
ru.simsonic
rscPermissions
- 0.9.10a
+ 0.9.11a
jar
rscPermissions
diff --git a/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java b/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java
index 007adc6..06530ac 100644
--- a/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java
+++ b/src/main/java/ru/simsonic/rscPermissions/API/PlayerType.java
@@ -1,14 +1,13 @@
package ru.simsonic.rscPermissions.API;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import ru.simsonic.rscPermissions.Engine.Matchers;
public enum PlayerType
{
NAME(0), // 16 chars max
- HYPHENATED_UUID(1), // 550e8400-e29b-41d4-a716-446655440000
- DEHYPHENATED_UUID(2), // 550e8400e29b41d4a716446655440000
+ UUID(1), // 550e8400-e29b-41d4-a716-446655440000
+ DASHLESS_UUID(2), // 550e8400e29b41d4a716446655440000
INTERNET_WILDCARD(3), // 192.168.*.*
- INTERNET_SUBNETMASK(4), // 192.168.1.0/16
+ INTERNET_SUBNETMASK(4), // 192.168.0.0/16
INAPPLICABLE(-1);
private final int value;
private PlayerType(int value)
@@ -22,87 +21,22 @@ public enum PlayerType
return constant;
return INAPPLICABLE;
}
- private static final Pattern nicknameRegExp = Pattern.compile("^[a-zA-Z0-9_-]{3,16}$");
- private static final Pattern hyphenatedRegExp = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
- private static final Pattern dehyphenatedRegExp = Pattern.compile("^[0-9a-f]{32}$");
- private static final Pattern ipWildcardRegExp = Pattern.compile("^"
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)$");
- private static final Pattern ipSubnetMaskRegExp = Pattern.compile("^"
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
- + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
- + "(?:/([0-9]|[1-2][0-9]|3[0-2]))$");
public static PlayerType scanPlayerEntity(String entity)
{
if(entity == null || "".equals(entity))
return NAME;
- if(nicknameRegExp.matcher(entity).matches())
+ if(Matchers.isCorrectNickname(entity))
return NAME;
- if(hyphenatedRegExp.matcher(entity.toLowerCase()).matches())
- return HYPHENATED_UUID;
- if(dehyphenatedRegExp.matcher(entity.toLowerCase()).matches())
- return DEHYPHENATED_UUID;
- /*
- final Matcher mIP1 = ipWildcardRegExp.matcher(entity);
- if(mIP1.matches())
- {
- final String a1 = mIP1.group(1);
- final String a2 = mIP1.group(2);
- final String a3 = mIP1.group(3);
- final String a4 = mIP1.group(4);
- // TO DO
- long address = 0, mask = 0;
+ if(Matchers.isCorrectUUID(entity))
+ return UUID;
+ if(Matchers.isCorrectDashlessUUID(entity))
+ return DASHLESS_UUID;
+ if(Matchers.isCorrectWildcard(entity))
return INTERNET_WILDCARD;
- }
- final Matcher mIP2 = ipSubnetMaskRegExp.matcher(entity);
- if(mIP2.matches())
- {
- final String a1 = mIP1.group(1);
- final String a2 = mIP1.group(2);
- final String a3 = mIP1.group(3);
- final String a4 = mIP1.group(4);
- final String sn = mIP1.group(5);
- // TO DO
- long address = 0, mask = 0;
+ if(Matchers.isCorrectSubnetMask(entity))
return INTERNET_SUBNETMASK;
- }
- */
return INAPPLICABLE;
}
- /*
- public static void getAddressDetails(String entity, RowPermission row)
- {
- final Matcher mIP1 = ipWildcardRegExp.matcher(entity);
- if(mIP1.matches())
- {
- final String a1 = mIP1.group(1);
- final String a2 = mIP1.group(2);
- final String a3 = mIP1.group(3);
- final String a4 = mIP1.group(4);
- // TO DO
- if("*".equals(a1))
- {
- } else {
- }
- long address = 0, mask = 0;
- }
- final Matcher mIP2 = ipSubnetMaskRegExp.matcher(entity);
- if(mIP2.matches())
- {
- final String a1 = mIP1.group(1);
- final String a2 = mIP1.group(2);
- final String a3 = mIP1.group(3);
- final String a4 = mIP1.group(4);
- final String sn = mIP1.group(5);
- // TO DO
- long address = 0, mask = 0;
- }
- }
- */
public boolean isEntityApplicable(String entity, String identifier)
{
if(entity == null || "".equals(entity) || identifier == null || "".equals(identifier))
@@ -111,9 +45,9 @@ public enum PlayerType
{
case NAME:
return identifier.equals(entity);
- case HYPHENATED_UUID:
+ case UUID:
identifier = identifier.replace("-", "");
- case DEHYPHENATED_UUID:
+ case DASHLESS_UUID:
return entity.equalsIgnoreCase(identifier);
}
return false;
diff --git a/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java b/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java
index dbff862..37ff9fb 100644
--- a/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java
+++ b/src/main/java/ru/simsonic/rscPermissions/API/RowInheritance.java
@@ -52,9 +52,9 @@ public class RowInheritance implements Cloneable, Comparable
{
case NAME:
return entity.equals(identifier);
- case HYPHENATED_UUID:
+ case UUID:
identifier = identifier.replace("-", "");
- case DEHYPHENATED_UUID:
+ case DASHLESS_UUID:
return entity.equals(identifier);
}
// TO DO
diff --git a/src/main/java/ru/simsonic/rscPermissions/API/Settings.java b/src/main/java/ru/simsonic/rscPermissions/API/Settings.java
index 2d1346e..14fa0d8 100644
--- a/src/main/java/ru/simsonic/rscPermissions/API/Settings.java
+++ b/src/main/java/ru/simsonic/rscPermissions/API/Settings.java
@@ -4,11 +4,12 @@ import ru.simsonic.rscUtilityLibrary.ConnectionMySQL.ConnectionParams;
public interface Settings
{
- public static final String chatPrefix = "{GOLD}[rscp] {_LS}";
+ public static final String chatPrefix = "{GOLD}[rscp] {_LS}";
public static final String separator = ".";
public static final String separatorRegExp = "\\.";
public static final String instantiator = "?";
public static final String textInheriter = "%";
+ public static final char groupLevelTab = '┏';
public static final boolean decolorizeForConsole = false;
public void onLoad();
public void readSettings();
diff --git a/src/main/java/ru/simsonic/rscPermissions/Bukkit/Commands/BukkitCommands.java b/src/main/java/ru/simsonic/rscPermissions/Bukkit/Commands/BukkitCommands.java
index 3e0cd7a..76dddf6 100644
--- a/src/main/java/ru/simsonic/rscPermissions/Bukkit/Commands/BukkitCommands.java
+++ b/src/main/java/ru/simsonic/rscPermissions/Bukkit/Commands/BukkitCommands.java
@@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import ru.simsonic.rscPermissions.API.Settings;
import ru.simsonic.rscPermissions.BukkitPluginMain;
+import ru.simsonic.rscPermissions.Engine.Matchers;
import ru.simsonic.rscPermissions.Engine.ResolutionResult;
import ru.simsonic.rscUtilityLibrary.Bukkit.Commands.CommandAnswerException;
import ru.simsonic.rscUtilityLibrary.RestartableThread;
@@ -115,7 +116,7 @@ public class BukkitCommands
help.add("{_YL}/rscp fetch {_LS}-- reread all permissions from database");
help.add("{_YL}/rscp reload {_LS}-- reload config and restart the plugin");
}
- help.add("{_YL}/rscp [help] {_LS}-- show this help page");
+ help.add("{_YL}/rscp help {_LS}-- show this help page");
switch(args[0].toLowerCase())
{
case "user":
@@ -184,6 +185,8 @@ public class BukkitCommands
? rscp.permissionManager.getResult(player)
: rscp.permissionManager.getResult(args[1]);
final ArrayList answer = new ArrayList<>();
+ if(Matchers.isCorrectDashlessUUID(args[1]))
+ args[1] = Matchers.uuidAddDashes(args[1]);
switch(args[2].toLowerCase())
{
case "lp":
diff --git a/src/main/java/ru/simsonic/rscPermissions/Engine/InternalCache.java b/src/main/java/ru/simsonic/rscPermissions/Engine/InternalCache.java
index 6454317..dab6f69 100644
--- a/src/main/java/ru/simsonic/rscPermissions/Engine/InternalCache.java
+++ b/src/main/java/ru/simsonic/rscPermissions/Engine/InternalCache.java
@@ -222,9 +222,7 @@ public class InternalCache
intermediateResults.add(resolveParent(params));
}
params.depth -= 1;
- params.groupList.add(
- new String(new char[params.depth]).replace('\0', '*')
- + currentParent.entity
+ params.groupList.add(depthPrefix(params.depth) + currentParent.entity
+ ("".equals(instantiator) ? "" : Settings.separator + instantiator));
// Prefixes and suffixes
params.parentEntity = currentParent;
@@ -235,6 +233,16 @@ public class InternalCache
processPermissions(params, Arrays.asList(currentParent.permissions));
return result;
}
+ private String depthPrefix(int depth)
+ {
+ if(depth > 0)
+ {
+ final char[] levelParent = new char[depth];
+ levelParent[depth - 1] = Settings.groupLevelTab;
+ return new String(levelParent).replace('\0', ' ');
+ }
+ return "";
+ }
private ResolutionResult processPrefixesAndSuffixes(ResolutionParams params, ArrayList intermediate)
{
final ResolutionResult result = new ResolutionResult();
diff --git a/src/main/java/ru/simsonic/rscPermissions/Engine/Matchers.java b/src/main/java/ru/simsonic/rscPermissions/Engine/Matchers.java
index fbd5645..d5733f6 100644
--- a/src/main/java/ru/simsonic/rscPermissions/Engine/Matchers.java
+++ b/src/main/java/ru/simsonic/rscPermissions/Engine/Matchers.java
@@ -1,7 +1,8 @@
package ru.simsonic.rscPermissions.Engine;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class Matchers
+public final class Matchers
{
private static final String genericSplitter = "\\s*[;,\\r\\n\\s]+\\s*";
public static String[] genericParse(String multiobject)
@@ -10,12 +11,117 @@ public class Matchers
multiobject = "";
return multiobject.split(genericSplitter);
}
- private static final Pattern patternUUID = Pattern.compile(
- "^(?:[a-f\\d]{8}(?:-[a-f\\d]{4}){3}-[a-f\\d]{12})$");
- private static boolean isCorrectUUID(String entityName)
+ private static final Pattern NICKNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]{3,16}$");
+ public static boolean isCorrectNickname(String entityName)
{
- if(entityName == null)
+ if(entityName == null || "".equals(entityName))
return false;
- return patternUUID.matcher(entityName).find();
+ return NICKNAME_PATTERN.matcher(entityName).matches();
}
+ private static final Pattern UUID_PATTERN = Pattern.compile("^(?:[a-f\\d]{8}(?:-[a-f\\d]{4}){3}-[a-f\\d]{12})$");
+ private static final Pattern DASHLESS_UUID_PATTERN = Pattern.compile("^([A-Fa-f0-9]{8})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{12})$");
+ public static boolean isCorrectUUID(String entityName)
+ {
+ if(entityName == null || "".equals(entityName))
+ return false;
+ entityName = entityName.toLowerCase();
+ return UUID_PATTERN.matcher(entityName).matches();
+ }
+ public static boolean isCorrectDashlessUUID(String entityName)
+ {
+ if(entityName == null || "".equals(entityName))
+ return false;
+ entityName = entityName.toLowerCase();
+ return DASHLESS_UUID_PATTERN.matcher(entityName).matches();
+ }
+ public static String uuidRemoveDashes(String uuid) throws IllegalArgumentException
+ {
+ if(!isCorrectUUID(uuid) && !isCorrectDashlessUUID(uuid))
+ throw new IllegalArgumentException("Invalid UUID format");
+ return uuid.replace("-", "").toLowerCase();
+
+ }
+ public static String uuidAddDashes(String uuid) throws IllegalArgumentException
+ {
+ if(!isCorrectUUID(uuid) && !isCorrectDashlessUUID(uuid))
+ throw new IllegalArgumentException("Invalid UUID format");
+ final Matcher matcher = DASHLESS_UUID_PATTERN.matcher(uuidRemoveDashes(uuid));
+ return matcher.replaceAll("$1-$2-$3-$4-$5").toLowerCase();
+ }
+ private static final Pattern WILDCARD_PATTERN = Pattern.compile("^"
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|\\*)$");
+ private static final Pattern SUBNETMASK_PATTERN = Pattern.compile("^"
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\."
+ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
+ + "(?:/([0-9]|[1-2][0-9]|3[0-2]))$");
+ public static boolean isCorrectWildcard(String wildcard)
+ {
+ /*
+ final Matcher mIP1 = ipWildcardRegExp.matcher(entity);
+ if(mIP1.matches())
+ {
+ final String a1 = mIP1.group(1);
+ final String a2 = mIP1.group(2);
+ final String a3 = mIP1.group(3);
+ final String a4 = mIP1.group(4);
+ // TO DO
+ long address = 0, mask = 0;
+ return INTERNET_WILDCARD;
+ }
+ */
+ return false;
+ }
+ public static boolean isCorrectSubnetMask(String wildcard)
+ {
+ /*
+ final Matcher mIP2 = ipSubnetMaskRegExp.matcher(entity);
+ if(mIP2.matches())
+ {
+ final String a1 = mIP1.group(1);
+ final String a2 = mIP1.group(2);
+ final String a3 = mIP1.group(3);
+ final String a4 = mIP1.group(4);
+ final String sn = mIP1.group(5);
+ // TO DO
+ long address = 0, mask = 0;
+ return INTERNET_SUBNETMASK;
+ }
+ */
+ return false;
+ }
+ /*
+ public static void getAddressDetails(String entity, RowPermission row)
+ {
+ final Matcher mIP1 = ipWildcardRegExp.matcher(entity);
+ if(mIP1.matches())
+ {
+ final String a1 = mIP1.group(1);
+ final String a2 = mIP1.group(2);
+ final String a3 = mIP1.group(3);
+ final String a4 = mIP1.group(4);
+ // TO DO
+ if("*".equals(a1))
+ {
+ } else {
+ }
+ long address = 0, mask = 0;
+ }
+ final Matcher mIP2 = ipSubnetMaskRegExp.matcher(entity);
+ if(mIP2.matches())
+ {
+ final String a1 = mIP1.group(1);
+ final String a2 = mIP1.group(2);
+ final String a3 = mIP1.group(3);
+ final String a4 = mIP1.group(4);
+ final String sn = mIP1.group(5);
+ // TO DO
+ long address = 0, mask = 0;
+ }
+ }
+ */
}
diff --git a/src/main/resources/sqlt/Insert_example_rows_v1.sqlt b/src/main/resources/sqlt/Insert_example_rows_v1.sqlt
index 63d43c0..692008c 100644
--- a/src/main/resources/sqlt/Insert_example_rows_v1.sqlt
+++ b/src/main/resources/sqlt/Insert_example_rows_v1.sqlt
@@ -1,4 +1,4 @@
-INSERT INTO
+INSERT IGNORE INTO
`{DATABASE}`.`{PREFIX}entities`
(`entity`, `entity_type`, `prefix`, `suffix`)
VALUES
@@ -8,7 +8,7 @@ VALUES
('Moderators', b'0', '§r§b[Moderator]§6', '§r'),
('Administrators', b'0', '§r§c[Administrator]§6', '§r');
-INSERT INTO
+INSERT IGNORE INTO
`{DATABASE}`.`{PREFIX}permissions`
(`entity`, `entity_type`, `destination`, `permission`)
VALUES
@@ -22,20 +22,20 @@ VALUES
('rpgLevelHigh', b'0', '@RPG', 'third.plugin.superperm'),
('Donators', b'0', '', 'scavenger.scavenge');
-INSERT INTO
+INSERT IGNORE INTO
`{DATABASE}`.`{PREFIX}inheritance`
(`entity`, `parent`, `inheritance_type`, `destination`, `expirience`)
VALUES
- ('Moderators', 'Administrators', b'0', '', NULL),
- ('Default', 'rpgLevelLow', b'0', '@RPG', '10'),
- ('Default', 'rpgLevelMedium', b'0', '@RPG', '100'),
- ('Default', 'rpgLevelHigh', b'0', '@RPG', '1000'),
- ('rpgOutcasts', 'Default', b'0', '@RPG', NULL),
- ('rpgTramps', 'Default', b'0', '@RPG', NULL),
- ('rpgCitizens', 'rpgTramps', b'0', '@RPG', NULL),
- ('rpgElites', 'rpgCitizens', b'0', '@RPG', NULL),
- ('rpgHeads', 'rpgElites', b'0', '@RPG', NULL),
- ('testplayer', 'Donators', b'1', '@RPG', NULL);
+ ('Moderators', 'Administrators', b'0', '', 0),
+ ('Default', 'rpgLevelLow', b'0', '@RPG', 10),
+ ('Default', 'rpgLevelMedium', b'0', '@RPG', 100),
+ ('Default', 'rpgLevelHigh', b'0', '@RPG', 1000),
+ ('rpgOutcasts', 'Default', b'0', '@RPG', 0),
+ ('rpgTramps', 'Default', b'0', '@RPG', 0),
+ ('rpgCitizens', 'rpgTramps', b'0', '@RPG', 0),
+ ('rpgElites', 'rpgCitizens', b'0', '@RPG', 0),
+ ('rpgHeads', 'rpgElites', b'0', '@RPG', 0),
+ ('testplayer', 'Donators', b'1', '@RPG', 0);
INSERT INTO
`{DATABASE}`.`{PREFIX}inheritance`