diff --git a/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platform.java b/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platform.java index 7f60e9e06..d0e848290 100644 --- a/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platform.java +++ b/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platform.java @@ -121,7 +121,8 @@ public enum Category { BUKKIT, BUNGEE, SPONGE, - VELOCITY + VELOCITY, + STANDALONE } @Override diff --git a/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platforms.java b/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platforms.java index 0a5e251b3..265c3356a 100644 --- a/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platforms.java +++ b/bans-bootstrap/src/main/java/space/arim/libertybans/bootstrap/Platforms.java @@ -58,6 +58,10 @@ public static Platform velocity(ClassLoader platformClassLoader) { .build("Velocity"); } + public static Platform standalone() { + return Platform.builderForCategory(Platform.Category.STANDALONE).build("Standalone"); + } + // Used for testing purposes public static Stream allPossiblePlatforms(String platformName) { Set platforms = new HashSet<>(); diff --git a/bans-core/src/main/java/space/arim/libertybans/core/database/Vendor.java b/bans-core/src/main/java/space/arim/libertybans/core/database/Vendor.java index f4dce181f..47179351a 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/database/Vendor.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/database/Vendor.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -55,7 +55,7 @@ public boolean hasDeleteFromJoin() { return isMySQLLike(); } - boolean isRemote() { + public boolean isRemote() { return isMySQLLike() || isPostgresLike(); } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/env/Environment.java b/bans-core/src/main/java/space/arim/libertybans/core/env/Environment.java index 2d26743cc..085b2ed16 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/env/Environment.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/env/Environment.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -28,7 +28,10 @@ public interface Environment { PlatformListener createAliasCommand(String command); /** - * Used for Sponge only; since Sponge requires early command registration and service provision + * Used for Sponge and the standalone application only.
+ *
+ * Sponge requires early command registration and service provision, while for the standalone application + * this usage is merely convenient. * * @return the platform accessors */ diff --git a/bans-distribution/distributable/pom.xml b/bans-distribution/distributable/pom.xml index 28c65fbb3..4fbbc5648 100644 --- a/bans-distribution/distributable/pom.xml +++ b/bans-distribution/distributable/pom.xml @@ -1,3 +1,22 @@ + + @@ -15,6 +34,17 @@ LibertyBans_Release-${project.version} + + org.apache.maven.plugins + maven-jar-plugin + + + + space.arim.libertybans.env.standalone.launcher.StandaloneApplication + + + + org.apache.maven.plugins maven-shade-plugin @@ -89,5 +119,9 @@ space.arim.libertybans bans-env-velocityplugin + + space.arim.libertybans + bans-env-standalonelauncher + \ No newline at end of file diff --git a/bans-distribution/download/pom.xml b/bans-distribution/download/pom.xml index ae54adb14..b7dcfd278 100644 --- a/bans-distribution/download/pom.xml +++ b/bans-distribution/download/pom.xml @@ -1,3 +1,22 @@ + + @@ -97,5 +116,9 @@ space.arim.libertybans bans-env-velocity + + space.arim.libertybans + bans-env-standalone + \ No newline at end of file diff --git a/bans-distribution/executable/pom.xml b/bans-distribution/executable/pom.xml index 5fd710137..cb5daed57 100644 --- a/bans-distribution/executable/pom.xml +++ b/bans-distribution/executable/pom.xml @@ -1,3 +1,22 @@ + + @@ -49,6 +68,11 @@ src/assembly/final-executable.xml + + + space.arim.libertybans.env.standalone.launcher.StandaloneApplication + + @@ -80,6 +104,10 @@ space.arim.libertybans bans-env-velocityplugin + + space.arim.libertybans + bans-env-standalonelauncher + space.arim.libertybans bans-env-bungee @@ -96,6 +124,10 @@ space.arim.libertybans bans-env-velocity + + space.arim.libertybans + bans-env-standalone + org.slf4j slf4j-simple diff --git a/bans-distribution/executable/src/assembly/final-executable.xml b/bans-distribution/executable/src/assembly/final-executable.xml index 95c118957..affebb07b 100644 --- a/bans-distribution/executable/src/assembly/final-executable.xml +++ b/bans-distribution/executable/src/assembly/final-executable.xml @@ -73,6 +73,7 @@ space.arim.libertybans:bans-env-spigotplugin space.arim.libertybans:bans-env-spongeplugin space.arim.libertybans:bans-env-velocityplugin + space.arim.libertybans:bans-env-standalonelauncher space.arim.licenser:licenser-agpl3 diff --git a/bans-distribution/executable/src/assembly/self-implementation.xml b/bans-distribution/executable/src/assembly/self-implementation.xml index 7ce1e3675..3e7188596 100644 --- a/bans-distribution/executable/src/assembly/self-implementation.xml +++ b/bans-distribution/executable/src/assembly/self-implementation.xml @@ -48,6 +48,7 @@ space.arim.libertybans:bans-env-spigotplugin space.arim.libertybans:bans-env-spongeplugin space.arim.libertybans:bans-env-velocityplugin + space.arim.libertybans:bans-env-standalonelauncher space.arim.licenser:licenser-agpl3 org.yaml:snakeyaml diff --git a/bans-env/bungeeplugin/src/main/java/space/arim/libertybans/env/bungee/plugin/BungeePlugin.java b/bans-env/bungeeplugin/src/main/java/space/arim/libertybans/env/bungee/plugin/BungeePlugin.java index 495d28a91..baeb413ef 100644 --- a/bans-env/bungeeplugin/src/main/java/space/arim/libertybans/env/bungee/plugin/BungeePlugin.java +++ b/bans-env/bungeeplugin/src/main/java/space/arim/libertybans/env/bungee/plugin/BungeePlugin.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -80,11 +80,6 @@ private BaseFoundation initialize() { .culpritFinder(new BungeeCulpritFinder(getLogger())) .build(); ClassLoader launchLoader = launcher.attemptLaunch().join(); - - if (launchLoader == null) { - getLogger().warning("Failed to launch LibertyBans"); - return null; - } BaseFoundation base; try { base = new Instantiator("space.arim.libertybans.env.bungee.BungeeLauncher", launchLoader) diff --git a/bans-env/pom.xml b/bans-env/pom.xml index efb361495..afe3aa1b7 100644 --- a/bans-env/pom.xml +++ b/bans-env/pom.xml @@ -21,6 +21,8 @@ spongeplugin velocity velocityplugin + standalone + standalonelauncher diff --git a/bans-env/spigotplugin/src/main/java/space/arim/libertybans/env/spigot/plugin/SpigotPlugin.java b/bans-env/spigotplugin/src/main/java/space/arim/libertybans/env/spigot/plugin/SpigotPlugin.java index c3367bceb..c44f56569 100644 --- a/bans-env/spigotplugin/src/main/java/space/arim/libertybans/env/spigot/plugin/SpigotPlugin.java +++ b/bans-env/spigotplugin/src/main/java/space/arim/libertybans/env/spigot/plugin/SpigotPlugin.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -101,10 +101,6 @@ private BaseFoundation initialize() { executor.shutdown(); assert executor.isTerminated(); } - if (launchLoader == null) { - getLogger().warning("Failed to launch LibertyBans"); - return null; - } BaseFoundation base; try { base = new Instantiator("space.arim.libertybans.env.spigot.SpigotLauncher", launchLoader) diff --git a/bans-env/spongeplugin/src/main/java/space/arim/libertybans/env/sponge/plugin/SpongePlugin.java b/bans-env/spongeplugin/src/main/java/space/arim/libertybans/env/sponge/plugin/SpongePlugin.java index a69ffbb8d..c92add01a 100644 --- a/bans-env/spongeplugin/src/main/java/space/arim/libertybans/env/sponge/plugin/SpongePlugin.java +++ b/bans-env/spongeplugin/src/main/java/space/arim/libertybans/env/sponge/plugin/SpongePlugin.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -139,10 +139,6 @@ private CompletableFuture initialize() { .culpritFinder(new SpongeCulpritFinder(game)) .build(); return launcher.attemptLaunch().thenApply((launchLoader) -> { - if (launchLoader == null) { - logger.warn("Failed to launch LibertyBans"); - return null; - } BaseFoundation base; try { base = new Instantiator("space.arim.libertybans.env.sponge.SpongeLauncher", launchLoader) diff --git a/bans-env/standalone/pom.xml b/bans-env/standalone/pom.xml new file mode 100644 index 000000000..93b7d51d3 --- /dev/null +++ b/bans-env/standalone/pom.xml @@ -0,0 +1,56 @@ + + + + 4.0.0 + + + space.arim.libertybans + bans-env + 1.1.0-SNAPSHOT + + + bans-env-standalone + + + + space.arim.libertybans + bans-core + + + net.kyori + adventure-text-serializer-plain + + + + org.junit.jupiter + junit-jupiter-api + + + org.slf4j + slf4j-simple + + + org.mockito + mockito-junit-jupiter + + + \ No newline at end of file diff --git a/bans-env/standalone/src/main/java/module-info.java b/bans-env/standalone/src/main/java/module-info.java new file mode 100644 index 000000000..b71d5f8c1 --- /dev/null +++ b/bans-env/standalone/src/main/java/module-info.java @@ -0,0 +1,13 @@ +module space.arim.libertybans.env.standalone { + requires jakarta.inject; + requires net.kyori.adventure.text.serializer.plain; + requires org.checkerframework.checker.qual; + requires org.slf4j; + requires space.arim.api.env; + requires space.arim.api.jsonchat; + requires transitive space.arim.injector; + requires transitive space.arim.libertybans.bootstrap; + requires space.arim.libertybans.core; + exports space.arim.libertybans.env.standalone; + opens space.arim.libertybans.env.standalone to space.arim.injector; +} \ No newline at end of file diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/CommandDispatch.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/CommandDispatch.java new file mode 100644 index 000000000..cbf44f78e --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/CommandDispatch.java @@ -0,0 +1,71 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import org.slf4j.LoggerFactory; +import space.arim.libertybans.core.commands.Commands; +import space.arim.libertybans.core.commands.StringCommandPackage; +import space.arim.libertybans.core.env.PlatformListener; + +import java.util.function.Consumer; + +@Singleton +public final class CommandDispatch implements PlatformListener, Consumer { + + private final Commands commands; + private final ConsoleSender sender; + + private volatile boolean registered; + + @Inject + CommandDispatch(Commands commands, ConsoleSender sender) { + this.commands = commands; + this.sender = sender; + } + + /** + * Accepts and dispatches the given console command to LibertyBans. + * + * @param command the command. No 'libertybans' prefix should be added. For example, "ban A248 have fun" is valid. + */ + @Override + public void accept(String command) { + if (!registered) { + LoggerFactory.getLogger(getClass()).warn( + "Skipping the following command because initialization is yet incomplete: {}", + command + ); + return; + } + commands.execute(sender, StringCommandPackage.create(command)); + } + + @Override + public void register() { + registered = true; + } + + @Override + public void unregister() { + registered = false; + } +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudience.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudience.java new file mode 100644 index 000000000..8f365b2a1 --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudience.java @@ -0,0 +1,25 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import net.kyori.adventure.audience.Audience; + +public interface ConsoleAudience extends Audience { +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudienceToLogger.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudienceToLogger.java new file mode 100644 index 000000000..e25c7f5b1 --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleAudienceToLogger.java @@ -0,0 +1,48 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import net.kyori.adventure.audience.MessageType; +import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.slf4j.Logger; +import space.arim.api.jsonchat.adventure.implementor.MessageOnlyAudience; + +import java.util.Objects; + +public record ConsoleAudienceToLogger(Logger logger) implements ConsoleAudience, MessageOnlyAudience { + + public ConsoleAudienceToLogger { + Objects.requireNonNull(logger); + } + + @Override + public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) { + logger.info(PlainComponentSerializer.plain().serialize(message)); + } + + @Override + public UnsupportedOperationException notSupportedException() { + return new UnsupportedOperationException("The console can only receive messages"); + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleSender.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleSender.java new file mode 100644 index 000000000..e90e63dee --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/ConsoleSender.java @@ -0,0 +1,82 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Inject; +import net.kyori.adventure.text.ComponentLike; +import space.arim.libertybans.api.ConsoleOperator; +import space.arim.libertybans.api.Operator; +import space.arim.libertybans.core.config.InternalFormatter; +import space.arim.libertybans.core.env.CmdSender; + +import java.util.stream.Stream; + +final class ConsoleSender implements CmdSender { + + private final InternalFormatter formatter; + private final ConsoleAudience audience; + + @Inject + ConsoleSender(InternalFormatter formatter, ConsoleAudience audience) { + this.formatter = formatter; + this.audience = audience; + } + + @Override + public Operator getOperator() { + return ConsoleOperator.INSTANCE; + } + + @Override + public boolean hasPermission(String permission) { + return true; + } + + @Override + public void sendMessageNoPrefix(ComponentLike message) { + audience.sendMessage(message); + } + + @Override + public void sendMessage(ComponentLike message) { + sendMessageNoPrefix(formatter.prefix(message)); + } + + @Override + public void sendLiteralMessageNoPrefix(String message) { + sendMessageNoPrefix(formatter.parseMessageWithoutPrefix(message)); + } + + @Override + public void sendLiteralMessage(String message) { + sendMessage(formatter.parseMessageWithoutPrefix(message)); + } + + @Override + public Stream getPlayerNames() { + return Stream.empty(); + } + + @Override + public Stream getPlayerNamesOnSameServer() { + return Stream.empty(); + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneBindModule.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneBindModule.java new file mode 100644 index 000000000..54110285e --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneBindModule.java @@ -0,0 +1,88 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Singleton; +import space.arim.api.env.PlatformHandle; +import space.arim.api.env.PlatformPluginInfo; +import space.arim.libertybans.core.env.EnvEnforcer; +import space.arim.libertybans.core.env.EnvUserResolver; +import space.arim.libertybans.core.env.Environment; +import space.arim.libertybans.core.importing.PlatformImportSource; +import space.arim.libertybans.core.selector.cache.MuteCache; +import space.arim.libertybans.core.selector.cache.OnDemandMuteCache; +import space.arim.omnibus.util.concurrent.EnhancedExecutor; +import space.arim.omnibus.util.concurrent.FactoryOfTheFuture; +import space.arim.omnibus.util.concurrent.impl.IndifferentFactoryOfTheFuture; +import space.arim.omnibus.util.concurrent.impl.SimplifiedEnhancedExecutor; + +import java.util.concurrent.ForkJoinPool; + +public class StandaloneBindModule { + + @Singleton + public PlatformHandle handle() { + return new PlatformHandle() { + @Override + public FactoryOfTheFuture createFuturesFactory() { + return new IndifferentFactoryOfTheFuture(); + } + + @Override + public EnhancedExecutor createEnhancedExecutor() { + return new SimplifiedEnhancedExecutor() { + @Override + public void execute(Runnable command) { + ForkJoinPool.commonPool().execute(command); + } + }; + } + + @Override + public PlatformPluginInfo getImplementingPluginInfo() { + return new PlatformPluginInfo( + // Completely irrelevant + StandaloneBindModule.this, StandaloneBindModule.class + ); + } + }; + } + + public MuteCache muteCache(OnDemandMuteCache muteCache) { + return muteCache; + } + + public Environment environment(StandaloneEnv env) { + return env; + } + + public EnvEnforcer enforcer(StandaloneEnforcer enforcer) { + return enforcer; + } + + public EnvUserResolver resolver(StandaloneResolver resolver) { + return resolver; + } + + public PlatformImportSource platformImportSource() { + throw new UnsupportedOperationException("It is impossible to import from vanilla on the standalone application"); + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnforcer.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnforcer.java new file mode 100644 index 000000000..b236be032 --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnforcer.java @@ -0,0 +1,96 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; +import space.arim.libertybans.core.env.EnvEnforcer; +import space.arim.libertybans.core.env.TargetMatcher; +import space.arim.omnibus.util.concurrent.CentralisedFuture; +import space.arim.omnibus.util.concurrent.FactoryOfTheFuture; + +import java.net.InetAddress; +import java.util.UUID; +import java.util.function.Consumer; + +final class StandaloneEnforcer implements EnvEnforcer { + + private final FactoryOfTheFuture futuresFactory; + private final Provider commandHandler; + + @Inject + StandaloneEnforcer(FactoryOfTheFuture futuresFactory, Provider commandHandler) { + this.futuresFactory = futuresFactory; + this.commandHandler = commandHandler; + } + + @Override + public CentralisedFuture sendToThoseWithPermission(String permission, ComponentLike message) { + return completedVoid(); + } + + @Override + public CentralisedFuture doForPlayerIfOnline(UUID uuid, Consumer callback) { + return completedVoid(); + } + + @Override + public void kickPlayer(Void player, Component message) { + throw new UnsupportedOperationException(); + } + + @Override + public void sendMessageNoPrefix(Void player, ComponentLike message) { + throw new UnsupportedOperationException(); + } + + @Override + public CentralisedFuture enforceMatcher(TargetMatcher matcher) { + return completedVoid(); + } + + @Override + public UUID getUniqueIdFor(Void player) { + throw new UnsupportedOperationException(); + } + + @Override + public InetAddress getAddressFor(Void player) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasPermission(Void player, String permission) { + return false; + } + + @Override + public CentralisedFuture executeConsoleCommand(String command) { + commandHandler.get().accept(command); + return completedVoid(); + } + + private CentralisedFuture completedVoid() { + return futuresFactory.completedFuture(null); + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnv.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnv.java new file mode 100644 index 000000000..dda599510 --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneEnv.java @@ -0,0 +1,64 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Inject; +import space.arim.libertybans.core.env.Environment; +import space.arim.libertybans.core.env.PlatformListener; + +import java.util.Set; +import java.util.function.Consumer; + +final class StandaloneEnv implements Environment { + + private final CommandDispatch commandHandler; + + @Inject + StandaloneEnv(CommandDispatch commandHandler) { + this.commandHandler = commandHandler; + } + + @Override + public Set createListeners() { + return Set.of(commandHandler); + } + + @Override + public PlatformListener createAliasCommand(String command) { + // No-op + return new PlatformListener() { + @Override + public void register() { + + } + + @Override + public void unregister() { + + } + }; + } + + @Override + public Consumer platformAccess() { + return commandHandler; + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneLauncher.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneLauncher.java new file mode 100644 index 000000000..36aba259f --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneLauncher.java @@ -0,0 +1,78 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import org.slf4j.LoggerFactory; +import space.arim.injector.Identifier; +import space.arim.injector.Injector; +import space.arim.injector.InjectorBuilder; +import space.arim.injector.SpecificationSupport; +import space.arim.libertybans.bootstrap.BaseFoundation; +import space.arim.libertybans.bootstrap.PlatformLauncher; +import space.arim.libertybans.core.ApiBindModule; +import space.arim.libertybans.core.CommandsModule; +import space.arim.libertybans.core.PillarOneBindModule; +import space.arim.libertybans.core.PillarTwoBindModule; +import space.arim.libertybans.core.addon.AddonLoader; +import space.arim.omnibus.Omnibus; +import space.arim.omnibus.OmnibusProvider; + +import java.nio.file.Path; + +public final class StandaloneLauncher implements PlatformLauncher { + + private final Path folder; + private final Omnibus omnibus; + + public StandaloneLauncher(/* Useless */ Void plugin, Path folder) { + this(folder, OmnibusProvider.getOmnibus()); + } + + public StandaloneLauncher(Path folder, Omnibus omnibus) { + this.folder = folder; + this.omnibus = omnibus; + } + + public Injector createInjector(ConsoleAudience consoleAudience) { + return new InjectorBuilder() + .bindInstance(Identifier.ofTypeAndNamed(Path.class, "folder"), folder) + .bindInstance(Omnibus.class, omnibus) + .bindInstance(ConsoleAudience.class, consoleAudience) + .addBindModules( + new ApiBindModule(), + new PillarOneBindModule(), + new PillarTwoBindModule(), + new CommandsModule(), + new StandaloneBindModule()) + .addBindModules(AddonLoader.loadAddonBindModules()) + .specification(SpecificationSupport.JAKARTA) + .privateInjection(true) + .multiBindings(true) + .build(); + } + + @Override + public BaseFoundation launch() { + return createInjector( + new ConsoleAudienceToLogger(LoggerFactory.getLogger(getClass())) + ).request(BaseFoundation.class); + } + +} diff --git a/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneResolver.java b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneResolver.java new file mode 100644 index 000000000..475bf940e --- /dev/null +++ b/bans-env/standalone/src/main/java/space/arim/libertybans/env/standalone/StandaloneResolver.java @@ -0,0 +1,67 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import jakarta.inject.Inject; +import space.arim.libertybans.core.env.SimpleEnvUserResolver; +import space.arim.libertybans.core.env.UUIDAndAddress; +import space.arim.omnibus.util.concurrent.CentralisedFuture; +import space.arim.omnibus.util.concurrent.FactoryOfTheFuture; + +import java.net.InetAddress; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Supplier; + +final class StandaloneResolver extends SimpleEnvUserResolver { + + private final FactoryOfTheFuture futuresFactory; + + @Inject + StandaloneResolver(FactoryOfTheFuture futuresFactory) { + this.futuresFactory = futuresFactory; + } + + @Override + protected CentralisedFuture performLookup(Supplier rootImplementation) { + return futuresFactory.completedFuture(rootImplementation.get()); + } + + @Override + public Optional lookupUUID0(String name) { + return Optional.empty(); + } + + @Override + public Optional lookupName0(UUID uuid) { + return Optional.empty(); + } + + @Override + public Optional lookupAddress0(String name) { + return Optional.empty(); + } + + @Override + public Optional lookupPlayer0(String name) { + return Optional.empty(); + } + +} diff --git a/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/ConsoleReceiver.java b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/ConsoleReceiver.java new file mode 100644 index 000000000..517968215 --- /dev/null +++ b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/ConsoleReceiver.java @@ -0,0 +1,48 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import net.kyori.adventure.audience.MessageType; +import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; +import org.checkerframework.checker.nullness.qual.NonNull; +import space.arim.api.jsonchat.adventure.implementor.MessageOnlyAudience; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public record ConsoleReceiver(List messages) implements ConsoleAudience, MessageOnlyAudience { + + public ConsoleReceiver() { + this(Collections.synchronizedList(new ArrayList<>())); + } + + @Override + public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) { + messages.add(PlainComponentSerializer.plain().serialize(message)); + } + + @Override + public UnsupportedOperationException notSupportedException() { + return new UnsupportedOperationException("Not supported"); + } +} diff --git a/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/StandaloneLauncherTest.java b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/StandaloneLauncherTest.java new file mode 100644 index 000000000..b56bf11da --- /dev/null +++ b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/StandaloneLauncherTest.java @@ -0,0 +1,75 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.junit.jupiter.MockitoExtension; +import space.arim.injector.Injector; +import space.arim.libertybans.api.LibertyBans; +import space.arim.libertybans.bootstrap.BaseFoundation; +import space.arim.omnibus.DefaultOmnibus; + +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.mock; + +@ExtendWith(MockitoExtension.class) +public class StandaloneLauncherTest { + + private Path dataFolder; + + @BeforeEach + public void setDataFolder(@TempDir Path dataFolder) { + this.dataFolder = dataFolder; + } + + @Test + public void allBindings() { + Injector injector = new StandaloneLauncher( + dataFolder, new DefaultOmnibus() + ).createInjector(mock(ConsoleAudience.class)); + assertDoesNotThrow(() -> injector.request(LibertyBans.class)); + assertDoesNotThrow(() -> injector.request(BaseFoundation.class)); + } + + @Test + public void startup() { + ConsoleReceiver consoleReceiver = new ConsoleReceiver(); + Injector injector = new StandaloneLauncher( + dataFolder, new DefaultOmnibus() + ).createInjector(consoleReceiver); + + // Startup + BaseFoundation base = injector.request(BaseFoundation.class); + assertDoesNotThrow(base::startup); + + injector.request(CommandDispatch.class).accept("about"); + assertFalse(consoleReceiver.messages().isEmpty()); + + // Shutdown + base.shutdown(); + } + +} diff --git a/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/UsageExample.java b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/UsageExample.java new file mode 100644 index 000000000..c96e5ed63 --- /dev/null +++ b/bans-env/standalone/src/test/java/space/arim/libertybans/env/standalone/UsageExample.java @@ -0,0 +1,78 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone; + +import space.arim.injector.Injector; +import space.arim.libertybans.api.LibertyBans; +import space.arim.libertybans.api.punish.Punishment; +import space.arim.libertybans.bootstrap.BaseFoundation; +import space.arim.omnibus.DefaultOmnibus; + +import java.nio.file.Path; +import java.util.List; + +public class UsageExample { + + // Prerequisites: snakeyaml and Gson dependencies on the classpath + // Two items needed to implement: + // 1. output for receiving messages (ConsoleAudience) + // 2. input for dispatching commands (calls to CommandDispatch) + public void compileMe() { + // Define the data folder used for configuration, local databases, etc. + Path dataFolder = Path.of("libertybans"); + // MUST IMPLEMENT: output for receiving messages + // You may use the utility interface MessageOnlyAudience because Audience has unnecessary methods + ConsoleAudience consoleAudience = consoleAudience(); + + // Launch the punishment suite + Injector injector = new StandaloneLauncher( + dataFolder, new DefaultOmnibus() + ).createInjector(consoleAudience); + // Retrieve the API + LibertyBans api = injector.request(LibertyBans.class); + // Retrieve the implementation + BaseFoundation base = injector.request(BaseFoundation.class); + // Startup + base.startup(); + // MUST IMPLEMENT: input for dispatching commands + CommandDispatch commandDispatch = injector.request(CommandDispatch.class); + commandDispatch.accept("ban A248 Example ban"); + // You can use the API as usual + // Careful - the following method loads ALL active punishments WITHOUT streaming or pagination + // To use pagination I recommend the seekAfter methods (keyset pagination) + @SuppressWarnings("unused") + List punishments = api + .getSelector() + .selectionBuilder() + .selectActiveOnly() + //.seekAfter(/*...*/) + .build() + .getAllSpecificPunishments() + .toCompletableFuture() + .join(); // You may have better techniques depending on the usecase + // Shutdown + base.shutdown(); + } + + private ConsoleAudience consoleAudience() { + throw new RuntimeException("Implement me"); + } + +} diff --git a/bans-env/standalonelauncher/pom.xml b/bans-env/standalonelauncher/pom.xml new file mode 100644 index 000000000..4e54085c6 --- /dev/null +++ b/bans-env/standalonelauncher/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + + + space.arim.libertybans + bans-env + 1.1.0-SNAPSHOT + + + bans-env-standalonelauncher + + + + space.arim.libertybans + bans-bootstrap + + + \ No newline at end of file diff --git a/bans-env/standalonelauncher/src/main/java/module-info.java b/bans-env/standalonelauncher/src/main/java/module-info.java new file mode 100644 index 000000000..51c298a6a --- /dev/null +++ b/bans-env/standalonelauncher/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module space.arim.libertybans.env.standalonelauncher { + requires space.arim.libertybans.bootstrap; + requires java.logging; +} \ No newline at end of file diff --git a/bans-env/standalonelauncher/src/main/java/space/arim/libertybans/env/standalone/launcher/StandaloneApplication.java b/bans-env/standalonelauncher/src/main/java/space/arim/libertybans/env/standalone/launcher/StandaloneApplication.java new file mode 100644 index 000000000..33205e6ac --- /dev/null +++ b/bans-env/standalonelauncher/src/main/java/space/arim/libertybans/env/standalone/launcher/StandaloneApplication.java @@ -0,0 +1,99 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.standalone.launcher; + +import space.arim.libertybans.bootstrap.BaseFoundation; +import space.arim.libertybans.bootstrap.Instantiator; +import space.arim.libertybans.bootstrap.LibertyBansLauncher; +import space.arim.libertybans.bootstrap.Platforms; +import space.arim.libertybans.bootstrap.logger.BootstrapLogger; +import space.arim.libertybans.bootstrap.logger.JulBootstrapLogger; + +import java.io.Console; +import java.nio.file.Path; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Consumer; +import java.util.logging.Logger; + +public final class StandaloneApplication { + + private final Path folder; + private final BootstrapLogger logger; + + public StandaloneApplication(Path folder, BootstrapLogger logger) { + this.folder = folder; + this.logger = logger; + } + + public static void main(String[] args) { + var logger = Logger.getLogger(StandaloneApplication.class.getName()); + try { + Class.forName("com.google.gson.Gson"); + Class.forName("org.yaml.snakeyaml.Yaml"); + } catch (ClassNotFoundException ignored) { + logger.warning("The Gson and SnakeYaml dependencies must be present"); + return; + } + new StandaloneApplication( + Path.of("libertybans"), new JulBootstrapLogger(logger) + ).appStart(); + } + + private void appStart() { + logger.info("Starting the standalone instance. Use command 'stop' to stop."); + BaseFoundation base = initialize(); + if (base == null) { + return; + } + @SuppressWarnings("unchecked") + Consumer commandDispatch = (Consumer) base.platformAccess(); + + Console console = System.console(); + String command; + while ((command = console.readLine()) != null) { + if (command.equalsIgnoreCase("stop")) { + break; + } + commandDispatch.accept(command); + } + base.shutdown(); + } + + private BaseFoundation initialize() { + LibertyBansLauncher launcher = new LibertyBansLauncher.Builder() + .folder(folder) + .logger(logger) + .platform(Platforms.standalone()) + .executor(ForkJoinPool.commonPool()) + .build(); + ClassLoader launchLoader = launcher.attemptLaunch().join(); + BaseFoundation base; + try { + base = new Instantiator("space.arim.libertybans.env.standalone.StandaloneLauncher", launchLoader) + .invoke(Void.class, null, folder); + } catch (IllegalArgumentException | SecurityException | ReflectiveOperationException ex) { + logger.warn("Failed to launch LibertyBans", ex); + return null; + } + base.startup(); + return base; + } + +} diff --git a/bans-env/velocityplugin/src/main/java/space/arim/libertybans/env/velocity/plugin/VelocityPlugin.java b/bans-env/velocityplugin/src/main/java/space/arim/libertybans/env/velocity/plugin/VelocityPlugin.java index 4034ba967..e27c1eb09 100644 --- a/bans-env/velocityplugin/src/main/java/space/arim/libertybans/env/velocity/plugin/VelocityPlugin.java +++ b/bans-env/velocityplugin/src/main/java/space/arim/libertybans/env/velocity/plugin/VelocityPlugin.java @@ -1,6 +1,6 @@ /* * LibertyBans - * Copyright © 2022 Anand Beh + * Copyright © 2023 Anand Beh * * LibertyBans is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -94,11 +94,6 @@ private BaseFoundation initialize() { .culpritFinder(new VelocityCulpritFinder(server)) .build(); ClassLoader launchLoader = launcher.attemptLaunch().join(); - - if (launchLoader == null) { - logger.warn("Failed to launch LibertyBans"); - return null; - } BaseFoundation base; try { base = new Instantiator("space.arim.libertybans.env.velocity.VelocityLauncher", launchLoader) diff --git a/pom.xml b/pom.xml index bd40f71c4..b4cda68db 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,22 @@ + + @@ -341,6 +360,16 @@ bans-env-velocityplugin ${project.version} + + space.arim.libertybans + bans-env-standalone + ${project.version} + + + space.arim.libertybans + bans-env-standalonelauncher + ${project.version} +