Skip to content

Commit

Permalink
Update method of specifying modules for initialization, add permissio…
Browse files Browse the repository at this point in the history
…n service suggestions
  • Loading branch information
NickImpact committed Nov 18, 2023
1 parent 873d4a3 commit 6c843f3
Show file tree
Hide file tree
Showing 14 changed files with 380 additions and 137 deletions.
12 changes: 6 additions & 6 deletions impactor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ dependencies {
}

// Databases
api("com.zaxxer:HikariCP:4.0.3")
api("com.zaxxer:HikariCP:5.0.1")
api("com.h2database:h2:2.1.214")
api("mysql:mysql-connector-java:8.0.32")
api("mysql:mysql-connector-java:8.0.33")
api("org.mariadb.jdbc:mariadb-java-client:3.1.2")
api("org.mongodb:mongo-java-driver:3.12.2")
api("org.mongodb:mongo-java-driver:3.12.12")

api("com.github.ben-manes.caffeine:caffeine:2.9.3")
api("com.github.ben-manes.caffeine:caffeine:3.1.5")
implementation("io.github.classgraph:classgraph:4.8.157")
implementation("net.luckperms:api:5.4")
implementation("me.lucko:spark-api:0.1-SNAPSHOT")
Expand All @@ -44,8 +44,8 @@ dependencies {
testImplementation("net.kyori:adventure-text-serializer-ansi:4.14.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
testImplementation("org.mockito:mockito-core:4.7.0")
testRuntimeOnly("org.apache.logging.log4j:log4j-core:2.19.0")
testImplementation("org.mockito:mockito-core:5.2.0")
testRuntimeOnly("org.apache.logging.log4j:log4j-core:2.20.0")
}

tasks.withType(Test::class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import net.impactdev.impactor.core.commands.pagination.PaginationCommands;
import net.impactdev.impactor.core.commands.translations.TranslationCommands;
import net.impactdev.impactor.core.modules.ImpactorModule;
import net.impactdev.impactor.core.platform.commands.PlatformCommands;
import net.kyori.event.EventBus;

public final class CommandsModule implements ImpactorModule {
Expand All @@ -41,6 +42,7 @@ public void subscribe(EventBus<ImpactorEvent> bus) {
event.register(EconomyCommands.class);
event.register(PaginationCommands.class);
event.register(TranslationCommands.class);
event.register(PlatformCommands.class);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* This file is part of Impactor, licensed under the MIT License (MIT).
*
* Copyright (c) 2018-2022 NickImpact
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package net.impactdev.impactor.core.modules;

import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfoList;
import io.github.classgraph.ScanResult;
import net.impactdev.impactor.api.Impactor;
import net.impactdev.impactor.api.logging.PluginLogger;
import net.impactdev.impactor.api.utility.ExceptionPrinter;

import java.util.LinkedList;
import java.util.Queue;

public final class ModuleInitializer {

public Queue<Class<? extends ImpactorModule>> definitions = new LinkedList<>();
public Queue<ImpactorModule> modules = new LinkedList<>();

public ModuleInitializer with(Class<? extends ImpactorModule> module) {
this.definitions.add(module);
return this;
}

public void construct(Impactor service) throws Exception {
while(!this.definitions.isEmpty()) {
Class<? extends ImpactorModule> type = this.definitions.poll();
ImpactorModule module = type.getConstructor().newInstance();

module.factories(service.factories());
module.builders(service.builders());
module.services(service.services());
module.subscribe(service.events());

this.modules.add(module);
}
}

public void initialize(Impactor service, PluginLogger logger) throws Exception {
while(!this.modules.isEmpty()) {
ImpactorModule module = this.modules.poll();
module.init(service, logger);
}
}

/**
* For 1.16.5, this code works perfectly in a non-forge environment. However, with forge, there's
* a discrepancy with the TransformingClassLoader which prevents this tool from finding
* the class file assets. Per forums, this should be fixed with 1.17.1+ due to forge switching
* to the java module system. This code will be reactivated then, but for now, we are stuck with a
* manual solution.
* <p>
* This problem affects sponge and forge only (SpongeForge, SpongeVanilla, Forge).
*/
private void initializeModules(Impactor service) {
ClassGraph graph = new ClassGraph()
.acceptPackages("net.impactdev.impactor")
.overrideClassLoaders(this.getClass().getClassLoader());

try (ScanResult scan = graph.scan()) {
ClassInfoList list = scan.getClassesImplementing(ImpactorModule.class);
//this.bootstrapper.logger().info("Scan complete, found " + list.size() + " modules, now loading...");
list.stream()
.map(info -> info.loadClass(ImpactorModule.class))
.map(type -> {
try {
return type.getConstructor().newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
})
.forEach(module -> {
module.factories(service.factories());
module.builders(service.builders());
module.services(service.services());
});
//this.bootstrapper.logger().info("Module loading complete!");
} catch (Exception e) {
//ExceptionPrinter.print(this.logger(), e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* This file is part of Impactor, licensed under the MIT License (MIT).
*
* Copyright (c) 2018-2022 NickImpact
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package net.impactdev.impactor.core.permissions;

import net.impactdev.impactor.api.Impactor;
import net.impactdev.impactor.api.events.ImpactorEvent;
import net.impactdev.impactor.api.logging.PluginLogger;
import net.impactdev.impactor.api.platform.plugins.PluginMetadata;
import net.impactdev.impactor.api.services.permissions.PermissionsService;
import net.impactdev.impactor.api.services.permissions.SuggestPermissionServiceEvent;
import net.impactdev.impactor.core.modules.ImpactorModule;
import net.impactdev.impactor.core.permissions.register.PermissionsRegistrationProvider;
import net.impactdev.impactor.core.permissions.register.SuggestPermissionServiceEventImpl;
import net.impactdev.impactor.core.plugin.BaseImpactorPlugin;
import net.kyori.event.EventBus;

public final class PermissionsModule implements ImpactorModule {

@Override
public void subscribe(EventBus<ImpactorEvent> bus) {
bus.subscribe(SuggestPermissionServiceEvent.class, event -> {
PluginMetadata metadata = BaseImpactorPlugin.instance().metadata();

event.suggest(metadata, ignore -> true, NoOpPermissionsService::new, 0);
event.suggest(
metadata,
info -> info.plugin("luckperms").isPresent(),
LuckPermsPermissionsService::new,
10
);
});
}

@Override
public void init(Impactor impactor, PluginLogger logger) throws Exception {
logger.info("Calculating permissions service...");

SuggestPermissionServiceEventImpl event = new SuggestPermissionServiceEventImpl();
impactor.events().post(event);

PermissionsRegistrationProvider.PermissionServiceSuggestion suggestion = event.provider().suggestion();
PermissionsService service = suggestion.supplier().get();
logger.info("Permissions » Selected \"" + service.name() + "\" (Provider: " + suggestion.metadata().name().orElse(suggestion.metadata().id()) + ", Priority = " + suggestion.priority() + ")");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* This file is part of Impactor, licensed under the MIT License (MIT).
*
* Copyright (c) 2018-2022 NickImpact
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package net.impactdev.impactor.core.permissions.register;

import net.impactdev.impactor.api.platform.plugins.PluginMetadata;
import net.impactdev.impactor.api.services.permissions.PermissionsService;

import java.util.Optional;
import java.util.function.Supplier;

public final class PermissionsRegistrationProvider {

private PermissionServiceSuggestion suggestion;

public PermissionServiceSuggestion suggestion() {
return Optional.ofNullable(this.suggestion).orElseThrow(() -> new IllegalStateException("No suggestions available"));
}

public void suggest(PluginMetadata metadata, int priority, Supplier<PermissionsService> supplier) {
if(this.suggestion == null || this.suggestion.priority() < priority) {
this.suggestion = this.createSuggestion(metadata, priority, supplier);
}
}

private PermissionServiceSuggestion createSuggestion(PluginMetadata metadata, int priority, Supplier<PermissionsService> supplier) {
return new PermissionServiceSuggestion(
metadata,
priority,
supplier
);
}

public static final class PermissionServiceSuggestion {

private final PluginMetadata metadata;
private final int priority;
private final Supplier<PermissionsService> supplier;

private PermissionServiceSuggestion(PluginMetadata metadata, int priority, Supplier<PermissionsService> supplier) {
this.metadata = metadata;
this.priority = priority;
this.supplier = supplier;
}

public PluginMetadata metadata() {
return this.metadata;
}

public int priority() {
return this.priority;
}

public Supplier<PermissionsService> supplier() {
return this.supplier;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* This file is part of Impactor, licensed under the MIT License (MIT).
*
* Copyright (c) 2018-2022 NickImpact
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package net.impactdev.impactor.core.permissions.register;

import net.impactdev.impactor.api.Impactor;
import net.impactdev.impactor.api.platform.PlatformInfo;
import net.impactdev.impactor.api.platform.plugins.PluginMetadata;
import net.impactdev.impactor.api.services.permissions.PermissionsService;
import net.impactdev.impactor.api.services.permissions.SuggestPermissionServiceEvent;
import net.impactdev.impactor.core.plugin.BaseImpactorPlugin;
import org.jetbrains.annotations.Range;

import java.util.function.Predicate;
import java.util.function.Supplier;

public final class SuggestPermissionServiceEventImpl implements SuggestPermissionServiceEvent {

private final PermissionsRegistrationProvider provider = new PermissionsRegistrationProvider();

public PermissionsRegistrationProvider provider() {
return this.provider;
}

@SuppressWarnings("ConstantValue")
@Override
public void suggest(PluginMetadata suggestor, Predicate<PlatformInfo> filter, Supplier<PermissionsService> service, @Range(from = 0, to = Integer.MAX_VALUE) int priority) {
if(priority < 0) {
BaseImpactorPlugin.instance().logger().warn(suggestor.name() + " attempted to suggest their permissions service" +
"with a priority lower than 0 (" + priority + "), this suggestion has been ignored!");
return;
}

if(filter.test(Impactor.instance().platform().info())) {
this.provider.suggest(suggestor, priority, service);
}
}
}
Loading

0 comments on commit 6c843f3

Please sign in to comment.