From 19322950cae742d48fb38d98a817904a8fa4df77 Mon Sep 17 00:00:00 2001 From: phinner <62483793+phinner@users.noreply.github.com> Date: Thu, 7 Mar 2024 00:24:42 +0100 Subject: [PATCH] feat: Shit is stable --- .../src/main/kotlin/extensions.kt | 2 + .../command/cloud/ArcCommandManager.java | 4 +- .../distributor/core/Distributor.java | 7 +- .../core/DistributorCorePlugin.java | 34 ++++++- .../distributor/core/DistributorProvider.java | 8 +- .../core/permission/EmptyPermissionTree.java | 44 +++++++++ .../core/permission/PermissionTree.java | 4 + .../core/permission/SimplePermissionTree.java | 3 + .../core/plugin/MindustryPlugin.java | 2 +- .../core/service/ServiceManager.java | 61 +++++++++++++ .../core/service/SimpleServiceManager.java | 68 ++++++++++++++ .../distributor/core/util/Priority.java | 12 ++- distributor-permission-rank/build.gradle.kts | 7 ++ .../rank/DistributorPermissionRankPlugin.java | 45 +++++++++ .../permission/{ => rank}/EnumRankNode.java | 2 +- .../{ => rank}/LinearEnumRankNode.java | 5 +- .../rank/MindustryRankProvider.java | 39 ++++++++ .../permission/{ => rank}/RankNode.java | 2 +- .../{ => rank}/RankPermissionManager.java | 6 +- .../{ => rank}/RankPermissionStorage.java | 2 +- .../permission/{ => rank}/RankProvider.java | 2 +- .../rank/YamlRankPermissionStorage.java | 91 +++++++++++++++++++ .../permission/{ => rank}/package-info.java | 2 +- gradle/libs.versions.toml | 5 +- 24 files changed, 430 insertions(+), 27 deletions(-) create mode 100644 distributor-common/src/main/java/com/xpdustry/distributor/core/permission/EmptyPermissionTree.java create mode 100644 distributor-common/src/main/java/com/xpdustry/distributor/core/service/ServiceManager.java create mode 100644 distributor-common/src/main/java/com/xpdustry/distributor/core/service/SimpleServiceManager.java rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/DistributorPermissionRankPlugin.java => distributor-common/src/main/java/com/xpdustry/distributor/core/util/Priority.java (78%) create mode 100644 distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/DistributorPermissionRankPlugin.java rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/EnumRankNode.java (96%) rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/LinearEnumRankNode.java (91%) create mode 100644 distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/MindustryRankProvider.java rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/RankNode.java (94%) rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/RankPermissionManager.java (92%) rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/RankPermissionStorage.java (94%) rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/RankProvider.java (94%) create mode 100644 distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/YamlRankPermissionStorage.java rename distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/{ => rank}/package-info.java (53%) diff --git a/distributor-build-logic/src/main/kotlin/extensions.kt b/distributor-build-logic/src/main/kotlin/extensions.kt index e0b45f71..2de40293 100644 --- a/distributor-build-logic/src/main/kotlin/extensions.kt +++ b/distributor-build-logic/src/main/kotlin/extensions.kt @@ -13,5 +13,7 @@ open class DistributorModuleExtension(project: Project) { val display = project.objects.property(String::class.java) val main = project.objects.property(String::class.java) val description = project.objects.property(String::class.java) + + // TODO Does not handle transitive dependencies, FIX IT val dependencies = project.objects.setProperty(Project::class.java) } diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java index 9eddcdc9..b384ffbe 100644 --- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java +++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java @@ -24,7 +24,6 @@ import com.xpdustry.distributor.command.cloud.specifier.AllTeams; import com.xpdustry.distributor.core.DistributorProvider; import com.xpdustry.distributor.core.command.CommandSender; -import com.xpdustry.distributor.core.permission.PermissionManager; import com.xpdustry.distributor.core.plugin.MindustryPlugin; import com.xpdustry.distributor.core.plugin.PluginAware; import io.leangen.geantyref.TypeToken; @@ -113,8 +112,7 @@ public boolean hasPermission(final @NonNull C sender, final String permission) { final var reversed = senderMapper().reverse(sender); return reversed.isServer() || DistributorProvider.get() - .getService(PermissionManager.class) - .orElseThrow() + .getPermissionManager() .getPermission(reversed.getPlayer(), permission) .asBoolean(); } diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/Distributor.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/Distributor.java index 04c13c29..263886cf 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/Distributor.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/Distributor.java @@ -18,9 +18,12 @@ */ package com.xpdustry.distributor.core; -import java.util.Optional; +import com.xpdustry.distributor.core.permission.PermissionManager; +import com.xpdustry.distributor.core.service.ServiceManager; public interface Distributor { - Optional getService(final Class clazz); + ServiceManager getServiceManager(); + + PermissionManager getPermissionManager(); } diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorCorePlugin.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorCorePlugin.java index 8c62c169..d3b101ec 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorCorePlugin.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorCorePlugin.java @@ -18,6 +18,38 @@ */ package com.xpdustry.distributor.core; +import com.xpdustry.distributor.core.permission.PermissionManager; import com.xpdustry.distributor.core.plugin.AbstractMindustryPlugin; +import com.xpdustry.distributor.core.service.ServiceManager; +import java.util.Objects; +import org.jspecify.annotations.Nullable; -public final class DistributorCorePlugin extends AbstractMindustryPlugin {} +public final class DistributorCorePlugin extends AbstractMindustryPlugin implements Distributor { + + private final ServiceManager services = ServiceManager.simple(); + private @Nullable PermissionManager permissions = null; + + @Override + public ServiceManager getServiceManager() { + return this.services; + } + + @Override + public PermissionManager getPermissionManager() { + return Objects.requireNonNull(permissions, notInitialized("permission")); + } + + @Override + public void onInit() { + DistributorProvider.set(this); + } + + @Override + public void onLoad() { + this.permissions = services.provide(PermissionManager.class); + } + + private String notInitialized(final String subsystem) { + return String.format("The \"%s\" subsystem is not initialized yet.", subsystem); + } +} diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorProvider.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorProvider.java index 6dcc51e8..0f70207d 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorProvider.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/DistributorProvider.java @@ -21,7 +21,7 @@ import org.jspecify.annotations.Nullable; /** - * A holder for the global {@link Distributor} instance. + * A holder for the global {@link Distributor} factory. */ public final class DistributorProvider { @@ -30,7 +30,7 @@ public final class DistributorProvider { private DistributorProvider() {} /** - * Returns the global {@link Distributor} instance. + * Returns the global {@link Distributor} factory. * @throws DistributorInitializationException if the API hasn't been initialized yet */ public static Distributor get() { @@ -41,7 +41,7 @@ public static Distributor get() { } /** - * Sets the global {@link Distributor} instance. + * Sets the global {@link Distributor} factory. * @throws DistributorInitializationException if the API has already been initialized */ public static void set(final Distributor distributor) { @@ -52,7 +52,7 @@ public static void set(final Distributor distributor) { } /** - * Clears the global {@link Distributor} instance. + * Clears the global {@link Distributor} factory. * @throws DistributorInitializationException if the API hasn't been initialized yet */ public static void clear() { diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/EmptyPermissionTree.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/EmptyPermissionTree.java new file mode 100644 index 00000000..4eaf0740 --- /dev/null +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/EmptyPermissionTree.java @@ -0,0 +1,44 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.core.permission; + +import java.util.Collections; +import java.util.Map; + +final class EmptyPermissionTree implements PermissionTree { + + static EmptyPermissionTree INSTANCE = new EmptyPermissionTree(); + + private EmptyPermissionTree() {} + + @Override + public TriState getPermission(final String permission) { + return TriState.UNDEFINED; + } + + @Override + public void setPermission(final String permission, final TriState state) { + throw new UnsupportedOperationException(); + } + + @Override + public Map getPermissions() { + return Collections.emptyMap(); + } +} diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/PermissionTree.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/PermissionTree.java index ac397ed7..332ada04 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/PermissionTree.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/PermissionTree.java @@ -26,6 +26,10 @@ static PermissionTree simple() { return new SimplePermissionTree(); } + static PermissionTree empty() { + return EmptyPermissionTree.INSTANCE; + } + static PermissionTree immutable(final PermissionTree tree) { return (tree instanceof ImmutablePermissionTree) ? tree : new ImmutablePermissionTree(tree); } diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/SimplePermissionTree.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/SimplePermissionTree.java index 5da8f915..44fa43bc 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/SimplePermissionTree.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/permission/SimplePermissionTree.java @@ -37,6 +37,7 @@ private SimplePermissionTree(final @Nullable SimplePermissionTree parent) { this.parent = parent; } + @Override public TriState getPermission(final String permission) { if (!PermissionManager.PERMISSION_PATTERN.matcher(permission).matches()) { throw new IllegalArgumentException("The permission doesn't match the regex: " + permission); @@ -57,6 +58,7 @@ public TriState getPermission(final String permission) { return state; } + @Override public void setPermission(final String permission, final TriState state) { if (!PermissionManager.PERMISSION_PATTERN.matcher(permission).matches()) { throw new IllegalArgumentException("The permission doesn't match the regex: " + permission); @@ -85,6 +87,7 @@ public void setPermission(final String permission, final TriState state) { } } + @Override public Map getPermissions() { final Map permissions = new HashMap<>(); for (final var child : this.children.entrySet()) { diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/plugin/MindustryPlugin.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/plugin/MindustryPlugin.java index ea4b34df..f5b86ac7 100644 --- a/distributor-common/src/main/java/com/xpdustry/distributor/core/plugin/MindustryPlugin.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/plugin/MindustryPlugin.java @@ -40,7 +40,7 @@ static MindustryPlugin wrap(final Plugin plugin) { } /** - * Called after the plugin instance creation. + * Called after the plugin factory creation. * Initialize your plugin here. *

* Warning: Only call other plugins in this method if they use Distributor too. diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/service/ServiceManager.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/service/ServiceManager.java new file mode 100644 index 00000000..3734f9ac --- /dev/null +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/service/ServiceManager.java @@ -0,0 +1,61 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.core.service; + +import com.xpdustry.distributor.core.internal.GeneratedDataClass; +import com.xpdustry.distributor.core.plugin.MindustryPlugin; +import com.xpdustry.distributor.core.util.Priority; +import java.util.List; +import java.util.function.Supplier; +import org.immutables.value.Value; + +public interface ServiceManager { + + static ServiceManager simple() { + return new SimpleServiceManager(); + } + + void register( + final MindustryPlugin plugin, final Class clazz, final Priority priority, final Supplier factory); + + T provide(final Class clazz); + + List> getProviders(final Class clazz); + + @GeneratedDataClass + @Value.Immutable + sealed interface Provider permits ImmutableProvider { + + static Provider of( + final MindustryPlugin plugin, + final Class clazz, + final Priority priority, + final Supplier factory) { + return ImmutableProvider.of(plugin, clazz, priority, factory); + } + + MindustryPlugin getPlugin(); + + Class getClazz(); + + Priority getPriority(); + + Supplier getFactory(); + } +} diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/service/SimpleServiceManager.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/service/SimpleServiceManager.java new file mode 100644 index 00000000..ad77a65f --- /dev/null +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/service/SimpleServiceManager.java @@ -0,0 +1,68 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.core.service; + +import com.xpdustry.distributor.core.plugin.MindustryPlugin; +import com.xpdustry.distributor.core.util.Priority; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.function.Supplier; + +final class SimpleServiceManager implements ServiceManager { + + private final Map, Queue>> services = new HashMap<>(); + private final Object lock = new Object(); + + @Override + public void register( + final MindustryPlugin plugin, final Class clazz, final Priority priority, final Supplier instance) { + synchronized (this.lock) { + this.services + .computeIfAbsent( + clazz, k -> new PriorityQueue>(Comparator.comparing(Provider::getPriority))) + .add(Provider.of(plugin, clazz, priority, instance)); + } + } + + @Override + public T provide(final Class clazz) { + final var providers = this.getProviders(clazz); + if (providers.isEmpty()) { + throw new IllegalStateException("Expected provider for " + clazz.getCanonicalName() + ", got nothing."); + } + return providers.get(0).getFactory().get(); + } + + @SuppressWarnings("unchecked") + @Override + public List> getProviders(final Class clazz) { + synchronized (this.lock) { + final Object implementation = this.services.get(clazz); + return implementation != null + ? List.copyOf((Collection>) implementation) + : Collections.emptyList(); + } + } +} diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/DistributorPermissionRankPlugin.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/util/Priority.java similarity index 78% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/DistributorPermissionRankPlugin.java rename to distributor-common/src/main/java/com/xpdustry/distributor/core/util/Priority.java index aa5eb7bb..ed16e3a7 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/DistributorPermissionRankPlugin.java +++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/util/Priority.java @@ -16,8 +16,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.core.util; -import com.xpdustry.distributor.core.plugin.AbstractMindustryPlugin; - -public final class DistributorPermissionRankPlugin extends AbstractMindustryPlugin {} +public enum Priority { + HIGHEST, + HIGH, + NORMAL, + LOW, + LOWEST +} diff --git a/distributor-permission-rank/build.gradle.kts b/distributor-permission-rank/build.gradle.kts index 060d469d..3eddc102 100644 --- a/distributor-permission-rank/build.gradle.kts +++ b/distributor-permission-rank/build.gradle.kts @@ -8,8 +8,15 @@ module { display = "DistributorPermissionRank" main = "com.xpdustry.distributor.permission.rank.DistributorPermissionRankPlugin" description = "Simple permission system based on ranks." + dependencies = setOf(project(":distributor-common")) } dependencies { compileOnly(project(":distributor-common")) + implementation(libs.configurate.core) + implementation(libs.configurate.yaml) } + +tasks.runMindustryServer { + mods.from(project(":distributor-logging-simple").tasks.shadowJar) +} \ No newline at end of file diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/DistributorPermissionRankPlugin.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/DistributorPermissionRankPlugin.java new file mode 100644 index 00000000..03c998dd --- /dev/null +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/DistributorPermissionRankPlugin.java @@ -0,0 +1,45 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.permission.rank; + +import com.xpdustry.distributor.core.DistributorProvider; +import com.xpdustry.distributor.core.permission.PermissionManager; +import com.xpdustry.distributor.core.plugin.AbstractMindustryPlugin; +import com.xpdustry.distributor.core.util.Priority; + +public final class DistributorPermissionRankPlugin extends AbstractMindustryPlugin { + + @Override + public void onInit() { + final var services = DistributorProvider.get().getServiceManager(); + services.register(this, RankProvider.class, Priority.LOW, MindustryRankProvider::new); + services.register(this, RankPermissionStorage.class, Priority.LOW, () -> { + final var storage = + new YamlRankPermissionStorage(this.getDirectory().resolve("permissions.yaml")); + this.addListener(storage); + return storage; + }); + services.register( + this, + PermissionManager.class, + Priority.HIGH, + () -> new RankPermissionManager( + services.provide(RankProvider.class), services.provide(RankPermissionStorage.class))); + } +} diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/EnumRankNode.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/EnumRankNode.java similarity index 96% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/EnumRankNode.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/EnumRankNode.java index b761797f..086a87bc 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/EnumRankNode.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/EnumRankNode.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import java.util.function.Function; import org.jspecify.annotations.Nullable; diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/LinearEnumRankNode.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/LinearEnumRankNode.java similarity index 91% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/LinearEnumRankNode.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/LinearEnumRankNode.java index 306fd619..694ba8d8 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/LinearEnumRankNode.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/LinearEnumRankNode.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import java.util.function.Function; import org.jspecify.annotations.Nullable; @@ -36,8 +36,7 @@ public E getValue() { @Override public @Nullable EnumRankNode getPrevious() { - @SuppressWarnings("unchecked") - final var constants = (E[]) this.value.getClass().getEnumConstants(); + final var constants = this.value.getDeclaringClass().getEnumConstants(); if (this.ascending) { return (this.value.ordinal() > 0) ? new LinearEnumRankNode<>(constants[this.value.ordinal() - 1], this.nameProvider, true) diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/MindustryRankProvider.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/MindustryRankProvider.java new file mode 100644 index 00000000..56602d8f --- /dev/null +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/MindustryRankProvider.java @@ -0,0 +1,39 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.permission.rank; + +import java.util.Collection; +import java.util.Collections; +import java.util.Locale; +import mindustry.gen.Player; + +final class MindustryRankProvider implements RankProvider { + + @Override + public Collection getRanks(final Player player) { + final var rank = player.admin() ? MindustryRank.ADMIN : MindustryRank.PLAYER; + return Collections.singleton( + EnumRankNode.linear(rank, r -> "mindustry:" + r.name().toLowerCase(Locale.ROOT), true)); + } + + private enum MindustryRank { + PLAYER, + ADMIN + } +} diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankNode.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankNode.java similarity index 94% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankNode.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankNode.java index 6e9cb691..f00f702e 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankNode.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankNode.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import org.jspecify.annotations.Nullable; diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionManager.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionManager.java similarity index 92% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionManager.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionManager.java index 1077660a..0bc1e2b3 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionManager.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionManager.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import com.xpdustry.distributor.core.permission.PermissionManager; import com.xpdustry.distributor.core.permission.TriState; @@ -24,8 +24,8 @@ final class RankPermissionManager implements PermissionManager { - private RankProvider provider; - private RankPermissionStorage storage; + private final RankProvider provider; + private final RankPermissionStorage storage; RankPermissionManager(final RankProvider provider, final RankPermissionStorage storage) { this.provider = provider; diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionStorage.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionStorage.java similarity index 94% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionStorage.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionStorage.java index 332b642e..f39a52a1 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankPermissionStorage.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankPermissionStorage.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import com.xpdustry.distributor.core.permission.PermissionTree; diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankProvider.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankProvider.java similarity index 94% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankProvider.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankProvider.java index ea3d2c72..209d86db 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/RankProvider.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/RankProvider.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import java.util.Collection; import mindustry.gen.Player; diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/YamlRankPermissionStorage.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/YamlRankPermissionStorage.java new file mode 100644 index 00000000..2e88ceca --- /dev/null +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/YamlRankPermissionStorage.java @@ -0,0 +1,91 @@ +/* + * Distributor, a feature-rich framework for Mindustry plugins. + * + * Copyright (C) 2024 Xpdustry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.xpdustry.distributor.permission.rank; + +import arc.util.Log; +import com.xpdustry.distributor.core.permission.PermissionTree; +import com.xpdustry.distributor.core.permission.TriState; +import com.xpdustry.distributor.core.plugin.PluginListener; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import mindustry.server.ServerControl; +import org.spongepowered.configurate.yaml.NodeStyle; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + +final class YamlRankPermissionStorage implements RankPermissionStorage, PluginListener { + + private Map permissions = Collections.emptyMap(); + private final Object lock = new Object(); + private final YamlConfigurationLoader loader; + + YamlRankPermissionStorage(final Path file) { + this.loader = YamlConfigurationLoader.builder() + .path(file) + .nodeStyle(NodeStyle.BLOCK) + .build(); + } + + @Override + public void onPluginLoad() { + try { + reload(); + } catch (final IOException error) { + throw new RuntimeException("Failed to load permission file.", error); + } + + ServerControl.instance.handler.register("rank-permission-reload", "Reload the permissions", $ -> { + try { + reload(); + Log.info("Reloaded rank permissions file"); + } catch (final IOException e) { + Log.err("Failed to reload rank permission file", e); + } + }); + } + + @Override + public PermissionTree getRankPermissions(final RankNode node) { + synchronized (this.lock) { + return this.permissions.getOrDefault(node.getName().toLowerCase(Locale.ROOT), PermissionTree.empty()); + } + } + + private void reload() throws IOException { + final Map map = new HashMap<>(); + for (final var node : loader.load().node("ranks").childrenList()) { + final var name = node.node("name").getString(); + if (name == null || name.isBlank()) { + throw new IOException("Invalid rank name."); + } + final var tree = PermissionTree.simple(); + for (final var entry : node.node("permissions").childrenMap().entrySet()) { + tree.setPermission( + (String) entry.getKey(), TriState.of(entry.getValue().getBoolean())); + } + map.put(name, PermissionTree.immutable(tree)); + } + synchronized (this.lock) { + this.permissions = map; + } + } +} diff --git a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/package-info.java b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/package-info.java similarity index 53% rename from distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/package-info.java rename to distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/package-info.java index 6414c90d..b7637649 100644 --- a/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/package-info.java +++ b/distributor-permission-rank/src/main/java/com/xpdustry/distributor/permission/rank/package-info.java @@ -1,4 +1,4 @@ @NullMarked -package com.xpdustry.distributor.permission; +package com.xpdustry.distributor.permission.rank; import org.jspecify.annotations.NullMarked; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8af0cbed..c761fc4d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ cloud = "2.0.0-beta.3" # utilities immutables = "2.9.2" geantyref = "1.3.15" +configurate = "4.1.2" # testing junit = "5.10.1" @@ -56,6 +57,8 @@ cloud-core = { module = "org.incendo:cloud-core", version.ref = "cloud" } # utilities immutables = { module = "org.immutables:value", version.ref = "immutables" } geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref" } +configurate-core = { module = "org.spongepowered:configurate-core", version.ref = "configurate" } +configurate-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate" } # testing junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } @@ -79,4 +82,4 @@ mammoth = { module = "net.kyori:mammoth", version.ref = "mammoth" } [bundles] indra = [ "indra-common", "indra-licenser-spotless" ] tests = [ "junit-api", "junit-engine", "assert4j-core" ] -mindustry = [ "mindustry-core", "mindustry-server", "arc-core", "arc-backend-headless" ] \ No newline at end of file +mindustry = [ "mindustry-core", "mindustry-server", "arc-core", "arc-backend-headless" ]