diff --git a/dependencies/factionsuuid/pom.xml b/dependencies/factionsuuid/pom.xml new file mode 100644 index 00000000..fe179b56 --- /dev/null +++ b/dependencies/factionsuuid/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + + fr.utarwyn + endercontainers + 2.2.3-SNAPSHOT + ../../pom.xml + + + endercontainers-dependency-factionsuuid + EnderContainers Dependency FactionsUUID + + + 1.6.9.5-U0.6.6 + + + + + enderzone + https://ci.ender.zone/plugin/repository/everything/ + + + + + + ${project.groupId} + endercontainers-api + 2.2.3-SNAPSHOT + + + com.massivecraft + Factions + ${factions.version} + provided + + + * + * + + + + + diff --git a/dependencies/factionsuuid/src/main/java/fr/utarwyn/endercontainers/dependency/FactionsUUIDDependency.java b/dependencies/factionsuuid/src/main/java/fr/utarwyn/endercontainers/dependency/FactionsUUIDDependency.java new file mode 100644 index 00000000..765c6bec --- /dev/null +++ b/dependencies/factionsuuid/src/main/java/fr/utarwyn/endercontainers/dependency/FactionsUUIDDependency.java @@ -0,0 +1,80 @@ +package fr.utarwyn.endercontainers.dependency; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.perms.PermissibleActions; +import fr.utarwyn.endercontainers.configuration.LocaleKey; +import fr.utarwyn.endercontainers.dependency.exceptions.BlockChestOpeningException; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.Collections; + +/** + * FactionsUUID dependency. Protect enderchests in enemy factions. + * Works with FactionsUUID: https://www.spigotmc.org/resources/factionsuuid.1035/ + * + * @author Utarwyn + * @since 2.2.3 + */ +public class FactionsUUIDDependency extends Dependency { + + /** + * Construct the FactionsUUID dependency object. + * + * @param plugin plugin instance + */ + public FactionsUUIDDependency(Plugin plugin) { + super(plugin); + } + + /** + * {@inheritDoc} + */ + @Override + public void validateBlockChestOpening(Block block, Player player) + throws BlockChestOpeningException { + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + + // Bypass the check? + if (fPlayer == null || fPlayer.isAdminBypassing()) return; + + // Init checking variables + Faction playerFac = fPlayer.getFaction(); + Faction currentFac = Board.getInstance().getFactionAt(new FLocation(block)); + + boolean playerFacIsReal = this.isRealFaction(playerFac); + boolean currentFacIsReal = this.isRealFaction(currentFac); + + // Check permission between the two factions if there are real + if (playerFacIsReal && currentFacIsReal) { + if (currentFac != playerFac || !playerFac.hasAccess(fPlayer, PermissibleActions.CONTAINER, new FLocation(block))) { + // Exception without message error in this case + throw new BlockChestOpeningException(); + } + } + // If the current player does not have a faction + // but trying to open a chest in a real faction + else if (currentFacIsReal) { + throw new BlockChestOpeningException( + LocaleKey.ERR_DEP_FACTIONS, + Collections.singletonMap("faction", currentFac.getTag()) + ); + } + } + + /** + * Checks if a faction is real or fictive. + * Handles Warzone, Safezone and Wilderness. + * + * @param faction faction to check + * @return true if the faction is real + */ + private boolean isRealFaction(Faction faction) { + return faction != null + && !faction.isWilderness() + && !faction.isWarZone() + && !faction.isSafeZone(); + } + +} diff --git a/plugin/pom.xml b/plugin/pom.xml index b0a0949b..5fc5b5dc 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -38,6 +38,12 @@ 2.2.3-SNAPSHOT + + ${project.groupId} + endercontainers-dependency-factionsuuid + 2.2.3-SNAPSHOT + + ${project.groupId} endercontainers-dependency-plotsquared diff --git a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependenciesManager.java b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependenciesManager.java index f20c6869..b5a3b79f 100644 --- a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependenciesManager.java +++ b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependenciesManager.java @@ -2,6 +2,7 @@ import fr.utarwyn.endercontainers.AbstractManager; import fr.utarwyn.endercontainers.dependency.exceptions.BlockChestOpeningException; +import fr.utarwyn.endercontainers.dependency.resolve.DependencyResolver; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; @@ -88,6 +89,7 @@ private void loadDependencies() { // Factions new DependencyResolver(this.pluginManager) .name("Factions") + .matchAuthor("mbaxter", FactionsUUIDDependency.class) .matchVersion("^1\\.6.*", Factions1Dependency.class) .matchVersion("^2.*", Factions2Dependency.class) .resolve().ifPresent(this::enableDependency); diff --git a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependencyResolver.java b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolver.java similarity index 72% rename from plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependencyResolver.java rename to plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolver.java index a9b37f95..fa3069ac 100644 --- a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/DependencyResolver.java +++ b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolver.java @@ -1,15 +1,15 @@ -package fr.utarwyn.endercontainers.dependency; +package fr.utarwyn.endercontainers.dependency.resolve; +import fr.utarwyn.endercontainers.dependency.Dependency; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; -import java.util.regex.Pattern; /** - * Resolve a dependency instance with a custom version matching. + * Resolve a dependency instance using custom matching patterns. * * @author Utarwyn * @since 2.2.0 @@ -24,7 +24,7 @@ public class DependencyResolver { /** * Patterns to match dependency's versions */ - private final Map> patterns; + private final List patterns; /** * Name of the dependency instance to build @@ -38,7 +38,7 @@ public class DependencyResolver { */ public DependencyResolver(PluginManager pluginManager) { this.pluginManager = pluginManager; - this.patterns = new HashMap<>(); + this.patterns = new ArrayList<>(); } /** @@ -61,7 +61,19 @@ public DependencyResolver name(String name) { * @return this instance */ public DependencyResolver matchVersion(String expression, Class clazz) { - this.patterns.put(Pattern.compile(expression), clazz); + this.patterns.add(new DependencyResolverPatternVersion(expression, clazz)); + return this; + } + + /** + * Match a specific dependency class from an author name. + * + * @param author dependency author to match + * @param clazz class to use for for the targeted author + * @return this instance + */ + public DependencyResolver matchAuthor(String author, Class clazz) { + this.patterns.add(new DependencyResolverPatternAuthor(author, clazz)); return this; } @@ -103,19 +115,10 @@ public Optional resolve() { * @return dependency instance if present */ private Optional constructInstance(Plugin plugin) { - String pluginVersion = plugin.getDescription().getVersion(); - - return this.patterns.entrySet().stream() - .filter(entry -> entry.getKey().matcher(pluginVersion).find()) - .map(Map.Entry::getValue) + return this.patterns.stream() + .filter(pattern -> pattern.matchWith(plugin)) .findFirst() - .map(clazz -> { - try { - return clazz.getDeclaredConstructor(Plugin.class).newInstance(plugin); - } catch (ReflectiveOperationException e) { - return null; - } - }); + .map(pattern -> pattern.construct(plugin)); } } diff --git a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPattern.java b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPattern.java new file mode 100644 index 00000000..bec02bf5 --- /dev/null +++ b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPattern.java @@ -0,0 +1,43 @@ +package fr.utarwyn.endercontainers.dependency.resolve; + +import fr.utarwyn.endercontainers.dependency.Dependency; +import org.bukkit.plugin.Plugin; + +/** + * Represents a custom matching + * pattern used to resolve a dependency. + * + * @author Utarwyn + * @since 2.2.3 + */ +public abstract class DependencyResolverPattern { + + private final Class clazz; + + public DependencyResolverPattern(Class clazz) { + this.clazz = clazz; + } + + /** + * Checks if a plugin matches with stored resolving pattern. + * + * @param plugin plugin to check + * @return true if plugin matches this pattern + */ + public abstract boolean matchWith(Plugin plugin); + + /** + * Constructs an instance of registered dependency class for this matcher. + * + * @param plugin plugin managed by the dependency + * @return constructed dependency instance + */ + public Dependency construct(Plugin plugin) { + try { + return this.clazz.getDeclaredConstructor(Plugin.class).newInstance(plugin); + } catch (ReflectiveOperationException e) { + throw new IllegalStateException("cannot instanciate dependency class", e); + } + } + +} diff --git a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternAuthor.java b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternAuthor.java new file mode 100644 index 00000000..fc6430a5 --- /dev/null +++ b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternAuthor.java @@ -0,0 +1,29 @@ +package fr.utarwyn.endercontainers.dependency.resolve; + +import fr.utarwyn.endercontainers.dependency.Dependency; +import org.bukkit.plugin.Plugin; + +/** + * Represents a dependency resolver using an author pattern. + * + * @author Utarwyn + * @since 2.2.3 + */ +public class DependencyResolverPatternAuthor extends DependencyResolverPattern { + + private final String author; + + public DependencyResolverPatternAuthor(String author, Class clazz) { + super(clazz); + this.author = author; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean matchWith(Plugin plugin) { + return plugin.getDescription().getAuthors().contains(this.author); + } + +} diff --git a/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternVersion.java b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternVersion.java new file mode 100644 index 00000000..d893ab8e --- /dev/null +++ b/plugin/src/main/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverPatternVersion.java @@ -0,0 +1,31 @@ +package fr.utarwyn.endercontainers.dependency.resolve; + +import fr.utarwyn.endercontainers.dependency.Dependency; +import org.bukkit.plugin.Plugin; + +import java.util.regex.Pattern; + +/** + * Represents a dependency resolver using a version pattern. + * + * @author Utarwyn + * @since 2.2.3 + */ +public class DependencyResolverPatternVersion extends DependencyResolverPattern { + + private final Pattern pattern; + + public DependencyResolverPatternVersion(String expression, Class clazz) { + super(clazz); + this.pattern = Pattern.compile(expression); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean matchWith(Plugin plugin) { + return this.pattern.matcher(plugin.getDescription().getVersion()).find(); + } + +} diff --git a/plugin/src/test/java/fr/utarwyn/endercontainers/dependency/DependencyResolverTest.java b/plugin/src/test/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverTest.java similarity index 79% rename from plugin/src/test/java/fr/utarwyn/endercontainers/dependency/DependencyResolverTest.java rename to plugin/src/test/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverTest.java index 8b907b81..2d017b5e 100644 --- a/plugin/src/test/java/fr/utarwyn/endercontainers/dependency/DependencyResolverTest.java +++ b/plugin/src/test/java/fr/utarwyn/endercontainers/dependency/resolve/DependencyResolverTest.java @@ -1,5 +1,6 @@ -package fr.utarwyn.endercontainers.dependency; +package fr.utarwyn.endercontainers.dependency.resolve; +import fr.utarwyn.endercontainers.dependency.Dependency; import fr.utarwyn.endercontainers.mock.DependencyMock; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; @@ -10,6 +11,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.util.Collections; import java.util.Optional; import static org.assertj.core.api.Assertions.*; @@ -30,6 +32,7 @@ public void setUp() { // Create a fake description file for the plugin PluginDescriptionFile descriptionFile = mock(PluginDescriptionFile.class); when(descriptionFile.getVersion()).thenReturn("1.12.5"); + when(descriptionFile.getAuthors()).thenReturn(Collections.singletonList("Utarwyn")); // Plugin manager stubs when(this.plugin.getDescription()).thenReturn(descriptionFile); @@ -56,7 +59,9 @@ public void resolveFailure() { // Wrong dependency class with enabled plugin resolver.name("Plugin"); - assertThat(resolver.resolve()).isEmpty(); + assertThatIllegalStateException().isThrownBy(resolver::resolve) + .withCauseInstanceOf(ReflectiveOperationException.class) + .withMessageContaining("cannot instanciate"); } @Test @@ -89,4 +94,14 @@ public void resolveWithMatcher() { assertThat(resolver.resolve()).isNotEmpty(); } + @Test + public void resolvingOrder() { + DependencyResolver resolver = new DependencyResolver(this.pluginManager) + .name("Plugin") + .matchAuthor("Utarwyn", DependencyMock.class) + .use(null); + + assertThat(resolver.resolve()).isNotEmpty(); + } + } diff --git a/pom.xml b/pom.xml index f1b3bc37..2ff101b4 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,7 @@ api dependencies/Factions1 dependencies/Factions2 + dependencies/FactionsUUID dependencies/PlotSquared dependencies/WorldGuard6 dependencies/WorldGuard7