diff --git a/.editorconfig b/.editorconfig index 4dad478be..0ff0a5ab9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,8 @@ indent_style = space indent_size = 4 insert_final_newline = true trim_trailing_whitespace = true +ij_kotlin_allow_trailing_comma_on_call_site = true +ij_kotlin_allow_trailing_comma = true [{*.json,*.yml}] indent_size = 2 diff --git a/.gitignore b/.gitignore index c2fe75ab6..9f803fb42 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ### Intellij ### .idea/ *.iws -/out/ +out/ *.iml .idea_modules/ atlassian-ide-plugin.xml @@ -72,11 +72,10 @@ $RECYCLE.BIN/ ### Gradle ### .gradle -/build/ -out/ +# build/ already defined under netbeans gradle-app.setting !gradle-wrapper.jar .gradletasknamecache -.git/ - +### Kotlin/JS ### +yarn.lock diff --git a/README.md b/README.md index 88cef397c..1a449c550 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,12 @@ [CI](http://ci.anvilpowered.org) (Release candidate jars) -Anvil is a mineraft plugin api that aims to help developers create structured cross-platform plugins. Included is an entity framework and many services that abstract platform-specific actions so that they can be used in common code. +Anvil is a mineraft plugin api that aims to help developers create structured cross-platform plugins. +Included is an entity framework and many services that abstract platform-specific actions so that they can be used in common code. -Anvil is not only cross-platform in the context of plugin platforms, but also in the context of databases. Currently, MongoDB and Xodus are supported, with SQL on the way. With Anvil, you can write a central abstract set of logic that applies to several database types. +Anvil is not only cross-platform in the context of plugin platforms, but also in the context of databases. +Currently, MongoDB and Xodus are supported, with SQL on the way. +With Anvil, you can write a central abstract set of logic that applies to several database types. ## Quick start @@ -17,4 +20,4 @@ repositories { dependencies { implementation 'org.anvilpowered:anvil-api:0.1' } -``` \ No newline at end of file +``` diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Anvil.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/Anvil.java deleted file mode 100644 index 90aabec6d..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Anvil.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.base.Preconditions; -import com.google.inject.Binder; -import com.google.inject.Binding; -import com.google.inject.Injector; -import com.google.inject.Module; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.coremember.CoreMemberRepository; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.base.plugin.BasePlugin; - -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"unused"}) -public class Anvil extends BasePlugin { - - static final Map> bindingsCache = new HashMap<>(); - protected static ServiceManager serviceManager; - protected static Environment environment; - private static final String NOT_LOADED = "Anvil has not been loaded yet!"; - - Anvil(String name, Injector rootInjector, Module module) { - super(name, rootInjector, module); - } - - public static BindingExtensions getBindingExtensions(Binder binder) { - return getServiceManager().provide(BindingExtensions.class, binder); - } - - public static Environment.Builder getEnvironmentBuilder() { - return getServiceManager().provide(Environment.Builder.class); - } - - public static EnvironmentManager getEnvironmentManager() { - return getServiceManager().provide(EnvironmentManager.class); - } - - public static Environment getEnvironment() { - return Preconditions.checkNotNull(environment, NOT_LOADED); - } - - public static Platform getPlatform() { - return getEnvironment().getInjector().getInstance(Platform.class); - } - - public static Registry getRegistry() { - return getEnvironment().getInjector().getInstance(Registry.class); - } - - public static CoreMemberManager getCoreMemberManager() { - return getEnvironment().getInjector().getInstance(CoreMemberManager.class); - } - - public static CoreMemberRepository getCoreMemberRepository() { - return getCoreMemberManager().getPrimaryComponent(); - } - - public static ServiceManager getServiceManager() { - if (serviceManager != null) { - return serviceManager; - } - try { - return serviceManager = (ServiceManager) - Class.forName("org.anvilpowered.anvil.api.ServiceManagerImpl").newInstance(); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { - throw new IllegalStateException("Could not find ServiceManager implementation!", e); - } - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Environment.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/Environment.java deleted file mode 100644 index 708503886..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Environment.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.base.Preconditions; -import com.google.common.reflect.TypeToken; -import com.google.inject.Binding; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Module; -import com.google.inject.Provider; -import com.google.inject.TypeLiteral; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.api.misc.Named; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.util.TextService; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -@SuppressWarnings({"UnstableApiUsage", "unchecked"}) -public interface Environment extends Named, Comparable { - - static Binding getBinding(String name, Injector injector) { - long hash = ((long) name.hashCode()) * ((long) injector.hashCode()); - Binding[] binding = {Anvil.bindingsCache.get(hash)}; - if (binding[0] != null) { - return (Binding) binding[0]; - } - injector.getBindings().forEach((k, v) -> { - if (k.getTypeLiteral().getType().getTypeName().contains(name)) { - binding[0] = v; - } - }); - Binding result = Preconditions.checkNotNull( - (Binding) binding[0], - "Could not find binding for service: " + name + " in injector " + injector - ); - Anvil.bindingsCache.put(hash, result); - return result; - } - - static Key getKey(String name, Injector injector) { - return Environment.getBinding(name, injector).getKey(); - } - - static Provider getProvider(String name, Injector injector) { - return Environment.getBinding(name, injector).getProvider(); - } - - static T getInstance(String name, Injector injector) { - return Environment.getProvider(name, injector).get(); - } - - default Binding getBinding(String name) { - return getBinding(name, getInjector()); - } - - default Key getKey(String name) { - return getKey(name, getInjector()); - } - - default Provider getProvider(String name) { - return getProvider(name, getInjector()); - } - - default T getInstance(String name) { - return getInstance(name, getInjector()); - } - - void reload(); - - Injector getInjector(); - - Object getPlugin(); - - PluginInfo getPluginInfo(); - - TextService getTextService(); - - Registry getRegistry(); - - interface Builder { - - Builder addModules(Module... modules); - - Builder addModules(Iterable modules); - - Builder addEarlyServices(Key... keys); - - Builder addEarlyServices(Iterable> keys); - - Builder addEarlyServices(Class... classes); - - Builder addEarlyServices(TypeLiteral... typeLiterals); - - Builder addEarlyServices(TypeToken... typeTokens); - - Builder addEarlyServices(Key key, Consumer initializer); - - Builder addEarlyServices(Class clazz, Consumer initializer); - - Builder addEarlyServices(TypeLiteral typeLiteral, Consumer initializer); - - Builder addEarlyServices(TypeToken typeToken, Consumer initializer); - - /** - * Sets the name for this environment builder. - * - * @param name {@link String} Name to set. - * @return {@code this} - */ - Builder setName(String name); - - /** - * Sets the root injector for this environment builder. - * - * @param rootInjector {@link Injector} to set. Pass {@code null} to unset. - * @return {@code this} - */ - Builder setRootInjector(@Nullable Injector rootInjector); - - /** - * Sets the logger, currently only necessary on Nukkit. - * - *

- * The provided logger is adapted to the {@link org.slf4j.Logger}. - * If no logger is provided on Nukkit, Anvil's logger will be used. - * (This means logs will be prefixed with "Anvil" instead of your plugin name) - *

- * - *

-         *     setLoggerSupplier(MyNukkitPlugin.this::getLogger);
-         * 
- * - * @param logger to set. - */ - Builder setLoggerSupplier(Supplier logger); - - /** - * This will load your root {@link CommandNode} as - * defined by your guice module - * - * @return {@code this} - */ - Builder withRootCommand(); - - /** - * Called when the {@link Environment} is loaded. - * - *

- * This {@link Consumer} will be invoked when the {@link Environment} - * is first loaded and on subsequent reloads. - *

- * - *

- * This method can be called multiple times on one builder. - * Preexisting listeners will be used and will not be overridden. - *

- * - * @param listener {@link Consumer} to run when this environment is loaded - * @return {@code this} - */ - Builder whenLoaded(Consumer listener); - - /** - * Called when the {@link Environment} is loaded for the first time. - * - *

- * This {@link Consumer} will only be invoked when the {@link Environment} - * is loaded for the first time. - *

- * - *

- * This method can be called multiple times on one builder. - * Preexisting listeners will be used and will not be overridden. - *

- * - * @param listener {@link Consumer} to run when this environment is ready - * @return {@code this} - */ - Builder whenReady(Consumer listener); - - /** - * Called when the {@link Environment} is reloaded. - * - *

- * This {@link Consumer} will only be invoked when the {@link Environment} - * is reloaded, but not when it is first loaded. - *

- * - *

- * This method can be called multiple times on one builder. - * Preexisting listeners will be used and will not be overridden. - *

- * - * @param listener {@link Consumer} to run when this environment is reloaded - * @return {@code this} - */ - Builder whenReloaded(Consumer listener); - - /** - * Builds an {@link Environment} and registers it. - * - * @param plugin The owner for this environment - */ - void register(Object plugin); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/EnvironmentManager.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/EnvironmentManager.java deleted file mode 100644 index 0a5080c06..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/EnvironmentManager.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -public interface EnvironmentManager { - - Environment getCoreEnvironment(); - - Environment getEnvironmentUnsafe(String name); - - Map getEnvironments(); - - Stream getEnvironmentsAsStream(Pattern pattern); - - List getEnvironments(Pattern pattern); - - Optional getEnvironment(Pattern pattern); - - Optional getEnvironment(String name); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/KUtils.kt b/anvil-api/src/main/java/org/anvilpowered/anvil/api/KUtils.kt deleted file mode 100644 index bf2327b69..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/KUtils.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api - -import java.util.Optional -import java.util.concurrent.CompletableFuture - -val whitespace = "\\s+".toRegex() - -fun String.splitContext(): Array = if (isEmpty()) arrayOf() else split(whitespace).toTypedArray() - -fun CompletableFuture>.asNullable(): CompletableFuture = thenApplyAsync { it.orElse(null) } diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Platform.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/Platform.java deleted file mode 100644 index 410891f57..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/Platform.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import org.anvilpowered.anvil.api.misc.Named; - -public interface Platform extends Named { - - /** - * Returns a lowercase identifier for the current platform - * - *

- * Examples: "bungee", "spigot", "sponge", "velocity" - *

- * - * @return A lowercase identifier for the current platform - */ - @Override - String getName(); - - /** - * @return Whether the current platform is a proxy like bungee or velocity - */ - boolean isProxy(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/ServiceManager.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/ServiceManager.java deleted file mode 100644 index ff12981f8..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/ServiceManager.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.reflect.TypeToken; - -import java.util.function.Function; -import java.util.function.Supplier; - -@SuppressWarnings({"unused", "UnstableApiUsage"}) -public interface ServiceManager { - - Supplier provideSupplier(TypeToken typeToken); - - Supplier provideSupplier(Class clazz); - - Supplier provideSupplier(String name); - - Function provideFunction(TypeToken typeToken); - - Function provideFunction(Class clazz); - - Function provideFunction(String name); - - T provide(TypeToken typeToken); - - T provide(Class clazz); - - T provide(String name); - - R provide(TypeToken typeToken, T input); - - R provide(Class clazz, T input); - - R provide(String name, T input); - - void registerBinding(TypeToken typeToken, Supplier supplier); - - void registerBinding(Class clazz, Supplier supplier); - - void registerBinding(TypeToken typeToken, Function function); - - void registerBinding(Class clazz, Function function); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandNode.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandNode.java deleted file mode 100644 index 3a709e9dc..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandNode.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.command; - -import org.anvilpowered.anvil.api.misc.Named; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Predicate; - -public interface CommandNode extends Named { - - Map, Function> getDescriptions(); - - Map, Predicate> getPermissions(); - - Map, Function> getUsages(); - - /** - * @return An array containing (in order) the names - * of parent nodes. Empty if this is the root node. - */ - default String[] getPath() { - return new String[0]; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandService.java deleted file mode 100644 index 7dff48a30..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandService.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.command; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; - -public interface CommandService { - - /** - * Generates a command that runs a child command if its alias - * matches the first argument of the generated command. - * - *

- * If {@code childCommandFallback} is false - * and the first argument does not match a child, a syntax error message will - * be shown to the source. Otherwise, the root command executor will run. - *

- * - * @param root The command to run if no child was specified. - * @param children A map of child commands and their aliases. - * @param childCommandFallback whether to fall back to the root command if the first - * argument did not match a child command alias - * @throws UnsupportedOperationException on Sponge. - * Use {@code CommandSpec} instead. - * @return A routing command - */ - TCommandExecutor generateRoutingCommand( - @Nullable TCommandExecutor root, - Map, TCommandExecutor> children, - boolean childCommandFallback - ); - - TCommandExecutor generateRootCommand( - String helpUsage, - Predicate extended - ); - - default TCommandExecutor generateRootCommand(String helpUsage) { - return generateRootCommand(helpUsage, e -> true); - } - - TCommandExecutor generateVersionCommand( - String helpUsage, - Predicate extended - ); - - default TCommandExecutor generateVersionCommand(String helpUsage) { - return generateVersionCommand(helpUsage, e -> true); - } - - /** - * Generates a help command for the provided {@link CommandNode}. - * @param node The command node to return the HelpCommand for - * @return A help command for the provided {@link CommandNode} - */ - TCommandExecutor generateHelpCommand(CommandNode node); - - /** - * @return A reload command - */ - TCommandExecutor generateReloadCommand(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberManager.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberManager.java deleted file mode 100644 index 16446ed83..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberManager.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.coremember; - -import org.anvilpowered.anvil.api.datastore.Manager; - -public interface CoreMemberManager extends Manager> { - - @Override - default String getDefaultIdentifierSingularUpper() { - return "Core member"; - } - - @Override - default String getDefaultIdentifierPluralUpper() { - return "Core members"; - } - - @Override - default String getDefaultIdentifierSingularLower() { - return "core member"; - } - - @Override - default String getDefaultIdentifierPluralLower() { - return "core members"; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberRepository.java deleted file mode 100644 index aceb64558..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/CoreMemberRepository.java +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.coremember; - -import org.anvilpowered.anvil.api.datastore.Repository; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; - -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public interface CoreMemberRepository< - TKey, - TDataStore> - extends Repository, TDataStore> { - - /** - * Ensures that a matching {@link CoreMember} exists in the database. - * - *

- * If the userName has changed since the last time this method was called, it will be updated in the database - *

- *

- * The boolean values in {@code flags} will be set according to the following rules: - *

- *

- * 0 : Whether a new member was created in the database - *

- *

- * 1 : Whether userName was updated in the database - *

- *

- * 2 : Whether ipAddress was updated in the database - *

- *

- * {@code flags} must be an array of length 8. - * There are currently 5 elements reserved for future use - *

- * - * @param userUUID {@link UUID} userUUID of user. - * @param userName {@link String} Name of user. - * @param ipAddress {@link String} IP Address of user. - * @param flags A boolean array of length 8. - * @return An {@link Optional} containing the inserted {@link CoreMember} if successful, otherwise {@link Optional#empty()} - * @throws IllegalArgumentException If {@code flags} is not of length 8 - */ - CompletableFuture>> getOneOrGenerateForUser(UUID userUUID, String userName, String ipAddress, boolean[] flags); - - /** - * Ensures that a matching {@link CoreMember} exists in the database. - * - *

- * If the userName has changed since the last time this method was called, it will be updated in the database - *

- * - * @param userUUID {@link UUID} userUUID of user - * @param userName {@link String} Name of user - * @param ipAddress {@link String} IP Address of user - * @return An {@link Optional} containing the inserted {@link CoreMember} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture>> getOneOrGenerateForUser(UUID userUUID, String userName, String ipAddress); - - /** - * @param userUUID {@link UUID} userUUID of user - * @return An {@link Optional} containing a matching {@link CoreMember} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture>> getOneForUser(UUID userUUID); - - /** - * @param userName {@link String} Name of user - * @return An {@link Optional} containing a matching {@link CoreMember} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture>> getOneForUser(String userName); - - /** - * @param ipAddress {@link String} IP Address of user - * @return A {@link List} of matching {@link CoreMember} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture>> getForIpAddress(String ipAddress); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for the document - * whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture ban(TKey id, Instant endUtc, String reason); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for documents - * whose property {@code userUUID} matches the provided {@link UUID} - * - * @param userUUID {@link UUID} userUUID of documents to update - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture banUser(UUID userUUID, Instant endUtc, String reason); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for documents - * whose property {@code userName} matches the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture banUser(String userName, Instant endUtc, String reason); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for documents - * whose property {@code ipAddress} matches the provided {@link String} - * - * @param ipAddress {@link String} ipAddress of documents to update - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture banIpAddress(String ipAddress, Instant endUtc, String reason); - - /** - * Sets the property {@code banned} to {@code false} for - * the document whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBan(TKey id); - - /** - * Sets the property {@code banned} to {@code false} for - * documents whose property {@code userUUID} matches - * the provided {@link UUID} - * - * @param userUUID {@link UUID} userUUID of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBanUser(UUID userUUID); - - /** - * Sets the property {@code banned} to {@code false} for - * documents whose property {@code userName} matches - * the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBanUser(String userName); - - /** - * Sets the property {@code banned} to {@code false} for - * documents whose property {@code ipAddress} matches - * the provided {@link String} - * - * @param ipAddress {@link String} ipAddress of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBanIpAddress(String ipAddress); - - /** - * Verifies whether the provided {@link CoreMember} is in fact - * banned. - * - *

- * A user is only banned if {@link CoreMember#isBanned()} is - * true and {@link CoreMember#getBanEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isBanned()} and - * {@link CoreMember#getBanEndUtc()} and sets the member's - * ban status accordingly. - *

- * - * @param coreMember {@link CoreMember} to verify ban for - * @return {@code true} if user is verified to be banned, otherwise {@code false} - */ - boolean checkBanned(CoreMember coreMember); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link TKey} is in fact banned. - * - *

- * A user is only banned if {@link CoreMember#isBanned()} is - * true and {@link CoreMember#getBanEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isBanned()} and - * {@link CoreMember#getBanEndUtc()} and sets the member's - * ban status accordingly. - *

- * - * @param id {@link TKey} id of member to verify ban for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be banned, otherwise {@code false} - */ - CompletableFuture checkBanned(TKey id); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link UUID} userUUID is in fact banned. - * - *

- * A user is only banned if {@link CoreMember#isBanned()} is - * true and {@link CoreMember#getBanEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isBanned()} and - * {@link CoreMember#getBanEndUtc()} and sets the member's - * ban status accordingly. - *

- * - * @param userUUID {@link UUID} userUUID of member to verify ban for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be banned, otherwise {@code false} - */ - CompletableFuture checkBannedForUser(UUID userUUID); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link String} userName is in fact banned. - * - *

- * A user is only banned if {@link CoreMember#isBanned()} is - * true and {@link CoreMember#getBanEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isBanned()} and - * {@link CoreMember#getBanEndUtc()} and sets the member's - * ban status accordingly. - *

- * - * @param userName {@link String} userUUID of member to verify ban for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be banned, otherwise {@code false} - */ - CompletableFuture checkBannedForUser(String userName); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for the document - * whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture mute(TKey id, Instant endUtc, String reason); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for documents - * whose property {@code userUUID} matches the provided {@link UUID} - * - * @param userUUID {@link UUID} userUUID of documents to update - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture muteUser(UUID userUUID, Instant endUtc, String reason); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for documents - * whose property {@code userName} matches the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture muteUser(String userName, Instant endUtc, String reason); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for documents - * whose property {@code ipAddress} matches the provided {@link String} - * - * @param ipAddress {@link String} ipAddress of documents to update - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture muteIpAddress(String ipAddress, Instant endUtc, String reason); - - /** - * Sets the property {@code muted} to {@code false} for - * the document whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMute(TKey id); - - /** - * Sets the property {@code muted} to {@code false} for - * documents whose property {@code userUUID} matches - * the provided {@link UUID} - * - * @param userUUID {@link UUID} userUUID of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMuteUser(UUID userUUID); - - /** - * Sets the property {@code muted} to {@code false} for - * documents whose property {@code userName} matches - * the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMuteUser(String userName); - - /** - * Sets the property {@code muted} to {@code false} for - * documents whose property {@code ipAddress} matches - * the provided {@link String} - * - * @param ipAddress {@link String} ipAddress of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMuteIpAddress(String ipAddress); - - /** - * Verifies whether the provided {@link CoreMember} is in fact - * muted. - * - *

- * A user is only muted if {@link CoreMember#isMuted()} is - * true and {@link CoreMember#getMuteEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isMuted()} and - * {@link CoreMember#getMuteEndUtc()} and sets the member's - * mute status accordingly. - *

- * - * @param coreMember {@link CoreMember} to verify mute for - * @return {@code true} if user is verified to be muted, otherwise {@code false} - */ - boolean checkMuted(CoreMember coreMember); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link TKey} is in fact muted. - * - *

- * A user is only muted if {@link CoreMember#isMuted()} is - * true and {@link CoreMember#getMuteEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isMuted()} and - * {@link CoreMember#getMuteEndUtc()} and sets the member's - * mute status accordingly. - *

- * - * @param id {@link TKey} id of member to verify mute for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be muted, otherwise {@code false} - */ - CompletableFuture checkMuted(TKey id); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link UUID} userUUID is in fact muted. - * - *

- * A user is only muted if {@link CoreMember#isMuted()} is - * true and {@link CoreMember#getMuteEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isMuted()} and - * {@link CoreMember#getMuteEndUtc()} and sets the member's - * mute status accordingly. - *

- * - * @param userUUID {@link UUID} userUUID of member to verify mute for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be muted, otherwise {@code false} - */ - CompletableFuture checkMutedForUser(UUID userUUID); - - /** - * Verifies whether the {@link CoreMember} matching the provided - * {@link String} userName is in fact muted. - * - *

- * A user is only muted if {@link CoreMember#isMuted()} is - * true and {@link CoreMember#getMuteEndUtc()} is in the future. - *

- * - *

- * This method checks both {@link CoreMember#isMuted()} and - * {@link CoreMember#getMuteEndUtc()} and sets the member's - * mute status accordingly. - *

- * - * @param userUUID {@link UUID} userUUID of member to verify mute for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * {@code true} if user is verified to be muted, otherwise {@code false} - */ - CompletableFuture checkMutedForUser(String userUUID); - - /** - * Updates the property {@code nickName} for the - * document whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @param nickName {@link String} new nickName - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture setNickName(TKey id, String nickName); - - /** - * Updates the property {@code nickName} for documents whose - * property {@code userUUID} matches the provided {@link UUID} - * - * @param userUUID {@link UUID} userUUID of documents to update - * @param nickName {@link String} new nickName - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture setNickNameForUser(UUID userUUID, String nickName); - - /** - * Updates the property {@code nickName} for documents whose - * property {@code userName} matches the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @param nickName {@link String} new nickName - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture setNickNameForUser(String userName, String nickName); - - /** - * Deletes the property {@code nickName} for the - * document whose id matches the provided {@link TKey} - * - * @param id {@link TKey} id of document to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture deleteNickName(TKey id); - - /** - * Deletes the property {@code nickName} for documents whose - * property {@code userUUID} matches the provided {@link UUID} - * - * @param userUUID {@link UUID} userName of documents to update - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture deleteNickNameForUser(UUID userUUID); - - /** - * Deletes the property {@code nickName} for documents whose - * property {@code userName} matches the provided {@link String} - * - * @param userName {@link String} userName of documents to update - * @return {@link CompletableFuture} wrapped {@link boolean} - * true if successful, otherwise false - */ - CompletableFuture deleteNickNameForUser(String userName); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/MongoCoreMemberRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/MongoCoreMemberRepository.java deleted file mode 100644 index 8c0a912cf..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/MongoCoreMemberRepository.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.coremember; - -import dev.morphia.Datastore; -import dev.morphia.query.Query; -import org.anvilpowered.anvil.api.datastore.MongoRepository; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public interface MongoCoreMemberRepository - extends CoreMemberRepository, - MongoRepository> { - - /** - * Creates a {@link Query} matching documents whose - * property {@code userUUID} matches the provided {@link UUID} - * - * @param userUUID {@link UUID} to create {@link Query} for - * @return {@link Query} for the provided {@link UUID} - */ - Query> asQuery(UUID userUUID); - - /** - * Creates a {@link Query} matching documents whose - * property {@code userName} matches the provided {@link String} - * - * @param userName {@link String} to create {@link Query} for - * @return {@link Query} for the provided {@link String} - */ - Query> asQuery(String userName); - - /** - * Creates a {@link Query} matching documents whose - * property {@code ipAddress} matches the provided {@link String} - * - * @param ipAddress {@link String} to create {@link Query} for - * @return {@link Query} for the provided {@link String} - */ - Query> asQueryForIpAddress(String ipAddress); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for documents that - * match the provided {@link Query} - * - * @param query {@link Query} to update documents for - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture ban(Query> query, Instant endUtc, String reason); - - /** - * Sets the property {@code banned} to {@code false} for - * documents that match the provided {@link Query} - * - * @param query {@link Query} to update documents for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBan(Query> query); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for documents that - * match the provided {@link Query} - * - * @param query {@link Query} to update documents for - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture mute(Query> query, Instant endUtc, String reason); - - /** - * Sets the property {@code muted} to {@code false} for - * documents that match the provided {@link Query} - * - * @param query {@link Query} to update documents for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMute(Query> query); - - /** - * Updates the property {@code nickName} for - * documents that match the provided {@link Query} - * - * @param query {@link Query} to update documents for - * @param nickName {@link String} new nickName - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture setNickName(Query> query, String nickName); - - /** - * Deletes the property {@code nickName} for - * documents that match the provided {@link boolean} - * @param query {@link Query} to update documents for - * @return {@link CompletableFuture} wrapped {@link Boolean} - * true if successful, otherwise false - */ - CompletableFuture deleteNickName(Query> query); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/XodusCoreMemberRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/XodusCoreMemberRepository.java deleted file mode 100644 index e49bbf20c..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/coremember/XodusCoreMemberRepository.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.coremember; - -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import jetbrains.exodus.entitystore.StoreTransaction; -import org.anvilpowered.anvil.api.datastore.XodusRepository; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; - -import java.time.Instant; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -public interface XodusCoreMemberRepository - extends CoreMemberRepository, - XodusRepository> { - - /** - * Creates a {@link Function} that acts as a {@code query} - * matching documents whose property {@code userUUID} - * matches the provided {@link UUID} - * - * @param userUUID {@link UUID} to create {@code query} for - * @return {@code query} for the provided {@link UUID} - */ - Function> asQuery(UUID userUUID); - - /** - * Creates a {@link Function} that acts as a {@code query} - * matching documents whose property {@code userName} - * matches the provided {@link String} - * - * @param userName {@link String} to create {@code query} for - * @return {@code query} for the provided {@link UUID} - */ - Function> asQuery(String userName); - - /** - * Creates a {@link Function} that acts as a {@code query} - * matching documents whose property {@code ipAddress} - * matches the provided {@link String} - * - * @param ipAddress {@link String} to create {@code query} for - * @return {@code query} for the provided {@link UUID} - */ - Function> asQueryForIpAddress(String ipAddress); - - /** - * Updates the properties {@code banEndUtc}, {@code banReason} - * and sets {@code banned} to {@code true} for documents that - * match the provided {@code query} - * - * @param query {@code query} to update documents for - * @param endUtc {@link Instant} end of the ban - * @param reason {@link String} reason for the ban - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture ban(Function> query, Instant endUtc, String reason); - - /** - * Sets the property {@code banned} to {@code false} for - * documents that match the provided {@code query} - * - * @param query {@code query} to update documents for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unBan(Function> query); - - /** - * Updates the properties {@code muteEndUtc}, {@code muteReason} - * and sets {@code muted} to {@code true} for documents that - * match the provided {@code query} - * - * @param query {@code query} to update documents for - * @param endUtc {@link Instant} end of the mute - * @param reason {@link String} reason for the mute - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture mute(Function> query, Instant endUtc, String reason); - - /** - * Sets the property {@code muted} to {@code false} for - * documents that match the provided {@code query} - * - * @param query {@code query} to update documents for - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture unMute(Function> query); - - /** - * Updates the property {@code nickName} for - * documents that match the provided {@code query} - * - * @param query {@code query} to update documents for - * @param nickName {@link String} new nickName - * @return {@link CompletableFuture} wrapped {@link Boolean}. - * true if successful, otherwise false - */ - CompletableFuture setNickName(Function> query, String nickName); - - CompletableFuture deleteNickName(Function> query); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CacheService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CacheService.java deleted file mode 100644 index 9d6b5147c..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CacheService.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; - -@Deprecated // will probably break in 0.4 -public interface CacheService< - TKey, - T extends ObjectWithId, - TDataStore> - extends Repository { - - /** - * Starts cache invalidation task - * - * @param intervalSeconds How often the cache invalidation task should run - */ - void startCacheInvalidationTask(Integer intervalSeconds); - - /** - * Stop cache invalidation task - */ - void stopCacheInvalidationTask(); - - /** - * @return Cache invalidation task - */ - Runnable getCacheInvalidationTask(); - - /** - * @return A set containing all parties in the cache - */ - Set getAllAsSet(); - - /** - * Deletes a {@link T} from the cache - * - * @param predicate of {@link T} to remove from cache - * @return An optional containing the {@link T} if it was successfully removed - */ - Optional deleteOne(Predicate predicate); - - /** - * Deletes a {@link T} from the cache - * - * @param t {@link T} to remove from cache - * @return An optional containing the {@link T} if it was successfully removed - */ - Optional delete(T t); - - /** - * Deletes a {@link T} from the cache - * - * @param predicate of {@link T} to remove from cache - * @return A list of successfully deleted elements - */ - List delete(Predicate predicate); - - List getAll(Predicate predicate); - - Optional getOne(Predicate predicate); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CachedRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CachedRepository.java deleted file mode 100644 index 87c3f428c..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/CachedRepository.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; - -@Deprecated // will probably break in 0.4 -public interface CachedRepository< - TKey, - T extends ObjectWithId, - C extends CacheService, - TDataStore> - extends Repository { - - default Optional getRepositoryCacheService() { - return Optional.empty(); - } - - /** - *

- * Usually used when (updated) data from DB needs to be applied to cache - *

- *

- * {@code toCache} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
- * - * @param The type returned from the cache and database - * @param fromDB {@link Supplier} retrieving data from DB - * @param toCache {@link BiConsumer} applying DB data to cache - * @return Result from DB after it has (optionally) been applied to cache - */ - CompletableFuture applyFromDBToCache(Supplier fromDB, BiConsumer toCache); - - /** - *

- * Usually used when (updated) data from DB needs to be applied to cache - *

- *

- * {@code toCache} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
  • - {@link Optional} result from {@code fromDB} is present
  • - *
- * - * @param The type returned from the cache and database - * @param fromDB {@link Supplier} retrieving data from DB - * @param toCache {@link BiConsumer} applying DB data to cache. - * @return Result from DB after it has (optionally) been applied to cache - */ - CompletableFuture> applyFromDBToCacheConditionally(Supplier> fromDB, BiConsumer toCache); - - /** - *

- * Usually used for editing model data - *

- *

- * {@code cacheTransformer} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
- * - * @param The type returned from the cache and database - * @param fromDB {@link Supplier} retrieving data from DB - * @param cacheTransformer {@link BiFunction} applying DB data to cache - * @return Result from cache - */ - CompletableFuture applyFromDBThroughCache(Supplier fromDB, BiFunction cacheTransformer); - - /** - *

- * Usually used for editing model data - *

- *

- * {@code cacheTransformer} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
  • - {@link Optional} result from {@code fromDB} is present
  • - *
- * - * @param The type returned from the cache and database - * @param fromDB {@link Supplier} retrieving data from DB - * @param cacheTransformer {@link BiFunction} applying DB data to cache. Will only be run if {@link Optional} is present - * @return Result from cache if result and cache are present, otherwise from DB - */ - CompletableFuture> applyFromDBThroughCacheConditionally(Supplier> fromDB, BiFunction> cacheTransformer); - - /** - *

- * Usually used for editing model data - *

- *

- * {@code cacheTransformer} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
- * - * @param The type returned by the cache and database - * @param cacheTransformer {@link Function} applying transformation to data in cache and returning new data - * @param dbTransformer {@link Function} retrieving data from db. - * {@link Optional} is the result of the cache function (will be empty if the cache or the result is not present) - * @return Result from DB - */ - CompletableFuture applyThroughBoth(Function cacheTransformer, Function, K> dbTransformer); - - /** - *

- * Usually used for retrieving or editing model data - *

- *

- * {@code cacheTransformer} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
- *

- * {@code dbTransformer} will run if and only if: - *

- *
    - *
  • - {@link Optional} result from {@code cacheTransformer} is present
  • - *
- * - * @param The type returned by the cache and database - * @param cacheTransformer {@link Function} applying transformation to data in cache and returning new data - * @param dbTransformer {@link Function} applying transformation to data in db - * @return {@link K} result from cache - */ - CompletableFuture> applyThroughBothConditionally(Function> cacheTransformer, Function dbTransformer); - - /** - *

- * Usually used for retrieving or editing model data - *

- *

- * {@code cacheTransformer} will run if and only if: - *

- *
    - *
  • - Cache is present
  • - *
- * {@code dbTransformer} will run if and only if: - *
    - *
  • - {@link Optional} result from {@code cacheTransformer} is not present
  • - *
- * - * @param The type returned by the cache and database - * @param cacheTransformer {@link Function} applying transformation to data in cache and returning new data - * @param dbSupplier {@link Supplier} retrieving data from db. Will only be run if {@link Optional} is not present - * @return {@link K} result from cache if present, otherwise from db - */ - CompletableFuture> applyToBothConditionally(Function> cacheTransformer, Supplier> dbSupplier); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Component.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Component.java deleted file mode 100644 index c3d1ffdd2..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Component.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import org.anvilpowered.anvil.api.misc.BindingExtensions; - -import java.util.Optional; - -/** - * Part of a module - * - * @see Manager - * @see Repository - * @see CacheService - * @see BindingExtensions - */ -public interface Component< - TKey, - TDataStore> { - - Class getTKeyClass(); - - DataStoreContext getDataStoreContext(); - - /** - * Tries to convert the given object to {@link TKey} - * - * @param object To try to parse - * @return The {@link TKey} representing this {@code object} - * @throws UnsupportedOperationException If not implemented - * @throws IllegalArgumentException if object was unsuccessfully parsed - */ - default TKey parseUnsafe(Object object) { - throw new UnsupportedOperationException(); - } - - /** - * Tries to convert the given object to {@link TKey} - * - * @param object To try to parse - * @return {@link Optional} containing (if parsing successful) the {@link TKey} representing this {@code object} - */ - default Optional parse(Object object) { - return Optional.empty(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/DataStoreContext.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/DataStoreContext.java deleted file mode 100644 index 9c3deb33f..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/DataStoreContext.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.registry.Registry; -import org.jetbrains.annotations.Nullable; -import org.reflections.Reflections; -import org.reflections.scanners.SubTypesScanner; -import org.reflections.scanners.TypeAnnotationsScanner; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; - -// TODO: extract to interface -public abstract class DataStoreContext { - - private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - private final List> connectionOpenedListeners; - private final List> connectionClosedListeners; - protected final Registry registry; - - @Nullable - private TDataStore dataStore; - private Class[] entityClasses; - private Class tKeyClass; - - @Inject(optional = true) - private ClassLoader classLoader; - - protected DataStoreContext(Registry registry) { - connectionOpenedListeners = new ArrayList<>(); - connectionClosedListeners = new ArrayList<>(); - - this.registry = registry; - registry.whenLoaded(this::registryLoaded).register(); - } - - protected void registryLoaded() { - requestCloseConnection(); - dataStore = null; - } - - protected abstract TDataStore loadDataStore(); - - public TDataStore getDataStore() { - if (dataStore == null) { - dataStore = loadDataStore(); - notifyConnectionOpenedListeners(dataStore); - } - return Preconditions.checkNotNull(dataStore, "An error occurred while loading datastore"); - } - - @SafeVarargs - protected final Class[] calculateEntityClasses( - final String baseScanPackage, final Class... entityAnnotations) { - if (entityAnnotations.length == 0) return EMPTY_CLASS_ARRAY; - Reflections reflections = new Reflections( - baseScanPackage, new TypeAnnotationsScanner(), new SubTypesScanner(), classLoader); - Set> types = reflections.getTypesAnnotatedWith(entityAnnotations[0]); - for (int i = 1; i < entityAnnotations.length; i++) { - types.addAll(reflections.getTypesAnnotatedWith(entityAnnotations[i])); - } - return entityClasses = types.toArray(EMPTY_CLASS_ARRAY); - } - - public final Class[] getEntityClasses() { - return entityClasses; - } - - /** - * @param name The name that the entity class contains - * @return First entityClass that contains {@code name} - */ - public final Optional> getEntityClass(final String name) { - Class clazz = null; - try { - clazz = getEntityClassUnsafe(name); - } catch (RuntimeException ignored) { - } - return Optional.ofNullable(clazz); - } - - /** - * @param name The name that the entity class contains - * @return First entityClass that contains (ignored case) the provided name - */ - public final Class getEntityClassUnsafe(final String name) { - getDataStore(); // ensure that entityClasses is not null - final String n = name.toLowerCase(Locale.ENGLISH); - for (Class entityClass : entityClasses) { - if (entityClass.getSimpleName().toLowerCase(Locale.ENGLISH).contains(n)) { - return entityClass; - } - } - throw new IllegalStateException("Could not find EntityClass for " + name); - } - - protected final void setTKeyClass(Class tKeyClass) { - this.tKeyClass = tKeyClass; - } - - public final Class getTKeyClass() { - return tKeyClass; - } - - protected abstract void closeConnection(TDataStore dataStore); - - protected final void requestCloseConnection() { - if (dataStore != null) { - notifyConnectionClosedListeners(dataStore); - closeConnection(dataStore); - dataStore = null; - } - } - - private void notifyConnectionOpenedListeners(TDataStore dataStore) { - connectionOpenedListeners.forEach(listener -> listener.accept(dataStore)); - } - - public final void addConnectionOpenedListener(Consumer connectionOpenedListener) { - connectionOpenedListeners.add(connectionOpenedListener); - } - - public final void removeConnectionOpenedListener(Consumer connectionOpenedListener) { - connectionOpenedListeners.remove(connectionOpenedListener); - } - - private void notifyConnectionClosedListeners(TDataStore dataStore) { - connectionClosedListeners.forEach(listener -> listener.accept(dataStore)); - } - - public final void addConnectionClosedListener(Consumer connectionClosedListener) { - connectionClosedListeners.add(connectionClosedListener); - } - - public final void removeConnectionClosedListener(Consumer connectionClosedListener) { - connectionClosedListeners.remove(connectionClosedListener); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Manager.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Manager.java deleted file mode 100644 index a051da41f..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Manager.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import com.google.inject.name.Named; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.util.TextService; - -/** - *

- * A module consists of a {@link Manager} and a (single) {@link Component} - * for every data storage implementation. - *

- *

- * The {@link Manager} of a module is its metaphorical gateway. Interactions with - * other modules should (almost always) be done through the {@link Manager}. - * There are, however, some cases where direct access to a component is required. - * One such case is inter-{@link Repository} access that requires compile time - * type safety. Because the {@link Component#getTKeyClass()} type is not known - * to the manager, code that interacts with {@code TKey} must be placed in a - * {@link Component}. - *

- *

- * One of the primary functions of a {@link Manager} is to provide the correct - * {@link Component} implementation via {@link #getPrimaryComponent()}. - *

- *

- * Implementations of {@link Manager} should consist of methods similar to the - * following: - *

- *
    - *
  • {@code CompletableFuture create(UUID userUUID);}
  • - *
  • {@code CompletableFuture invite(UUID userUUID, UUID targetUserUUID);}
  • - *
  • {@code CompletableFuture kick(UUID userUUID, UUID targetUserUUID);}
  • - *
  • {@code CompletableFuture> list(String query);}
  • - *
- *

- * {@code TString} is the base return type for the methods in a {@link Manager}. - * To build these results use {@link TextService.Builder}. - *

- *

- * All methods (with some exceptions) in {@link Manager} should return a form of {@code TString} - * to be displayed directly to the end user. Normally, the return type, {@code TString}, is wrapped in - * a {@link java.util.concurrent.CompletableFuture} in order to keep the main game thread - * free from IO. It is sometimes necessary to further wrap the {@code TString} in a {@link java.util.List} - * when the result is more than a single line. In this case, pagination can be used to display the result - * to the end user. - *

- *

- * The following interface signature is an example of a simple {@link Manager}: - *

- *
{@code
- * public interface FooManager<
- * TFoo extends Foo,
- * TString>
- * extends Manager>
- * }
- * - * @param Base {@link Component} type for this manager. - * Must be implemented by all components in this module - * @see Repository - * @see Component - * @see TextService - */ -public interface Manager> { - - /** - *

- * Represents the default singular identifier for this module - *

- *

- * Should be overridden by other plugins who change the name of the object. - * Examples: "Clan", "Faction", "Guild", "Member", ... etc - *

- *

- * Used in text sent to the player - *

- * - * @return The default singular identifier for this module - */ - String getDefaultIdentifierSingularUpper(); - - /** - *

- * Represents the default plural identifier for this module - *

- *

- * Should be overridden by other plugins who change the name of party. - * Examples: "Clans", "Factions", "Guilds", "Members" ... etc - *

- *

- * Used in text sent to the player - *

- * - * @return The default plural identifier for this module - */ - String getDefaultIdentifierPluralUpper(); - - /** - *

- * Represents the default singular identifier for this module - *

- *

- * Should be overridden by other plugins who change the name of party. - * Examples: "clan", "faction", "guild", "member" ... etc - *

- *

- * Used in text sent to the player - *

- * - * @return The default singular identifier for this module - */ - String getDefaultIdentifierSingularLower(); - - /** - *

- * Represents the default plural identifier for this module - *

- *

- * Should be overridden by other plugins who change the name of party. - * Examples: "clans", "factions", "guilds", "members" ... etc - *

- *

- * Used in text sent to the player - *

- * - * @return The default plural identifier for this module - */ - String getDefaultIdentifierPluralLower(); - - /** - * Provides the current {@link Component} as defined by - * {@link Keys#DATA_STORE_NAME} in the current {@link Registry}. - * - *

- * The current {@link Component} implementation is defined as the - * implementation provided by Guice that meets the following criteria: - *

- *
- *

- * The value for {@link Keys#DATA_STORE_NAME} found by - * the the current {@link Registry} must match (ignored case) a registered - * datastore implementation. This can be one of the following predefined values: - *

- *
    - *
  • {@code "mongodb"}
  • - *
  • {@code "xodus"}
  • - *
- *

- * or a custom value defined by your guice module. - *

- *
- *

- * For example, 'mongodb' (or any capitalization thereof) will match - * a {@link Component} annotated with {@link Named}{@code (value = "mongodb"} - *

- *

- * Use {@link BindingExtensions} to bind your component implementations - *

- * - * @return The current {@link Component} implementation - * @throws IllegalStateException If the config has not been loaded yet, - * or if no implementation was found - * @see Component - * @see BindingExtensions - */ - C getPrimaryComponent(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoContext.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoContext.java deleted file mode 100644 index d0ca5ec3b..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoContext.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientURI; -import dev.morphia.Datastore; -import dev.morphia.Morphia; -import dev.morphia.annotations.Embedded; -import dev.morphia.annotations.Entity; -import dev.morphia.mapping.MapperOptions; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.bson.types.ObjectId; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - -@Singleton -public final class MongoContext extends DataStoreContext { - - @Inject - public MongoContext(Registry registry) { - super(registry); - } - - @Override - protected void closeConnection(Datastore dataStore) { - dataStore.getMongo().close(); - } - - @Override - protected Datastore loadDataStore() { - - /* === Get values from config === */ - String connectionString = registry.getExtraSafe(Keys.MONGODB_CONNECTION_STRING); - String hostname = registry.getExtraSafe(Keys.MONGODB_HOSTNAME); - int port = registry.getExtraSafe(Keys.MONGODB_PORT); - String dbName = registry.getExtraSafe(Keys.MONGODB_DBNAME); - String username = registry.getExtraSafe(Keys.MONGODB_USERNAME); - String password = registry.getExtraSafe(Keys.MONGODB_PASSWORD); - String authDb = registry.getExtraSafe(Keys.MONGODB_AUTH_DB); - boolean useAuth = registry.getExtraSafe(Keys.MONGODB_USE_AUTH); - boolean useSrv = registry.getExtraSafe(Keys.MONGODB_USE_SRV); - boolean useConnectionString = registry.getExtraSafe(Keys.MONGODB_USE_CONNECTION_STRING); - - /* === Determine credentials for MongoDB === */ - String clientUrl; - String protocol = useSrv ? "mongodb+srv://" : "mongodb://"; - String pt = useSrv ? "" : ":" + port; - if (useConnectionString) { - clientUrl = connectionString; - } else if (useAuth) { - String encodedPassword = password; - try { - encodedPassword = URLEncoder.encode(password, "UTF-8"); - } catch (UnsupportedEncodingException ignored) { - } - clientUrl = protocol + username + ":" + encodedPassword + "@" + hostname + pt + "/" + dbName + "?authSource=" + authDb; - } else { - clientUrl = protocol + hostname + pt + "/" + dbName; - } - - /* === Establish MongoDB connection === */ - MongoClientURI uri = new MongoClientURI(clientUrl); - MongoClient mongoClient = new MongoClient(uri); - Morphia morphia = new Morphia(); - Datastore dataStore = morphia.createDatastore(mongoClient, dbName); - dataStore.ensureIndexes(); - - /* === Save mapped objects and register with morphia === */ - morphia.map(calculateEntityClasses(registry.getOrDefault(Keys.BASE_SCAN_PACKAGE), Entity.class, Embedded.class)); - - /* === Set class loader to prevent morphia from breaking === */ - morphia.getMapper().setOptions(MapperOptions.legacy() - .classLoader(getClass().getClassLoader()) - .build()); - - setTKeyClass(ObjectId.class); - return dataStore; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoRepository.java deleted file mode 100644 index 0a9467d3f..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/MongoRepository.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import dev.morphia.Datastore; -import dev.morphia.query.Query; -import dev.morphia.query.UpdateOperations; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -public interface MongoRepository< - T extends ObjectWithId> - extends Repository { - - CompletableFuture> getOne(Query query); - - CompletableFuture> getAll(Query query); - - CompletableFuture delete(Query query); - - UpdateOperations createUpdateOperations(); - - UpdateOperations inc(String field, Number value); - - UpdateOperations inc(String field); - - UpdateOperations set(String field, Object value); - - UpdateOperations unSet(String field); - - CompletableFuture update(Query query, UpdateOperations updateOperations); - - CompletableFuture update(Optional> optionalQuery, - UpdateOperations updateOperations); - - Query asQuery(); - - Query asQuery(ObjectId id); - - Query asQuery(Instant createdUtc); - - Optional> asQueryForIdOrTime(String idOrTime); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Repository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Repository.java deleted file mode 100644 index b09840e13..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/Repository.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.anvilpowered.anvil.api.util.TimeFormatService; - -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -public interface Repository< - TKey, - T extends ObjectWithId, - TDataStore> - extends Component { - - /** - * @return An empty {@link T} - */ - T generateEmpty(); - - Class getTClass(); - - /** - * @param id A id of the document - * @return The time of creation of this document as an {@link Instant} - */ - default CompletableFuture> getCreatedUtc(TKey id) { - return getOne(id).thenApplyAsync(o -> o.map(ObjectWithId::getCreatedUtc)); - } - - /** - * @param item A {@link T document} to insert - * @return An {@link Optional} containing the inserted {@link T document} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture> insertOne(T item); - - /** - * @param list A {@link List} of {@link T documents} to insert - * @return A {@link List} of all {@link T documents} that were successfully inserted - */ - CompletableFuture> insert(List list); - - /** - * @return A {@link List} of all {@link TKey ids} in the repository - */ - CompletableFuture> getAllIds(); - - /** - * @return A {@link List} of all {@link T documents} in the repository - */ - CompletableFuture> getAll(); - - /** - * Attempts to find a matching {@link T document} with the provided {@link TKey id} - * - * @param id An {@link TKey id} to query the repository with - * @return An {@link Optional} containing a matching {@link T document} if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture> getOne(TKey id); - - /** - * Attempts to find the first {@link T document} where {@link Instant#getEpochSecond()} retrieved from - * {@link ObjectWithId#getCreatedUtc()} is equal to {@link Instant#getEpochSecond()} of the provided {@link Instant} - * - * @param createdUtc An {@link Instant} to query the repository with - * @return An {@link Optional} containing if successful, otherwise {@link Optional#empty()} - */ - CompletableFuture> getOne(Instant createdUtc); - - /** - * Attempts to find a matching {@link T document} by parsing provided id or time. - * - *

- * Attempts to parse the provided {@link Object} as an id. If parsing is successful, returns the - * result of {@link #getOne(Object)}. - *

- * - *

- * If parsing as an id is unsuccessful, attempts to parse the provided {@link Object} as createdUtc. - * If parsing is successful, returns the result of {@link #getOne(Instant)} - *

- * - *

- * Note: if parsing as id is successful but no document is found, will not attempt to parse as time - *

- * - * @param idOrTime An id or time to parse. Can be an instance of {@link TKey} or a {@link String} representation. May - * also be wrapped in an {@link Optional} - * @return An {@link Optional} containing a matching {@link T document} if successful, otherwise {@link Optional#empty()} - * @see Component#parseUnsafe(Object) - * @see Component#parse(Object) - * @see TimeFormatService#parseInstantUnsafe(String) - * @see TimeFormatService#parseInstant(String) - */ - CompletableFuture> parseAndGetOne(Object idOrTime); - - /** - * Attempts to delete a matching {@link T document} with the provided {@link TKey id} - * - * @param id An {@link TKey id} to query the repository with - * @return Whether or not an item was found and deleted - */ - CompletableFuture deleteOne(TKey id); - - /** - * Attempts to delete the first {@link T document} where {@link Instant#getEpochSecond()} retrieved from - * {@link ObjectWithId#getCreatedUtc()} is equal to {@link Instant#getEpochSecond()} of the provided {@link Instant} - * - * @param createdUtc An {@link Instant} to query the repository with - * @return Whether a {@link T document} was found and deleted - */ - CompletableFuture deleteOne(Instant createdUtc); - - /** - * Attempts to delete a matching {@link T document} by parsing provided id or time. - * - *

- * Attempts to parse the provided {@link Object} as an id. If parsing is successful, returns the - * result of {@link #deleteOne(Object)}. - *

- * - *

- * If parsing as an id is unsuccessful, attempts to parse the provided {@link Object} as createdUtc. - * If parsing is successful, returns the result of {@link #deleteOne(Instant)} - *

- * - *

- * Note: if id parsing is successful but no document is found, will not attempt to parse as time - *

- * - * @param idOrTime {@link Object} to parse. Can be an instance of {@link TKey} or a {@link String} representation. May - * also be wrapped in an {@link Optional} - * @return Whether a {@link T document} was found and deleted - * @see Component#parseUnsafe(Object) - * @see Component#parse(Object) - * @see TimeFormatService#parseInstantUnsafe(String) - * @see TimeFormatService#parseInstant(String) - */ - CompletableFuture parseAndDeleteOne(Object idOrTime); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusContext.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusContext.java deleted file mode 100644 index 73103ed58..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusContext.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import jetbrains.exodus.entitystore.PersistentEntityStores; -import org.anvilpowered.anvil.api.model.Mappable; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; - -import java.io.File; -import java.nio.file.Paths; - -@Singleton -public final class XodusContext extends DataStoreContext { - - @Inject - public XodusContext(Registry registry) { - super(registry); - } - - @Override - protected void closeConnection(PersistentEntityStore dataStore) { - dataStore.close(); - } - - @Override - protected PersistentEntityStore loadDataStore() { - - /* === Initialize storage location === */ - File dbFilesLocation = Paths.get(registry.getOrDefault(Keys.DATA_DIRECTORY) + "/data/xodus").toFile(); - if (!dbFilesLocation.exists()) { - if (!dbFilesLocation.mkdirs()) { - throw new IllegalStateException("Unable to create xodus directory"); - } - } - - /* === Find objects to map === */ - Class[] entityClasses = calculateEntityClasses(registry.getOrDefault(Keys.BASE_SCAN_PACKAGE), XodusEntity.class, XodusEmbedded.class); - - /* === Create collections if not present === */ - for (Class entityClass : entityClasses) { - if (Mappable.class.isAssignableFrom(entityClass)) { - try { - entityClass.getDeclaredMethod("writeTo", Entity.class); - entityClass.getDeclaredMethod("readFrom", Entity.class); - } catch (NoSuchMethodException e) { - throw new IllegalStateException("Xodus entity class " + entityClass.getName() + " must implement Mappable#writeTo(T) and Mappable#readFrom(T)", e); - } - } else if (entityClass.isAnnotationPresent(XodusEntity.class)){ - throw new IllegalStateException("Xodus entity class " + entityClass.getName() + " must extend org.anvilpowered.anvil.model.data.dbo.Mappable"); - } - } - - setTKeyClass(EntityId.class); - return PersistentEntityStores.newInstance(dbFilesLocation.getPath()); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEmbedded.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEmbedded.java deleted file mode 100644 index ef3412f3e..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEmbedded.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface XodusEmbedded { -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEntity.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEntity.java deleted file mode 100644 index 0ac601ac6..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusEntity.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface XodusEntity { -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusRepository.java deleted file mode 100644 index 95f9b6d64..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/datastore/XodusRepository.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.datastore; - -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import jetbrains.exodus.entitystore.StoreTransaction; -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.time.Instant; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.Function; - -public interface XodusRepository< - T extends ObjectWithId> - extends Repository { - - Iterator iterator( - Function> query); - - CompletableFuture> getAll( - Function> query); - - CompletableFuture> getOne( - Function> query); - - CompletableFuture delete( - Function> query); - - CompletableFuture update( - Function> query, - Consumer update); - - CompletableFuture update( - Optional>> optionalQuery, - Consumer update); - - Function> asQuery( - EntityId id); - - Function> asQuery( - Instant createdUtc); - - Optional>> asQueryForIdOrTime( - String idOrTime); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionCriteria.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionCriteria.java deleted file mode 100644 index b5381b84e..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionCriteria.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.entity; - -import com.google.common.base.MoreObjects; - -public final class RestrictionCriteria { - - private static final RestrictionCriteria ALL = new RestrictionCriteria( - true, - true, - true, - true, - true - ); - - private static final RestrictionCriteria NONE = new RestrictionCriteria( - false, - false, - false, - false, - false - ); - - private static final RestrictionCriteria MOVEMENT_ONLY = new RestrictionCriteria( - true, - false, - false, - false, - false - ); - - private static final RestrictionCriteria INTERACTION_ONLY = new RestrictionCriteria( - false, - true, - false, - false, - false - ); - - private static final RestrictionCriteria INVENTORY_ONLY = new RestrictionCriteria( - false, - false, - true, - false, - false - ); - - private static final RestrictionCriteria COMMANDS_ONLY = new RestrictionCriteria( - false, - false, - false, - true, - false - ); - - private static final RestrictionCriteria DAMAGE_ONLY = new RestrictionCriteria( - false, - false, - false, - false, - true - ); - - public static RestrictionCriteria all() { - return ALL; - } - - public static RestrictionCriteria none() { - return NONE; - } - - public static RestrictionCriteria movementOnly() { - return MOVEMENT_ONLY; - } - - public static RestrictionCriteria interactionOnly() { - return INTERACTION_ONLY; - } - - public static RestrictionCriteria inventoryOnly() { - return INVENTORY_ONLY; - } - - public static RestrictionCriteria commandsOnly() { - return COMMANDS_ONLY; - } - - public static RestrictionCriteria damageOnly() { - return DAMAGE_ONLY; - } - - public final static class Builder { - private boolean movement = false; - private boolean interaction = false; - private boolean inventory = false; - private boolean commands = false; - private boolean damage = false; - - private Builder() { - } - - public Builder movement(boolean movement) { - this.movement = movement; - return this; - } - - public Builder interaction(boolean interaction) { - this.interaction = interaction; - return this; - } - - public Builder inventory(boolean inventory) { - this.inventory = inventory; - return this; - } - - public Builder commands(boolean commands) { - this.commands = commands; - return this; - } - - public Builder damage(boolean damage) { - this.damage = damage; - return this; - } - - public RestrictionCriteria build() { - return new RestrictionCriteria( - movement, - interaction, - inventory, - commands, - damage - ); - } - } - - public static Builder builder() { - return new Builder(); - } - - /** - * Prevents entity movement. This includes all movement keys (WASD + space) in addition to external influences. - */ - private final boolean movement; - - /** - * Prevents all interactions that occurs as the result of a right-click. - */ - private final boolean interaction; - - /** - * Prevents all inventory transactions. - */ - private final boolean inventory; - - /** - * Prevents all commands. - */ - private final boolean commands; - - /** - * Prevents damage dealt and taken. - */ - private final boolean damage; - - public RestrictionCriteria( - boolean movement, - boolean interaction, - boolean inventory, - boolean commands, - boolean damage - ) { - this.movement = movement; - this.interaction = interaction; - this.inventory = inventory; - this.commands = commands; - this.damage = damage; - } - - public RestrictionCriteria union(RestrictionCriteria criteria) { - final boolean movement = this.movement || criteria.movement; - final boolean interaction = this.interaction || criteria.interaction; - final boolean inventory = this.inventory || criteria.inventory; - final boolean commands = this.commands || criteria.commands; - final boolean damage = this.damage || criteria.damage; - return new RestrictionCriteria( - movement, - interaction, - inventory, - commands, - damage - ); - } - - public RestrictionCriteria intersect(RestrictionCriteria criteria) { - final boolean movement = this.movement && criteria.movement; - final boolean interaction = this.interaction && criteria.interaction; - final boolean inventory = this.inventory && criteria.inventory; - final boolean commands = this.commands && criteria.commands; - final boolean damage = this.damage && criteria.damage; - return new RestrictionCriteria( - movement, - interaction, - inventory, - commands, - damage - ); - } - - public boolean hasAll() { - return movement - && interaction - && inventory - && commands - && damage - ; - } - - public boolean hasAny() { - return movement - || interaction - || inventory - || commands - || damage - ; - } - - public boolean movement() { - return movement; - } - - public boolean interaction() { - return interaction; - } - - public boolean inventory() { - return inventory; - } - - public boolean commands() { - return commands; - } - - public boolean damage() { - return damage; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof RestrictionCriteria)) { - return false; - } - final RestrictionCriteria other = (RestrictionCriteria) obj; - return movement == other.movement - && interaction == other.interaction - && inventory == other.inventory - && commands == other.commands - && damage == other.damage - ; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("movement", movement) - .add("interaction", interaction) - .add("inventory", inventory) - .add("commands", commands) - .add("damage", damage) - .toString(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionService.java deleted file mode 100644 index 428bafc55..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/entity/RestrictionService.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.entity; - -import java.util.Optional; -import java.util.UUID; - -public interface RestrictionService { - - /** - *

- * Restricts the provided entity as specified by the provided {@link RestrictionCriteria}, overwriting any - * previous restrictions. - *

- *
- *

- * If the provided entity is identifiable by {@link UUID}, the provided {@link RestrictionCriteria} - * will be registered with said {@link UUID} rather than the provided entity instance. - *

- * - * @param entity The entity to restrict - * @param criteria The {@link RestrictionCriteria} to restrict with - */ - void put(Object entity, RestrictionCriteria criteria); - - /** - *

- * Restricts entities identified by the provided {@link UUID} as specified by the provided - * {@link RestrictionCriteria}, overwriting any previous restrictions. - *

- * - * @param uuid The uuid of the entity to restrict - * @param criteria The {@link RestrictionCriteria} to restrict with - */ - void put(UUID uuid, RestrictionCriteria criteria); - - /** - *

- * Stops all restrictions for the provided entity. - *

- *
- *

- * If the provided entity is identifiable by {@link UUID}, removes all restrictions for entities identified by - * said {@link UUID}. - *

- * - * @param entity The entity to stop restrictions for - * @return An {@link Optional} containing the removed {@link RestrictionCriteria} if it existed, - * otherwise {@link Optional#empty()} - */ - Optional remove(Object entity); - - /** - *

- * Stops all restrictions for entities identified by the provided {@link UUID}. - *

- * - * @param uuid The uuid of the entity to stop restricting - * @return An {@link Optional} containing the removed {@link RestrictionCriteria} if it existed, - * otherwise {@link Optional#empty()} - */ - Optional remove(UUID uuid); - - /** - *

- * Checks whether the provided entity is restricted. - *

- * - * @param entity The entity to check - * @return The {@link RestrictionCriteria} associated with the provided entity, otherwise - * {@link RestrictionCriteria#none()} - */ - RestrictionCriteria get(Object entity); - - /** - *

- * Checks whether the entity identified by the provided {@link UUID} is restricted. - *

- * - * @param uuid The {@link UUID} of the entity to check - * @return The {@link RestrictionCriteria} associated with the provided {@link UUID}, otherwise - * {@link RestrictionCriteria#none()} - */ - RestrictionCriteria get(UUID uuid); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/BindingExtensions.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/BindingExtensions.java deleted file mode 100644 index 7e6dbeede..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/BindingExtensions.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.misc; - -import com.google.common.reflect.TypeToken; -import com.google.inject.Key; -import com.google.inject.Provider; -import com.google.inject.TypeLiteral; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.datastore.Component; -import org.anvilpowered.anvil.api.datastore.DataStoreContext; - -import java.lang.annotation.Annotation; - -@SuppressWarnings({"unchecked", "UnstableApiUsage"}) -public interface BindingExtensions { - - /** - * Full binding method for a component - *

- * A typical example of usage of this method: - *

- *
{@code
-     * be.bind(
-     *     new TypeToken>(getClass()) {
-     *     },
-     *     new TypeToken>(getClass()) {
-     *     },
-     *     new TypeToken, Datastore>>(getClass()) {
-     *     },
-     *     new TypeToken>(getClass()) { // final implementation
-     *     },
-     *     Names.named("mongodb")
-     * );
-     * }
- */ - , - From2 extends Component, - From3 extends From1, - Target extends From1> - void bind( - TypeToken from1, - TypeToken from2, - TypeToken from3, - TypeToken target, - Annotation componentAnnotation - ); - - /** - * Binding method for a component - *

- * A typical example of usage of this method: - *

- *
{@code
-     * be.bind(
-     *     new TypeToken>(getClass()) {
-     *     },
-     *     new TypeToken>(getClass()) {
-     *     },
-     *     new TypeToken(getClass()) { // final implementation
-     *     },
-     *     Names.named("mongodb")
-     * );
-     * }
- */ - , - From2 extends From1, - Target extends From1> - void bind( - TypeToken from1, - TypeToken from2, - TypeToken target, - Annotation componentAnnotation - ); - - void bind( - TypeToken from, - TypeToken target, - Annotation annotation - ); - - void bind( - TypeToken from, - TypeToken target, - Class annotation - ); - - void bind( - TypeToken from, - TypeToken target - ); - - /** - * Binds the mongodb {@link DataStoreContext} - *

- * Using this method is the same as invoking: - *

- *
{@code
-     * bind(new TypeLiteral>() {
-     * }).to(MongoContext.class);
-     * }
- */ - void withMongoDB(); - - /** - * Binds the xodus {@link DataStoreContext} - *

- * Using this method is the same as invoking: - *

- *
{@code
-     * binder.bind(new TypeLiteral>() {
-     * }).to(XodusContext.class);
-     * }
- */ - void withXodus(); - - - static TypeLiteral getTypeLiteral(TypeToken typeToken) { - return (TypeLiteral) TypeLiteral.get(typeToken.getType()); - } - - static Key getKey(TypeToken typeToken) { - return Key.get(getTypeLiteral(typeToken)); - } - - static Provider asInternalProvider(Class clazz) { - return () -> Anvil.getEnvironment().getInjector() - .getInstance(clazz); - } - - static Provider asInternalProvider(TypeLiteral typeLiteral) { - return () -> Anvil.getEnvironment().getInjector() - .getInstance(Key.get(typeLiteral)); - } - - static Provider asInternalProvider(TypeToken typeToken) { - return () -> Anvil.getEnvironment().getInjector() - .getInstance(BindingExtensions.getKey(typeToken)); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/Mappable.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/Mappable.java deleted file mode 100644 index 2363a567d..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/Mappable.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.model; - -import com.google.common.collect.ImmutableList; -import jetbrains.exodus.util.ByteArraySizedInputStream; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInput; -import java.io.ObjectInputStream; -import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -public interface Mappable { - - /** - * Writes all data from this object to the provided {@code object}. - *

- * Fields that are {@code null} in this object but not {@code null} - * in the target object should not be overwritten. - *

- * - * @param object Object to write data to - * @return object with data written to. Same instance as provided object - */ - T writeTo(T object); - - /** - * Reads all data from the provided {@code object} to this object - *

- * Fields that are {@code null} in the provided object but not {@code null} - * this object should not be overwritten. - *

- * - * @param object Object to read data from - */ - void readFrom(T object); - - static byte[] serializeUnsafe(Object object) throws IOException { - try ( - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutput oos = new ObjectOutputStream(baos) - ) { - oos.writeObject(object); - return baos.toByteArray(); - } - } - - static Optional serialize(Object object) { - try { - return Optional.of(serializeUnsafe(object)); - } catch (IOException ignored) { - return Optional.empty(); - } - } - - @SuppressWarnings("unchecked") - static T deserializeUnsafe(InputStream inputStream) throws IOException, ClassNotFoundException { - try ( - ObjectInput objectInputStream = new ObjectInputStream(inputStream) - ) { - return (T) objectInputStream.readObject(); - } - } - - static Optional deserialize(InputStream inputStream) { - try { - return Optional.of(deserializeUnsafe(inputStream)); - } catch (IOException | ClassNotFoundException | ClassCastException ignored) { - return Optional.empty(); - } - } - - static boolean addToCollection(InputStream inputStream, Consumer callback, Collection elements) { - Collection collection; - try { - collection = deserializeUnsafe(inputStream); - } catch (IOException | ClassNotFoundException ignored) { - return false; - } - try { - collection.addAll(elements); - } catch (UnsupportedOperationException ignored) { - Collection temp = new ArrayList<>(collection.size() + elements.size()); - temp.addAll(collection); - temp.addAll(elements); - collection = temp; - } - byte[] data; - try { - data = serializeUnsafe(collection); - } catch (IOException ignored) { - return false; - } - callback.accept(new ByteArraySizedInputStream(data)); - return true; - } - - @SafeVarargs - static boolean addToCollection(InputStream inputStream, Consumer callback, T... elements) { - return addToCollection(inputStream, callback, ImmutableList.copyOf(elements)); - } - - static boolean removeFromCollection(InputStream inputStream, Consumer callback, - Predicate filter) { - Collection collection; - try { - collection = deserializeUnsafe(inputStream); - } catch (IOException | ClassNotFoundException ignored) { - return false; - } - try { - collection.removeIf(filter); - } catch (UnsupportedOperationException ignored) { - collection = collection.stream().filter(filter.negate()).collect(Collectors.toList()); - } - byte[] data; - try { - data = serializeUnsafe(collection); - } catch (IOException ignored) { - return false; - } - callback.accept(new ByteArraySizedInputStream(data)); - return true; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/ObjectWithId.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/ObjectWithId.java deleted file mode 100644 index b818a0252..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/ObjectWithId.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.model; - -import java.time.Instant; - -public interface ObjectWithId { - - TKey getId(); - void setId(TKey id); - - String getIdAsString(); - - Instant getCreatedUtc(); - Instant getUpdatedUtc(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/coremember/CoreMember.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/coremember/CoreMember.java deleted file mode 100644 index 2218d2141..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/model/coremember/CoreMember.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.model.coremember; - -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.time.Instant; -import java.util.UUID; - -public interface CoreMember extends ObjectWithId { - - UUID getUserUUID(); - void setUserUUID(UUID userUUID); - - String getUserName(); - void setUserName(String userName); - - String getIpAddress(); - void setIpAddress(String ipAddress); - - Instant getLastJoinedUtc(); - void setLastJoinedUtc(Instant joinedUtc); - - String getNickName(); - void setNickName(String nickName); - - boolean isBanned(); - void setBanned(boolean banned); - - boolean isMuted(); - void setMuted(boolean muted); - - Instant getBanEndUtc(); - void setBanEndUtc(Instant banEndUtc); - - Instant getMuteEndUtc(); - void setMuteEndUtc(Instant muteEndUtc); - - String getBanReason(); - void setBanReason(String banReason); - - String getMuteReason(); - void setMuteReason(String muteReason); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/BasicPluginInfo.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/BasicPluginInfo.java deleted file mode 100644 index e2cff1d80..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/BasicPluginInfo.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.plugin; - -import org.anvilpowered.anvil.api.misc.Named; - -public interface BasicPluginInfo extends Named { - - String getId(); - - String getVersion(); - - String getDescription(); - - String getUrl(); - - String[] getAuthors(); - - String getOrganizationName(); - - String getBuildDate(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ConfigurationService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ConfigurationService.java deleted file mode 100644 index 5ff0c4436..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ConfigurationService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -public interface ConfigurationService extends Registry { - - /** - * Updates the config with values from the registry. Will only update the file if changes were made - * - * @return {@code true} if there were updated values to save and they were saved successfully - * otherwise {@code false} - */ - boolean save(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Key.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Key.java deleted file mode 100644 index 707513390..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Key.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import com.google.common.reflect.TypeToken; -import org.anvilpowered.anvil.api.misc.Named; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.function.Function; - -@SuppressWarnings({"UnstableApiUsage", "unchecked"}) -public abstract class Key implements Named, Comparable> { - - private final TypeToken type; - private final String name; - private final T fallbackValue; - private final boolean userImmutable; - private final boolean sensitive; - @Nullable - private final String description; - @Nullable - private final Function parser; - @Nullable - private final Function toStringer; - - Key( - TypeToken type, - String name, - @Nullable T fallbackValue, - boolean userImmutable, - boolean sensitive, - @Nullable String description, - @Nullable Function parser, - @Nullable Function toStringer - ) { - this.type = type; - this.name = name; - this.fallbackValue = fallbackValue; - this.userImmutable = userImmutable; - this.sensitive = sensitive; - this.description = description; - if (parser == null) { - this.parser = extractParser(fallbackValue); - } else { - this.parser = parser; - } - this.toStringer = toStringer; - } - - public interface Builder { - - /** - * Sets the name of the generated {@link Key} - * - * @param name The name to set - * @return {@code this} - */ - Builder name(String name); - - /** - * Sets the fallback value of the generated {@link Key} - * - * @param fallbackValue The fallback value to set - * @return {@code this} - */ - Builder fallback(@Nullable T fallbackValue); - - /** - * Indicates that the generated {@link Key} cannot be changed by the user. - * - * @return {@code this} - */ - Builder userImmutable(); - - /** - * Indicates that the generated {@link Key} is sensitive (e.g. connection details) that should not - * be accessible through regedit by default. Values of sensitive keys can only be viewed or modified - * through registries that have {@link Keys#REGEDIT_ALLOW_SENSITIVE} enabled. - * - * @return {@code this} - */ - Builder sensitive(); - - /** - * Sets the description of the generated {@link Key}. - * - * @param description The description to set or {@code null} to remove it - * @return {@code this} - */ - Builder description(@Nullable String description); - - /** - * Sets the parser of the generated {@link Key}. - * - * @param parser The parser to set or {@code null} to remove it - * @return {@code this} - */ - Builder parser(@Nullable Function parser); - - /** - * Sets the toStringer of the generated {@link Key}. - * - * @param toStringer The toStringer to set or {@code null} to remove it - * @return {@code this} - */ - Builder toStringer(@Nullable Function toStringer); - - /** - * Generates a {@link Key} based on this builder. - * - * @return The generated {@link Key} - */ - Key build(); - } - - public static Builder builder(TypeToken type) { - return new KeyBuilder<>(type); - } - - @Nullable - private Function extractParser(@Nullable T value) { - if (value instanceof String) { - return s -> (T) s; - } else if (value instanceof Boolean) { - return s -> (T) Boolean.valueOf(s); - } else if (value instanceof Double) { - return s -> (T) Double.valueOf(s); - } else if (value instanceof Float) { - return s -> (T) Float.valueOf(s); - } else if (value instanceof Long) { - return s -> (T) Long.valueOf(s); - } else if (value instanceof Integer) { - return s -> (T) Integer.valueOf(s); - } else if (value instanceof Short) { - return s -> (T) Short.valueOf(s); - } else if (value instanceof Byte) { - return s -> (T) Byte.valueOf(s); - } - return null; - } - - @Nullable - public T parse(String value) { - if (parser == null) { - return null; - } - return parser.apply(value); - } - - public String toString(@Nullable T value) { - if (toStringer == null) { - return String.valueOf(value); - } - return String.valueOf(toStringer.apply(value)); - } - - @Override - public int compareTo(Key o) { - return name.compareToIgnoreCase(o.name); - } - - @Override - public boolean equals(Object o) { - return o instanceof Key && name.equalsIgnoreCase(((Key) o).name); - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return name; - } - - public TypeToken getType() { - return type; - } - - @Override - public String getName() { - return name; - } - - public T getFallbackValue() { - return fallbackValue; - } - - public boolean isUserImmutable() { - return userImmutable; - } - - public boolean isSensitive() { - return sensitive; - } - - public boolean isSensitive(Registry registry) { - return isSensitive() && !registry.get(Keys.REGEDIT_ALLOW_SENSITIVE).orElse(false); - } - - @Nullable - public String getDescription() { - return description; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/KeyBuilder.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/KeyBuilder.java deleted file mode 100644 index 99b419fef..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/KeyBuilder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import com.google.common.base.Preconditions; -import com.google.common.reflect.TypeToken; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.function.Function; - -@SuppressWarnings("UnstableApiUsage") -class KeyBuilder implements Key.Builder { - - private final TypeToken type; - @MonotonicNonNull - private String name; - @Nullable - private T fallbackValue; - private boolean userImmutable; - private boolean sensitive; - @Nullable - private String description; - @Nullable - private Function parser; - @Nullable - private Function toStringer; - - KeyBuilder(TypeToken type) { - this.type = Preconditions.checkNotNull(type, "type"); - this.sensitive = false; - } - - @Override - public Key.Builder name(String name) { - this.name = Preconditions.checkNotNull(name, "name"); - return this; - } - - @Override - public Key.Builder fallback(@Nullable T fallbackValue) { - this.fallbackValue = fallbackValue; - return this; - } - - @Override - public KeyBuilder userImmutable() { - userImmutable = true; - return this; - } - - @Override - public KeyBuilder sensitive() { - sensitive = true; - return this; - } - - @Override - public KeyBuilder description(@Nullable String description) { - this.description = description; - return this; - } - - @Override - public KeyBuilder parser(@Nullable Function parser) { - this.parser = parser; - return this; - } - - @Override - public KeyBuilder toStringer(@Nullable Function toStringer) { - this.toStringer = toStringer; - return this; - } - - @Override - public Key build() { - Preconditions.checkNotNull(name, "name"); - return new Key(type, name, fallbackValue, userImmutable, sensitive, description, parser, toStringer) { - }; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Keys.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Keys.java deleted file mode 100644 index 80c57053c..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Keys.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import com.google.common.base.Preconditions; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Table; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.time.ZoneId; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Optional; - -public final class Keys { - - private static final String GLOBAL_NAMESPACE - = "global"; - - private static final Table> keys - = HashBasedTable.create(); - - private static final Map>> localAndGlobalCache - = new HashMap<>(); - - private Keys() { - throw new AssertionError("**boss music** No instance for you!"); - } - - /** - *

- * Used to start the registration of keys in a namespace. - *

- *
- *

- * Example usage: - *

- *

-     * static {
-     *     Keys.startRegistration("ontime")
-     *         .register(RANKS)
-     *         .register(CHECK_PERMISSION)
-     *         .register(CHECK_EXTENDED_PERMISSION)
-     *         .register(EDIT_PERMISSION)
-     *         .register(IMPORT_PERMISSION);
-     * }
-     * 
- * - * @param nameSpace The namespace to register the keys in. Usually the name of the plugin. - * @return A {@link KeyRegistrationEnd} instance for registering keys - */ - public static KeyRegistrationEnd startRegistration(String nameSpace) { - return new KeyRegistrationEnd(nameSpace); - } - - public final static class KeyRegistrationEnd { - - private final String nameSpace; - - KeyRegistrationEnd(String nameSpace) { - this.nameSpace = nameSpace; - } - - private void checkName(String nameSpace, String name) { - if (keys.contains(nameSpace, name)) { - throw new IllegalArgumentException("The provided key " + name + " conflicts with a" - + " key of the same name in the " + nameSpace + " namespace."); - } - } - - /** - * Registers the provided key. - * - * @param key The {@link Key} to register - * @return {@code this} - */ - public KeyRegistrationEnd register(Key key) { - final String name = key.getName(); - checkName(nameSpace, name); - keys.put(nameSpace, key.getName(), key); - return this; - } - } - - @SuppressWarnings("unchecked") - public static Key resolveUnsafe(String name, String nameSpace) { - return (Key) Preconditions.checkNotNull(keys.get(nameSpace, name)); - } - - @SuppressWarnings("unchecked") - public static Optional> resolve(String name, String nameSpace) { - return Optional.ofNullable((Key) keys.get(nameSpace, name)); - } - - @SuppressWarnings("unchecked") - public static Key resolveUnsafe(String name) { - return (Key) resolve(name).orElseThrow(() -> - new IllegalArgumentException("Could not resolve key " + name)); - } - - @SuppressWarnings("unchecked") - public static Optional> resolve(String name) { - @Nullable - Key candidate = (Key) keys.get(GLOBAL_NAMESPACE, name); - if (candidate != null) { - return Optional.of(candidate); - } - Iterator> it = keys.column(name).values().iterator(); - if (it.hasNext()) { - return Optional.of((Key) it.next()); - } else { - return Optional.empty(); - } - } - - @SuppressWarnings("unchecked") - public static Optional> resolveLocalAndGlobal(String name, String nameSpace) { - @Nullable - Key candidate = (Key) keys.get(nameSpace, name); - if (candidate != null) { - return Optional.of(candidate); - } - return Optional.ofNullable((Key) keys.get(GLOBAL_NAMESPACE, name)); - } - - public static Map> getAll(String nameSpace) { - Map> result = localAndGlobalCache.get(nameSpace); - if (result != null) { - return result; - } - result = ImmutableMap.>builder() - .putAll(keys.row(nameSpace)) - .putAll(keys.row(GLOBAL_NAMESPACE)) - .build(); - localAndGlobalCache.put(nameSpace, result); - return result; - } - - public static final Key SERVER_NAME = - Key.builder(TypeTokens.STRING) - .name("SERVER_NAME") - .fallback("server") - .build(); - public static final Key TIME_ZONE = - Key.builder(TypeTokens.ZONE_ID) - .name("TIME_ZONE") - .fallback(ZoneId.systemDefault()) - .parser(ZoneIdSerializer::parse) - .toStringer(ZoneIdSerializer::toString) - .build(); - public static final Key PROXY_MODE = - Key.builder(TypeTokens.BOOLEAN) - .name("PROXY_MODE") - .fallback(false) - .build(); - public static final Key REGEDIT_ALLOW_SENSITIVE = - Key.builder(TypeTokens.BOOLEAN) - .name("REGEDIT_ALLOW_SENSITIVE") - .fallback(false) - .userImmutable() - .build(); - public static final Key BASE_SCAN_PACKAGE = - Key.builder(TypeTokens.STRING) - .name("BASE_SCAN_PACKAGE") - .fallback("org.anvilpowered.anvil.common.model") - .userImmutable() - .build(); - public static final Key CACHE_INVALIDATION_INTERVAL_SECONDS = - Key.builder(TypeTokens.INTEGER) - .name("CACHE_INVALIDATION_INTERVAL_SECONDS") - .fallback(30) - .build(); - public static final Key CACHE_INVALIDATION_TIMOUT_SECONDS = - Key.builder(TypeTokens.INTEGER) - .name("CACHE_INVALIDATION_TIMOUT_SECONDS") - .fallback(300) - .build(); - public static final Key USE_SHARED_ENVIRONMENT = - Key.builder(TypeTokens.BOOLEAN) - .name("USE_SHARED_ENVIRONMENT") - .fallback(false) - .sensitive() - .build(); - public static final Key USE_SHARED_CREDENTIALS = - Key.builder(TypeTokens.BOOLEAN) - .name("USE_SHARED_CREDENTIALS") - .fallback(false) - .sensitive() - .build(); - public static final Key DATA_DIRECTORY = - Key.builder(TypeTokens.STRING) - .name("DATA_DIRECTORY") - .fallback("anvil") - .sensitive() - .build(); - public static final Key DATA_STORE_NAME = - Key.builder(TypeTokens.STRING) - .name("DATA_STORE_NAME") - .fallback("xodus") - .sensitive() - .build(); - public static final Key MONGODB_CONNECTION_STRING = - Key.builder(TypeTokens.STRING) - .name("MONGODB_CONNECTION_STRING") - .fallback("mongodb://admin:password@localhost:27017/anvil?authSource=admin") - .sensitive() - .build(); - public static final Key MONGODB_HOSTNAME = - Key.builder(TypeTokens.STRING) - .name("MONGODB_HOSTNAME") - .fallback("localhost") - .sensitive() - .build(); - public static final Key MONGODB_PORT = - Key.builder(TypeTokens.INTEGER) - .name("MONGODB_PORT") - .fallback(27017) - .sensitive() - .build(); - public static final Key MONGODB_DBNAME = - Key.builder(TypeTokens.STRING) - .name("MONGODB_DBNAME") - .fallback("anvil") - .sensitive() - .build(); - public static final Key MONGODB_USERNAME = - Key.builder(TypeTokens.STRING) - .name("MONGODB_USERNAME") - .fallback("admin") - .sensitive() - .build(); - public static final Key MONGODB_PASSWORD = - Key.builder(TypeTokens.STRING) - .name("MONGODB_PASSWORD") - .fallback("password") - .sensitive() - .build(); - public static final Key MONGODB_AUTH_DB = - Key.builder(TypeTokens.STRING) - .name("MONGODB_AUTH_DB") - .fallback("admin") - .sensitive() - .build(); - public static final Key MONGODB_USE_AUTH = - Key.builder(TypeTokens.BOOLEAN) - .name("MONGODB_USE_AUTH") - .fallback(false) - .sensitive() - .build(); - public static final Key MONGODB_USE_SRV = - Key.builder(TypeTokens.BOOLEAN) - .name("MONGODB_USE_SRV") - .fallback(false) - .sensitive() - .build(); - public static final Key MONGODB_USE_CONNECTION_STRING = - Key.builder(TypeTokens.BOOLEAN) - .name("MONGODB_USE_CONNECTION_STRING") - .fallback(false) - .sensitive() - .build(); - - public static final Key PLUGINS_PERMISSION = - Key.builder(TypeTokens.STRING) - .name("PLUGINS_PERMISSION") - .fallback("anvil.admin.plugins") - .build(); - public static final Key REGEDIT_PERMISSION = - Key.builder(TypeTokens.STRING) - .name("REGEDIT_PERMISSION") - .fallback("anvil.admin.regedit") - .build(); - public static final Key RELOAD_PERMISSION = - Key.builder(TypeTokens.STRING) - .name("RELOAD_PERMISSION") - .fallback("anvil.admin.reload") - .build(); - - static { - startRegistration(GLOBAL_NAMESPACE) - .register(SERVER_NAME) - .register(TIME_ZONE) - .register(PROXY_MODE) - .register(REGEDIT_ALLOW_SENSITIVE) - .register(BASE_SCAN_PACKAGE) - .register(CACHE_INVALIDATION_INTERVAL_SECONDS) - .register(CACHE_INVALIDATION_TIMOUT_SECONDS) - .register(USE_SHARED_ENVIRONMENT) - .register(USE_SHARED_CREDENTIALS) - .register(DATA_DIRECTORY) - .register(DATA_STORE_NAME) - .register(MONGODB_HOSTNAME) - .register(MONGODB_PORT) - .register(MONGODB_DBNAME) - .register(MONGODB_USERNAME) - .register(MONGODB_PASSWORD) - .register(MONGODB_AUTH_DB) - .register(MONGODB_USE_AUTH) - .register(MONGODB_USE_SRV); - - startRegistration("anvil") - .register(PLUGINS_PERMISSION) - .register(REGEDIT_PERMISSION) - .register(RELOAD_PERMISSION) - ; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Registry.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Registry.java deleted file mode 100644 index 94ad567bd..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/Registry.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import org.anvilpowered.anvil.api.Environment; - -import java.util.Collection; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.function.BiFunction; -import java.util.function.Function; - -public interface Registry { - - /** - * Gets this registry's value for the provided {@link Key} - * and throws an exception if it is not present. - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to get the value for - * @return This registry's value for the provided {@link Key} - * @throws NoSuchElementException If this registry has no value defined - * for the provided {@link Key} - */ - @RegistryScoped - T getUnsafe(Key key); - - /** - * Gets this registry's value for the provided {@link Key} - * or {@link Optional#empty()} if it is not present. - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to get the value for - * @return This registry's value for the provided {@link Key} or {@link Optional#empty()} - */ - @RegistryScoped - Optional get(Key key); - - /** - * Gets this registry's default value for the provided {@link Key} - * or the fallback value if it is not present. - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to get the default value for - * @return This registry's default value for the provided {@link Key} or the fallback value - */ - @RegistryScoped - default T getDefault(Key key) { - return key.getFallbackValue(); - } - - /** - * Gets this registry's value for the provided {@link Key} - * or the default value if it is not present. - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to get the value or (if not present) the default value for - * @return This registry's value for the provided {@link Key} or the default value - */ - @RegistryScoped - default T getOrDefault(Key key) { - return get(key).orElse(getDefault(key)); - } - - /** - * Similar to {@link #getOrDefault(Key)}, but performs additional (implementation specific) - * checks that could potentially check other registries if certain requirements are met. - * Use {@link #getOrDefault(Key)} unless you are sure you need this. - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to get the value for - * @return The value for the provided {@link Key} as defined by the additional checks - */ - @RegistryScoped - default T getExtraSafe(Key key) { - return getOrDefault(key); - } - - /** - * Sets this registry's value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to set the value for - * @param value The value to set - */ - @RegistryScoped - void set(Key key, T value); - - /** - * Removes this registry's value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to set the value for - */ - @RegistryScoped - void remove(Key key); - - /** - * Applies the provided transformation to this registry's - * value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to transform the value for - * @param transformer The transformation to apply - */ - @RegistryScoped - void transform(Key key, BiFunction, ? super T, ? extends T> transformer); - - /** - * Applies the provided transformation to this registry's - * value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} to transform the value for - * @param transformer The transformation to apply - */ - @RegistryScoped - void transform(Key key, Function transformer); - - /** - * Adds the provided value to this registry's - * {@link Collection} value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} of the collection - * to add the provided value to - * @param value The value to add - */ - @RegistryScoped - void addToCollection(Key> key, T value); - - /** - * Removes the provided value from this registry's - * {@link Collection} value for the provided {@link Key} - * - * @param The value type of the provided {@link Key} - * @param key The {@link Key} of the collection - * to add the provided value to - * @param value The value to add - */ - @RegistryScoped - void removeFromCollection(Key> key, T value); - - /** - * Puts the provided key and value pair to this registry's - * {@link Map} value for the provided {@link Key} - * - * @param The key type of the map value for the provided key - * @param The value type of the map value for the provided key - * @param key The {@link Key} of the map to add the - * provided key and value pair to - * @param mapKey The map key to add - * @param mapValue The map value to add - */ - @RegistryScoped - void putInMap(Key> key, K mapKey, T mapValue); - - /** - * Removes the provided key from this registry's - * {@link Map} value for the provided {@link Key} - * - * @param The key type of the map value for the provided key - * @param The value type of the map value for the provided key - * @param key The {@link Key} of the map to remove the provided mapKey from - * @param mapKey The map key to remove - */ - @RegistryScoped - void removeFromMap(Key> key, K mapKey); - - /** - * Runs all {@link Runnable listeners} that were - * added before this call in the provided registryScope. - * - * @param registryScope The {@link RegistryScope} to load - * @see Environment#reload() - * @see #whenLoaded(Runnable) - */ - @RegistryScoped - void load(RegistryScope registryScope); - - /** - * Runs all {@link Runnable listeners} that were - * added before this call in the {@link RegistryScope#DEFAULT default scope}. - * - * @see Environment#reload() - * @see #whenLoaded(Runnable) - */ - @RegistryScoped - default void load() { - load(RegistryScope.DEFAULT); - } - - /** - * Adds a {@link Runnable} to be loaded on {@link #load()}. - * - *

- * Listeners are grouped by order. Smaller orders run before larger ones. - * The execution order within one order group is not guaranteed. - *

- *

- * Please note that {@link ListenerRegistrationEnd#register()} must be invoked to - * complete the registration. - *

- * - * @param listener Listener to add - * @return A {@link ListenerRegistrationEnd} for specifying additional parameters and - * completing the registration. - * @see #load() - */ - ListenerRegistrationEnd whenLoaded(Runnable listener); - - interface ListenerRegistrationEnd { - - /** - * Sets the order for the listener. - * The default order is 0. - * - * @param order The order to run this listener in. Smaller is earlier. - * @return {@code this} - */ - ListenerRegistrationEnd order(int order); - - /** - * Sets the scope for the listener. - * The default scope is {@link RegistryScope#DEFAULT}. - * - * @param scope The scope to run this listener in. - * @return {@code this} - * @see RegistryScope - * @see RegistryScoped - */ - ListenerRegistrationEnd scope(RegistryScope scope); - - /** - * Completes the listener registration. - */ - void register(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScope.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScope.java deleted file mode 100644 index 8bc20b9c9..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScope.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -public enum RegistryScope { - - /** - * The annotated value persists only between deep reloads. - *

- * Use this scope for values that should be reloadable but not necessarily - * during normal operation of the plugin. - *

- */ - DEEP, - - /** - * The annotated value persists only between normal reloads. - * This value is the default value for the {@link RegistryScoped} annotation. - *

- * Use this scope for - *

- */ - DEFAULT, -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScoped.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScoped.java deleted file mode 100644 index 5c3cb8bed..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/RegistryScoped.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; - -/** - * Used to indicate the persistence of a value or validity of a method in relation to reloads. - *

- * A field annotated with {@code RegistryScoped} must be persisted (cached) only between reloads - * of that scope. For example, you may choose to persist a result calculated from a configurable - * value (see {@link Registry}). This is illustrated here: - *

- *

- * public class FooService {
- *
- *     // this instance is persisted only for the duration of the scope
- *    {@literal @}RegistryScoped
- *     private Foo foo;
- *
- *     // used to calculate foo
- *     private final Registry registry;
- *
- *    {@literal @}Inject
- *     public FooService(Registry registry) {
- *         this.registry = registry;
- *         registry.whenLoaded(this::loaded).register();
- *     }
- *
- *     public void loaded() {
- *         // invalidate foo
- *         foo = null;
- *     }
- *
- *     // instances returned here are persisted only for the duration of the scope
- *    {@literal @}RegistryScoped
- *     public Foo getFoo() {
- *         if (foo == null) {
- *             foo = ...; // use registry for lazy initialization of foo
- *         }
- *         return foo;
- *     }
- * }
- * 
- *

- * A method annotated with {@code RegistryScoped} must be invoked inside of a reloaded listener - * of the same scope. An example of this is {@link Registry#set(Key, Object)}. Although it has a - * void return type, the side effects of this method will only persist during a scope and so must - * be invoked again to maintain these side effects. - *

- */ -@Target({ - FIELD, - METHOD, -}) -public @interface RegistryScoped { - - RegistryScope value() default RegistryScope.DEFAULT; -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/TypeTokens.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/TypeTokens.java deleted file mode 100644 index 0a92d4970..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/TypeTokens.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import com.google.common.reflect.TypeToken; - -import java.time.ZoneId; - -@SuppressWarnings("UnstableApiUsage") -public final class TypeTokens { - - private TypeTokens() { - throw new AssertionError("**boss music** No instance for you!"); - } - - public static final TypeToken BOOLEAN = TypeToken.of(Boolean.class); - public static final TypeToken INTEGER = TypeToken.of(Integer.class); - public static final TypeToken STRING = TypeToken.of(String.class); - public static final TypeToken ZONE_ID = TypeToken.of(ZoneId.class); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ZoneIdSerializer.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ZoneIdSerializer.java deleted file mode 100644 index d992c2a53..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/registry/ZoneIdSerializer.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.registry; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.time.ZoneId; - -public class ZoneIdSerializer { - - private static final String AUTO = "auto"; - - public static ZoneId parse(@Nullable String input) { - if (input == null || AUTO.equals(input)) { - return ZoneId.systemDefault(); - } else { - return ZoneId.of(input); - } - } - - public static String toString(@Nullable ZoneId zoneId) { - return zoneId == null || zoneId.equals(ZoneId.systemDefault()) ? AUTO : zoneId.getId(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/BackendServer.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/BackendServer.java deleted file mode 100644 index 4ab6dd031..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/BackendServer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.server; - -import org.anvilpowered.anvil.api.misc.Named; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public interface BackendServer extends Named { - - CompletableFuture getVersion(); - - CompletableFuture connect(@Nullable Object player); - - CompletableFuture connect(UUID userUUID); - - CompletableFuture connect(String userName); - - List getPlayerUUIDs(); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/LocationService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/LocationService.java deleted file mode 100644 index 3303858c0..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/LocationService.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.server; - -import com.flowpowered.math.vector.Vector3d; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public interface LocationService { - - Optional getServer(UUID userUUID); - - Optional getServer(String userName); - - Optional getServerForName(String serverName); - - List getServers(); - - Optional getWorldName(UUID userUUID); - - Optional getWorldName(String userName); - - Optional getPosition(UUID userUUID); - - Optional getPosition(String userName); - - CompletableFuture teleport(UUID teleportingUserUUID, UUID targetUserUUID); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/PermissionService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/PermissionService.java deleted file mode 100644 index cf5e02ae3..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/PermissionService.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.util; - -import org.checkerframework.checker.nullness.qual.Nullable; - -public interface PermissionService { - - /** - * Checks whether the provided {@code subject} has - * the provided {@code permission}. Depending on - * the target platform, this can be a - * Player, User, Group etc... - * - *

- * If the provided {@code subject} is the console, returns {@code true} - *

- * - *

- * If the provided {@code subject} is {@code null}, returns {@code false} - *

- * - * @param subject The {@code subject} to test - * @param permission The {@code permission} to check - * @return Whether the provided {@code subject} has - * the provided {@code permission} or is the console. - */ - boolean hasPermission(@Nullable Object subject, String permission); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TextService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TextService.java deleted file mode 100644 index 6baccd0d9..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TextService.java +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.util; - -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.net.URL; -import java.util.Optional; -import java.util.UUID; -import java.util.function.Consumer; - -public interface TextService - extends Result { - - /** - * @return A new {@link Builder} instance - */ - Builder builder(); - - /** - * @return A new {@link PaginationBuilder} instance - */ - PaginationBuilder paginationBuilder(); - - /** - * Create a {@link TString} with the provided contents - * - * @param contents The contents to add to the result - * @return A built {@link TString} - */ - default TString of(Object... contents) { - return builder().append(contents).build(); - } - - /** - * Create a {@link TString} with the provided contents - * - * @param contents The contents to add to the result - * @return A built {@link TString} - */ - default TString of(CharSequence... contents) { - return builder().append(contents).build(); - } - - /** - * Sends the provided {@link TString text} to the provided {@link TCommandSource receiver}. - * - * @param text The {@link TString text} to send - * @param receiver The {@link TCommandSource receiver} to send the provided text to - */ - void send(TString text, TCommandSource receiver); - - /** - * Sends the provided {@link TString text} to the provided {@link TCommandSource receiver}, - * originating from the provided {@link UUID sourceUUID}. - * - * @param text The {@link TString text} to send - * @param receiver The {@link TCommandSource receiver} to send the provided text to - * @param sourceUUID The {@link UUID} of the source of the message - */ - void send(TString text, TCommandSource receiver, UUID sourceUUID); - - /** - * Sends the provided {@link TString text} to the provided {@link TCommandSource receiver}, - * originating from the provided source. Attempts to extract a {@link UUID} - * from the provided source to server as the identity. - * - * @param text The {@link TString text} to send - * @param receiver The {@link TCommandSource receiver} source to send the provided text to - * @param source The source of the message - */ - void send(TString text, TCommandSource receiver, Object source); - - /** - * Send the provided {@link TString text} to the console - * - * @param text The {@link TString text} to send - */ - default void sendToConsole(TString text) { - send(text, getConsole()); - } - - /** - * @return The server console - */ - TCommandSource getConsole(); - - /** - * Deserializes the provided {@link String} using the - * character {@literal '&'} to determine styles. - * - * @param text {@link String} text to deserialize - * @return The {@link TString} result of the deserialization - */ - TString deserialize(String text); - - /** - * Serializes the provided {@link String} using the - * character {@literal '&'} to serialize styles. - * - * @param text {@link TString} text to serialize - * @return The {@link String} result of the serialization - */ - String serialize(TString text); - - /** - * Serializes the provided {@link String} and - * ignores all styles. - * - * @param text {@link TString} text to serialize - * @return The {@link String} result of the serialization - */ - String serializePlain(TString text); - - /** - * Removes all styles codes from the provided {@link String} - * using the character {@literal '&'} to determine styles - * - *

- * For example, {@code "&l&bhello &aworld"} becomes {@code "hello world"} - *

- * - * @param text {@link String} text to remove color from - * @return The provided {@link String} without any color codes - */ - String toPlain(String text); - - /** - * Counts the number of lines in the provided {@link TString} - * - * @param text {@link TString} text to count lines - * @return The number of lines in the provided {@link TString}. - * -1 if null. 0 if empty. - */ - int lineCount(@Nullable TString text); - - /** - * Counts the number of characters in the provided {@link TString} - * excluding color codes. - * - * @param text {@link TString} text to count characters - * @return The number of characters in the provided {@link TString}. - * -1 if null. 0 if empty. - */ - default int length(@Nullable TString text) { - return text == null - ? -1 - : serializePlain(text).length(); - } - - interface Builder { - - /** - * Sets the current color to aqua. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder aqua(); - - /** - * Sets the current color to black. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder black(); - - /** - * Sets the current color to blue. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder blue(); - - /** - * Sets the current color to dark aqua. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_aqua(); - - /** - * Sets the current color to dark blue. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_blue(); - - /** - * Sets the current color to dark gray. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_gray(); - - /** - * Sets the current color to dark green. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_green(); - - /** - * Sets the current color to dark purple. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_purple(); - - /** - * Sets the current color to dark red. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder dark_red(); - - /** - * Sets the current color to gold. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder gold(); - - /** - * Sets the current color to gray. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder gray(); - - /** - * Sets the current color to green. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder green(); - - /** - * Sets the current color to light purple. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder light_purple(); - - /** - * Sets the current color to red. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder red(); - - /** - * Resets the current style to default. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder reset(); - - /** - * Sets the current color to white. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder white(); - - /** - * Sets the current color to yellow. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder yellow(); - - /** - * Sets the current style to bold. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder bold(); - - /** - * Sets the current style to italic. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder italic(); - - /** - * Sets the current style to obfuscated. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder obfuscated(); - - /** - * Sets the current style to strikethrough. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder strikethrough(); - - /** - * Sets the current style to underlined. Only applies - * to text appended after this call. - * - * @return {@code this} - */ - Builder underlined(); - - /** - * Append the provided contents to this builder - * - * @param contents {@link Object} contents to append - * @return {@code this} - */ - Builder append( - Object... contents); - - /** - * Append the provided contents to this builder - * - * @param contents {@link CharSequence} contents to append - * @return {@code this} - */ - Builder append( - CharSequence... contents); - - /** - * Append the provided contents to this builder - * {@code count} times. - * - *

- * This method is the same as: - *

- *
{@code
-         * for (int i = 0; i < count; i++) {
-         *     builder.append(contents);
-         * }
-         * }
- * - * @param count number of times to append the provided contents - * @param contents {@link Object} contents to append - * @return {@code this} - */ - Builder appendCount( - int count, Object... contents); - - /** - * Append the provided contents to this builder - * {@code count} times. - * - *

- * This method is the same as: - *

- *
{@code
-         * for (int i = 0; i < count; i++) {
-         *     builder.append(contents);
-         * }
-         * }
- * - * @param count number of times to append the provided contents - * @param contents {@link CharSequence} contents to append - * @return {@code this} - */ - Builder appendCount( - int count, CharSequence... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on the left side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingLeft(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "----------hello"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingLeft(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "abcabcabchello"} (14 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the left side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingLeft( - int width, Object padding, Object... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on the left side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingLeft(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "----------hello"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingLeft(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "abcabcabchello"} (14 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the left side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingLeft( - int width, Object padding, CharSequence... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on both the left and right side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingAround(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "-----hello-----"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingAround(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "abchelloabc"} (11 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - * Note: The amount of padding on the left and right side will - * always be the same - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the left and right side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingAround( - int width, Object padding, Object... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on both the left and right side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingAround(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "-----hello-----"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingAround(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "abchelloabc"} (11 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - * Note: The amount of padding on the left and right side will - * always be the same - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the left and right side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingAround( - int width, Object padding, CharSequence... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on the right side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingRight(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "hello----------"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingRight(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "helloabcabcabc"} (14 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the right side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingRight( - int width, Object padding, Object... contents); - - /** - * Append the provided contents to this builder - * and add the provided padding on the right side - * until the result is at most {@code width} wide. - * - *

- * An example of usage is: - *

- *
{@code
-         * builder.appendWithPaddingRight(15, '-', "hello");
-         * }
- *

- * which appends the result {@code "hello----------"} - *

- *
- *

- * If the value for padding is longer than one character, - * the appended result may not reach the full provided {@code width}. - * This can be seen in the following example: - *

- *
{@code
-         * builder.appendWithPaddingRight(15, "abc", "hello");
-         * }
- *

- * which appends the result {@code "helloabcabcabc"} (14 characters instead of 15) - *

- *
- *

- * This happens because the remaining width is not a multiple of - * the length of the provided padding, which makes it impossible fill - * the full length of the appended result. - *

- *
- *

- * Note: The appended result will be at most {@code width} wide, or - * an exception will be thrown - *

- * - * @param width The maximum total width after padding - * @param padding The padding to fill the right side with - * @param contents The contents to append - * @return {@code this} - * @throws IllegalArgumentException If width {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal <} 1 - * @throws IllegalArgumentException If padding length {@literal >} width - * @throws IllegalArgumentException If contents length {@literal >} width - */ - Builder appendWithPaddingRight( - int width, Object padding, CharSequence... contents); - - /** - * Append the provided contents if {@code condition} is true. - * - *

- * This method is the same as: - *

- *
{@code
-         * if (condition) {
-         *     builder.append(contents);
-         * }
-         * }
- * - * @param condition The condition to check - * @param contents The contents to append - * @return {@code this} - */ - Builder appendIf( - boolean condition, Object... contents); - - /** - * Append the provided contents if {@code condition} is true. - * - *

- * This method is the same as: - *

- *
{@code
-         * if (condition) {
-         *     builder.append(contents);
-         * }
-         * }
- * - * @param condition The condition to check - * @param contents The contents to append - * @return {@code this} - */ - Builder appendIf( - boolean condition, CharSequence... contents); - - /** - * Append the provided contents, putting the - * provided delimiter between each element - * - *
{@code
-         * builder.appendJoining(", ", "Bob", "Alice", "Steven");
-         * }
- *

- * is the same as - *

- *
{@code
-         * builder.append("Bob", ", ", "Alice", ", ", "Steven");
-         * }
- *

- * They both append: {@code "Bob, Alice, Steven"} - *

- * - * @param delimiter The delimiter to put between each element - * @param contents The contents to append - * @return {@code this} - */ - Builder appendJoining( - Object delimiter, Object... contents); - - /** - * Append the provided contents, putting the - * provided delimiter between each element - * - *
{@code
-         * builder.appendJoining(", ", "Bob", "Alice", "Steven");
-         * }
- *

- * is the same as - *

- *
{@code
-         * builder.append("Bob", ", ", "Alice", ", ", "Steven");
-         * }
- *

- * They both append: {@code "Bob, Alice, Steven"} - *

- * - * @param delimiter The delimiter to put between each element - * @param contents The contents to append - * @return {@code this} - */ - Builder appendJoining( - Object delimiter, CharSequence... contents); - - /** - * Append the provided contents if {@code condition} is true, - * putting the provided delimiter between each element - * - *

- * This is a combination of {@link #appendIf(boolean, Object...)} - * and {@link #appendJoining(Object, Object...)} - *

- * - *
{@code
-         * builder.appendJoiningIf(condition, ", ", "Bob", "Alice", "Steven");
-         * }
- *

- * is the same as - *

- *
{@code
-         * if (condition) {
-         *     builder.append("Bob", ", ", "Alice", ", ", "Steven");
-         * }
-         * }
- *

- * They both append: {@code "Bob, Alice, Steven"} if {@code condition} is true - *

- * - * @param condition The condition to check before appending - * @param delimiter The delimiter to put between each element - * @param contents The contents to append - * @return {@code this} - */ - Builder appendJoiningIf( - boolean condition, Object delimiter, Object... contents); - - /** - * Append the provided contents if {@code condition} is true, - * putting the provided delimiter between each element - * - *

- * This is a combination of {@link #appendIf(boolean, CharSequence...)} - * and {@link #appendJoining(Object, CharSequence...)} - *

- * - *
{@code
-         * builder.appendJoiningIf(condition, ", ", "Bob", "Alice", "Steven");
-         * }
- *

- * is the same as - *

- *
{@code
-         * if (condition) {
-         *     builder.append("Bob", ", ", "Alice", ", ", "Steven");
-         * }
-         * }
- *

- * They both append: {@code "Bob, Alice, Steven"} if {@code condition} is true - *

- * - * @param condition The condition to check before appending - * @param delimiter The delimiter to put between each element - * @param contents The contents to append - * @return {@code this} - */ - Builder appendJoiningIf( - boolean condition, Object delimiter, CharSequence... contents); - - /** - * Fetches the plugin prefix from the bound {@link PluginInfo} and appends it to this builder. - * - * @return {@code this} - */ - Builder appendPrefix(); - - /** - * Show the provided text as a tooltip while - * the mouse is hovering over this text - * - * @param text The text to show on hover - * @return {@code this} - */ - Builder onHoverShowText( - TString text); - - /** - * Show the provided text as a tooltip while - * the mouse is hovering over this text - * - * @param builder The text to show on hover - * @return {@code this} - */ - Builder onHoverShowText( - Builder builder); - - /** - * Suggest the provided command to the provided{@link TCommandSource} when - * they click This puts it in their chat bar but does not run the command. - * - * @param command The command to suggest - * @return {@code this} - */ - Builder onClickSuggestCommand( - String command); - - /** - * Run the provided command as the provided {@link TCommandSource} when they click. - * - * @param command The command to run - * @return {@code this} - */ - Builder onClickRunCommand( - String command); - - /** - * Run the provided callback, passing the provided {@link TCommandSource}, when they click. - * - * @param callback The callback to run - * @return {@code this} - */ - Builder onClickExecuteCallback( - Consumer callback); - - /** - * Open a url in a browser when this text is clicked. - * - * @param url The url to open - * @return {@code this} - */ - Builder onClickOpenUrl( - URL url); - - /** - * Open a url in a browser when this text is clicked. - * - * @param url The url to open - * @return {@code this} - */ - Builder onClickOpenUrl( - String url); - - /** - * Creates a {@link TString} from this builder. - * - * @return The built {@link TString} - */ - TString build(); - - /** - * Creates a {@link TString text} from this builder and sends it to the provided {@link TCommandSource receiver} - * - * @param receiver The {@link TCommandSource receiver} to send the {@link TString text} to - */ - void sendTo(TCommandSource receiver); - - /** - * Creates a {@link TString} from this builder and sends - * it to the console - */ - void sendToConsole(); - } - - interface PaginationBuilder { - - /** - * Sets the contents of this {@link PaginationBuilder}. - * - * @param contents The contents to set - * @return {@code this} - */ - PaginationBuilder contents( - TString... contents); - - /** - * Sets the contents of this {@link PaginationBuilder}. - * - * @param contents The contents to set - * @return {@code this} - */ - PaginationBuilder contents( - Iterable contents); - - /** - * Sets the title of this {@link PaginationBuilder}. - * - * @param title The title to set, should be exactly one line - * @return {@code this} - */ - PaginationBuilder title( - @Nullable TString title); - - /** - * Sets the title of this {@link PaginationBuilder}. - * - * @param title The title to set, should be exactly one line - * @return {@code this} - */ - PaginationBuilder title( - @Nullable Builder title); - - /** - * Sets the header of this {@link PaginationBuilder}. - * - *

- * If the header is not specified, or passed in as {@code null}, - * it will be omitted when displaying this pagination. - *

- * - * @param header The header to set - * @return {@code this} - */ - PaginationBuilder header( - @Nullable TString header); - - /** - * Sets the header of this {@link PaginationBuilder}. - * - *

- * If the header is not specified, or passed in as {@code null}, - * it will be omitted when displaying this pagination. - *

- * - * @param header The header to set - * @return {@code this} - */ - PaginationBuilder header( - @Nullable Builder header); - - /** - * Sets the footer of this {@link PaginationBuilder}. - * - *

- * If the footer is not specified, or passed in as {@code null}, - * it will be omitted when displaying this pagination. - *

- * - * @param footer The footer to set - * @return {@code this} - */ - PaginationBuilder footer( - @Nullable TString footer); - - /** - * Sets the footer of this {@link PaginationBuilder}. - * - *

- * If the footer is not specified, or passed in as {@code null}, - * it will be omitted when displaying this pagination. - *

- * - * @param footer The footer to set - * @return {@code this} - */ - PaginationBuilder footer( - @Nullable Builder footer); - - /** - * Sets the padding of this {@link PaginationBuilder}. - * - * @param padding The padding to set - * @return {@code this} - */ - PaginationBuilder padding( - TString padding); - - /** - * Sets the padding of this {@link PaginationBuilder}. - * - * @param padding The padding to set - * @return {@code this} - */ - PaginationBuilder padding( - Builder padding); - - /** - * Sets the maximum number of lines for this {@link PaginationBuilder}. - * - * @param linesPerPge The lines per page to set - * @return {@code this} - * @throws IllegalArgumentException If linesPerPage {@literal <} 1 - */ - PaginationBuilder linesPerPage( - int linesPerPge); - - /** - * Creates a {@link Pagination} from this builder - * - * @return The built {@link Pagination} - */ - Pagination build(); - } - - interface Pagination { - - /** - * @return The contents of this {@link Pagination} - */ - Iterable getContents(); - - /** - * @return The title of this {@link Pagination} - */ - Optional getTitle(); - - /** - * @return The header of this {@link Pagination} - */ - Optional getHeader(); - - /** - * @return The footer of this {@link Pagination} - */ - Optional getFooter(); - - /** - * @return The padding of this {@link Pagination} - */ - TString getPadding(); - - /** - * @return The lines per page of this {@link Pagination} - */ - int getLinesPerPage(); - - /** - * Sends this {@link Pagination} to the provided {@link TCommandSource receiver} - * - * @param receiver The {@link TCommandSource receiver} to send this {@link Pagination} to - */ - void sendTo(TCommandSource receiver); - - /** - * Sends this {@link Pagination} to the console - */ - void sendToConsole(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TimeFormatService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TimeFormatService.java deleted file mode 100644 index a8ce18ce9..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/TimeFormatService.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.util; - -import java.time.Duration; -import java.time.Instant; -import java.time.ZonedDateTime; -import java.time.temporal.TemporalAccessor; -import java.util.Optional; - -/** - * A service that deals with transforming times and durations to and from human-readable formats. - * - *

- * In general, times are interpreted in the following way: - *

- *
    - *
  • {@link String} and {@link ZonedDateTime} - In the end user's time zone (as defined in the config)
  • - *
  • {@link Instant} - In UTC
  • - *
- */ -public interface TimeFormatService { - - long parseSecondsUnsafe(String input); - - Optional parseSeconds(String input); - - Duration parseDurationUnsafe(String input); - - Optional parseDuration(String input); - - Instant parseFutureInstantUnsafe(String input); - - Optional parseFutureInstant(String input); - - Instant parseInstantUnsafe(String input); - - Optional parseInstant(String input); - - /** - * Interprets the provided {@link Instant} as UTC and converts it into the time zone defined in the config. - * - * @param instant The {@link Instant} in UTC to convert - * @return An {@link Instant} converted to the time zone defined in the config - */ - ZonedDateTime fromUTC(Instant instant); - - FormatResult format(Duration duration); - - /** - * Formats the provided {@link TemporalAccessor} and converts it to the time zone defined in the config if it does - * not already have timezone data. - * - * @param temporal The {@link TemporalAccessor} to format - * @return A {@link FormatResult} - */ - FormatResult format(TemporalAccessor temporal); - - FormatResult formatDurationUnsafe(String input); - - Optional formatDuration(String input); - - FormatResult formatInstantUnsafe(String input); - - Optional formatInstant(String input); - - interface FormatResult { - - /** - * Sets the maximum amount of characters in the result. Providing a - * negative value means no maximum. - * - * @param maxCharacters The maximum amount of characters - * @return {@code this} - */ - FormatResult maxCharacters(int maxCharacters); - - /** - * Sets the maximum amount of units in the result. Providing a - * negative value means no maximum. - * - * @param maxUnits The maximum amount of units - * @return {@code this} - */ - FormatResult maxUnits(int maxUnits); - - /** - * Removes the nano second component of the result - * - * @return {@code this} - */ - FormatResult withoutNano(); - - /** - * Builds and returns the string representation of this {@link FormatResult} - * - * @return The string representation of this {@link FormatResult} - */ - @Override - String toString(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/UserService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/UserService.java deleted file mode 100644 index 80f4ac475..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/UserService.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api.util; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -/** - * Service for translating UUIDs to UserNames or UserNames to UUIDs - */ -public interface UserService { - - Optional get(String userName); - - Optional get(UUID userUUID); - - Optional getPlayer(String userName); - - Optional getPlayer(UUID userUUID); - - Optional getPlayer(TUser user); - - /** - * Attempts to find all matching userNames that start with the provided String (case-insensitive). - * - * @return A list of matching player names - */ - List matchPlayerNames(String startsWith); - - /** - * Attempts to find all matching userNames that start with the String at the provided index - * of the provided array when it has the provided length. - * - * @param length The length of {@code context} for which to match the String at {@code index} - * @return A list of matching player names - */ - List matchPlayerNames(String[] context, int index, int length); - - Collection getOnlinePlayers(); - - CompletableFuture> getUUID(String userName); - - CompletableFuture> getUserName(UUID userUUID); - - UUID getUUID(TUser user); - - /** - * If the provided object has a {@link UUID}, return it. Otherwise return a constant UUID that is - * the same for all objects without a UUID. - */ - UUID getUUIDSafe(Object object); - - String getUserName(TUser user); -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCacheService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCacheService.java deleted file mode 100644 index 8e263442b..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCacheService.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import org.anvilpowered.anvil.api.datastore.CacheService; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -@Deprecated // will probably break in 0.4 -public abstract class BaseCacheService< - TKey, - T extends ObjectWithId, - TDataStore> - extends BaseRepository - implements CacheService { - - protected Registry registry; - - protected ConcurrentMap cache; - - private Integer timeoutSeconds; - - protected BaseCacheService(Registry registry) { - this.registry = registry; - registry.whenLoaded(this::registryLoaded).register(); - cache = new ConcurrentHashMap<>(); - } - - private void registryLoaded() { - stopCacheInvalidationTask(); - Integer intervalSeconds = registry.getOrDefault(Keys.CACHE_INVALIDATION_INTERVAL_SECONDS); - timeoutSeconds = registry.getOrDefault(Keys.CACHE_INVALIDATION_TIMOUT_SECONDS); - startCacheInvalidationTask(intervalSeconds); - } - - @Override - public Runnable getCacheInvalidationTask() { - return () -> { - List toRemove = new ArrayList<>(); - for (T t : getAllAsSet()) { - if (System.currentTimeMillis() - cache.get(t) > timeoutSeconds * 1000L) { - toRemove.add(t); - } - } - toRemove.forEach(this::delete); - }; - } - - @Override - public Set getAllAsSet() { - return cache.keySet(); - } - - @Override - public CompletableFuture> insertOne(T t) { - return CompletableFuture.supplyAsync(() -> { - if (t == null) return Optional.empty(); - cache.put(t, System.currentTimeMillis()); - return Optional.of(t); - }); - } - - @Override - public CompletableFuture> insert(List list) { - return CompletableFuture.supplyAsync(() -> list.stream().map(t -> insertOne(t).join().orElse(null)).filter(Objects::nonNull).collect(Collectors.toList())); - } - - @Override - public CompletableFuture> getOne(TKey id) { - return CompletableFuture.supplyAsync(() -> getOne(dbo -> dbo.getId().equals(id))); - } - - @Override - public CompletableFuture deleteOne(TKey id) { - return CompletableFuture.supplyAsync(() -> deleteOne(dbo -> dbo.getId().equals(id)).isPresent()); - } - - @Override - public CompletableFuture> getAllIds() { - return CompletableFuture.supplyAsync(() -> cache.keySet().stream().map(ObjectWithId::getId).collect(Collectors.toList())); - } - - @Override - public Optional deleteOne(Predicate predicate) { - return getOne(predicate).flatMap(this::delete); - } - - @Override - public Optional delete(T t) { - return cache.remove(t) == null ? Optional.empty() : Optional.of(t); - } - - @Override - public List delete(Predicate predicate) { - return cache.keySet().stream().filter(predicate).filter(t -> cache.remove(t) != null).collect(Collectors.toList()); - } - - @Override - public List getAll(Predicate predicate) { - return getAllAsSet().stream().filter(predicate).collect(Collectors.toList()); - } - - @Override - public Optional getOne(Predicate predicate) { - return getAll(predicate).stream().findAny(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCachedRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCachedRepository.java deleted file mode 100644 index 7890019af..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseCachedRepository.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import org.anvilpowered.anvil.api.datastore.CacheService; -import org.anvilpowered.anvil.api.datastore.CachedRepository; -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; - -@Deprecated // will probably break in 0.4 -public abstract class BaseCachedRepository< - TKey, - T extends ObjectWithId, - C extends CacheService, - TDataStore> - extends BaseRepository - implements CachedRepository { - - @Override - public CompletableFuture applyFromDBToCache(Supplier fromDB, BiConsumer toCache) { - return CompletableFuture.supplyAsync(fromDB).thenApplyAsync(k -> { - getRepositoryCacheService().ifPresent(c -> toCache.accept(c, k)); - return k; - }); - } - - @Override - public CompletableFuture> applyFromDBToCacheConditionally(Supplier> fromDB, BiConsumer toCache) { - return CompletableFuture.supplyAsync(fromDB).thenApplyAsync(optionalK -> { - optionalK.ifPresent(k -> getRepositoryCacheService().ifPresent(c -> toCache.accept(c, k))); - return optionalK; - }); - } - - @Override - public CompletableFuture applyFromDBThroughCache(Supplier fromDB, BiFunction cacheTransformer) { - return CompletableFuture.supplyAsync(fromDB).thenApplyAsync(k -> getRepositoryCacheService().map(c -> cacheTransformer.apply(c, k)).orElse(k)); - } - - @Override - public CompletableFuture> applyFromDBThroughCacheConditionally(Supplier> fromDB, BiFunction> cacheTransformer) { - return CompletableFuture.supplyAsync(fromDB).thenApplyAsync(optionalK -> optionalK.flatMap(k -> getRepositoryCacheService().flatMap(c -> cacheTransformer.apply(c, k)))); - } - - @Override - public CompletableFuture applyThroughBoth(Function cacheTransformer, Function, K> dbTransformer) { - return CompletableFuture.supplyAsync(() -> dbTransformer.apply(getRepositoryCacheService().map(cacheTransformer))); - } - - @Override - public CompletableFuture> applyThroughBothConditionally(Function> cacheTransformer, Function dbTransformer) { - return CompletableFuture.supplyAsync(() -> getRepositoryCacheService().flatMap(cacheTransformer).map(dbTransformer)); - } - - @Override - public CompletableFuture> applyToBothConditionally(Function> cacheTransformer, Supplier> dbSupplier) { - return CompletableFuture.supplyAsync(() -> { - Optional optionalK = getRepositoryCacheService().flatMap(cacheTransformer); - if (!optionalK.isPresent()) { - return dbSupplier.get(); - } - return optionalK; - }); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseComponent.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseComponent.java deleted file mode 100644 index 5679c29fb..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseComponent.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.datastore.Component; -import org.anvilpowered.anvil.api.datastore.DataStoreContext; - -import java.util.Optional; - -public abstract class BaseComponent< - TKey, - TDataStore> - implements Component { - - @Inject - private DataStoreContext dataStoreContext; - - @Override - public DataStoreContext getDataStoreContext() { - return dataStoreContext; - } - - @Override - public Class getTKeyClass() { - return dataStoreContext.getTKeyClass(); - } - - @Override - public Optional parse(Object object) { - try { - return Optional.of(parseUnsafe(object)); - } catch (IllegalArgumentException | UnsupportedOperationException e) { - return Optional.empty(); - } - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseManager.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseManager.java deleted file mode 100644 index 03902d887..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseManager.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import com.google.common.base.Preconditions; -import com.google.common.reflect.TypeToken; -import com.google.inject.Binding; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.name.Named; -import com.google.inject.name.Names; -import org.anvilpowered.anvil.api.datastore.Component; -import org.anvilpowered.anvil.api.datastore.Manager; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.registry.RegistryScoped; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; - -import java.util.Locale; -import java.util.Map; - -@SuppressWarnings({"UnstableApiUsage", "unchecked"}) -public abstract class BaseManager> implements Manager { - - protected Registry registry; - - private final TypeToken componentType; - - protected BaseManager(Registry registry) { - this.registry = registry; - registry.whenLoaded(this::registryLoaded).register(); - componentType = new TypeToken(getClass()) { - }; - } - - @Inject - private Injector injector; - - @Inject - private Logger logger; - - @Nullable - @RegistryScoped - private C currentComponent; - - private void registryLoaded() { - currentComponent = null; - } - - private void loadComponent() { - String dataStoreName = registry.getExtraSafe(Keys.DATA_STORE_NAME) - .toLowerCase(Locale.ENGLISH); - String type = componentType.getRawType().getCanonicalName(); - Named named = Names.named(dataStoreName); - for (Map.Entry, Binding> entry : injector.getBindings().entrySet()) { - Key k = entry.getKey(); - if (k.getTypeLiteral().getType().getTypeName().contains(type) - && named.equals(k.getAnnotation())) { - currentComponent = (C) entry.getValue().getProvider().get(); - return; - } - } - String message = "Anvil: Could not find requested data store: \"" + dataStoreName - + "\". Did you bind it correctly?"; - logger.error(message, new IllegalStateException(message)); - } - - @Override - @RegistryScoped - public C getPrimaryComponent() { - try { - if (currentComponent == null) { - loadComponent(); - } - return Preconditions.checkNotNull(currentComponent, - "An error occurred while loading current component"); - } catch (RuntimeException e) { - String message = "Anvil: DataStoreName has not been loaded yet!" + - "Make sure your Registry and ConfigurationService implementations" + - "are annotated with @Singleton!"; - logger.error(message); - throw new IllegalStateException(message, e); - } - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoCachedRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoCachedRepository.java deleted file mode 100644 index 799096501..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoCachedRepository.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import dev.morphia.Datastore; -import org.anvilpowered.anvil.api.datastore.CacheService; -import org.anvilpowered.anvil.api.datastore.CachedRepository; -import org.anvilpowered.anvil.api.datastore.Repository; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.bson.types.ObjectId; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -@Deprecated // will probably break in 0.4 -public interface BaseMongoCachedRepository< - T extends ObjectWithId, - C extends CacheService> - extends BaseMongoRepository, CachedRepository { - - @Override - default CompletableFuture> insertOne(T item) { - return applyFromDBToCacheConditionally(() -> BaseMongoRepository.super.insertOne(item).join(), Repository::insertOne); - } - - @Override - default CompletableFuture> insert(List list) { - return applyFromDBToCache(() -> BaseMongoRepository.super.insert(list).join(), Repository::insert); - } - - @Override - default CompletableFuture> getOne(ObjectId id) { - return applyToBothConditionally(c -> c.getOne(id).join(), () -> BaseMongoRepository.super.getOne(id).join()); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoComponent.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoComponent.java deleted file mode 100644 index f1b2aa217..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoComponent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import dev.morphia.Datastore; -import org.anvilpowered.anvil.api.datastore.Component; -import org.bson.types.ObjectId; - -import java.util.Optional; - -public interface BaseMongoComponent extends Component { - - @Override - default ObjectId parseUnsafe(Object object) { - if (object instanceof ObjectId) { - return (ObjectId) object; - } else if (object instanceof Optional) { - Optional optional = (Optional) object; - if (optional.isPresent()) return parseUnsafe(optional.get()); - throw new IllegalArgumentException("Error while parsing " + object + ". Optional not present"); - } - String string = object.toString(); - if (ObjectId.isValid(string)) return new ObjectId(string); - throw new IllegalArgumentException("Error while parsing " + object + ". Not a valid ObjectId"); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoRepository.java deleted file mode 100644 index 494f02357..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseMongoRepository.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import com.google.common.collect.ImmutableList; -import dev.morphia.query.Query; -import dev.morphia.query.UpdateOperations; -import kotlin.collections.CollectionsKt; -import kotlin.sequences.SequencesKt; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.datastore.MongoRepository; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.anvilpowered.anvil.api.util.TimeFormatService; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -public interface BaseMongoRepository< - T extends ObjectWithId> - extends MongoRepository, BaseMongoComponent { - - @Override - default CompletableFuture> getCreatedUtc(ObjectId id) { - return CompletableFuture.completedFuture( - Optional.of(Instant.ofEpochSecond(id.getTimestamp()))); - } - - @Override - default CompletableFuture> insertOne(T item) { - return CompletableFuture.supplyAsync(() -> { - try { - getDataStoreContext().getDataStore().save(item); - } catch (RuntimeException e) { - e.printStackTrace(); - return Optional.empty(); - } - return Optional.of(item); - }); - } - - @Override - default CompletableFuture> insert(List list) { - return CompletableFuture.supplyAsync(() -> - list.stream().filter(item -> { - try { - getDataStoreContext().getDataStore().save(item); - } catch (RuntimeException e) { - e.printStackTrace(); - return false; - } - return true; - }).collect(Collectors.toList()) - ); - } - - @Override - default CompletableFuture> getOne(Query query) { - return CompletableFuture.supplyAsync(() -> Optional.ofNullable(query.first())); - } - - @Override - default CompletableFuture> getOne(ObjectId id) { - return getOne(asQuery(id)); - } - - @Override - default CompletableFuture> getOne(Instant createdUtc) { - return getOne(asQuery(createdUtc)); - } - - @Override - default CompletableFuture> getAllIds() { - return CompletableFuture.supplyAsync(() -> - ImmutableList.copyOf( - SequencesKt.map(CollectionsKt.asSequence(asQuery().project("_id", true)), - ObjectWithId::getId).iterator()) - ); - } - - @Override - default CompletableFuture delete(Query query) { - return CompletableFuture.supplyAsync(() -> { - try { - return getDataStoreContext().getDataStore().delete(query).getN() > 0; - } catch (RuntimeException e) { - e.printStackTrace(); - return false; - } - }); - } - - @Override - default CompletableFuture deleteOne(ObjectId id) { - return delete(asQuery(id)); - } - - @Override - default CompletableFuture deleteOne(Instant createdUtc) { - return delete(asQuery(createdUtc)); - } - - @Override - default UpdateOperations createUpdateOperations() { - return getDataStoreContext().getDataStore().createUpdateOperations(getTClass()); - } - - @Override - default UpdateOperations inc(String field, Number value) { - return createUpdateOperations().inc(field, value); - } - - @Override - default UpdateOperations inc(String field) { - return inc(field, 1); - } - - @Override - default UpdateOperations set(String field, Object value) { - return createUpdateOperations().set(field, value); - } - - @Override - default UpdateOperations unSet(String field) { - return createUpdateOperations().unset(field); - } - - @Override - default CompletableFuture update(Query query, - UpdateOperations updateOperations) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore() - .update(query, updateOperations).getUpdatedCount() > 0); - } - - @Override - default CompletableFuture update(Optional> optionalQuery, - UpdateOperations updateOperations) { - return optionalQuery.map(q -> update(q, updateOperations)) - .orElse(CompletableFuture.completedFuture(false)); - } - - @Override - default CompletableFuture> getAll() { - return getAll(asQuery()); - } - - @Override - default CompletableFuture> getAll(Query query) { - return CompletableFuture.supplyAsync(query::asList); - } - - @Override - default Query asQuery() { - return getDataStoreContext().getDataStore().createQuery(getTClass()); - } - - @Override - default Query asQuery(ObjectId id) { - return asQuery().field("_id").equal(id); - } - - @Override - default Query asQuery(Instant createdUtc) { - String time = Integer.toHexString((int) createdUtc.getEpochSecond()); - return asQuery() - .field("_id").greaterThan(new ObjectId(time + "0000000000000000")) - .field("_id").lessThan(new ObjectId(time + "ffffffffffffffff")); - } - - @Override - default Optional> asQueryForIdOrTime(String idOrTime) { - return parse(idOrTime).map(id -> Optional.of(asQuery(id))) - .orElseGet(() -> Anvil.getEnvironmentManager().getCoreEnvironment() - .getInjector().getInstance(TimeFormatService.class).parseInstant(idOrTime) - .map(this::asQuery)); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseRepository.java deleted file mode 100644 index d079814fa..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseRepository.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.datastore.Repository; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.anvilpowered.anvil.api.util.TimeFormatService; -import org.slf4j.Logger; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -public abstract class BaseRepository< - TKey, - T extends ObjectWithId, - TDataStore> - extends BaseComponent - implements Repository { - - @Inject - private Logger logger; - - @Override - public T generateEmpty() { - Class tClass = getTClass(); - try { - return tClass.getConstructor().newInstance(); - } catch (Exception e) { - String message = "There was an error creating an instance of " + tClass.getName() + "! Make sure it has an accessible no-args constructor!"; - logger.error(message); - throw new IllegalStateException(message, e); - } - } - - @Override - public CompletableFuture> parseAndGetOne(Object idOrTime) { - return parse(idOrTime).map(this::getOne).orElseGet(() -> - Anvil.getEnvironmentManager().getCoreEnvironment().getInjector() - .getInstance(TimeFormatService.class).parseInstant(idOrTime.toString()) - .map(this::getOne).orElse(CompletableFuture.completedFuture(Optional.empty()))); - } - - @Override - public CompletableFuture parseAndDeleteOne(Object idOrTime) { - return parse(idOrTime).map(this::deleteOne).orElseGet(() -> - Anvil.getEnvironmentManager().getCoreEnvironment().getInjector() - .getInstance(TimeFormatService.class).parseInstant(idOrTime.toString()) - .map(this::deleteOne).orElse(CompletableFuture.completedFuture(false))); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusCachedRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusCachedRepository.java deleted file mode 100644 index 3558b496f..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusCachedRepository.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import jetbrains.exodus.entitystore.StoreTransaction; -import org.anvilpowered.anvil.api.datastore.CacheService; -import org.anvilpowered.anvil.api.datastore.CachedRepository; -import org.anvilpowered.anvil.api.datastore.Repository; -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -@Deprecated // will probably break in 0.4 -public interface BaseXodusCachedRepository< - T extends ObjectWithId, - C extends CacheService> - extends BaseXodusRepository, CachedRepository { - - @Override - default CompletableFuture> insertOne(T item) { - return applyFromDBToCacheConditionally(() -> BaseXodusRepository.super.insertOne(item).join(), Repository::insertOne); - } - - @Override - default CompletableFuture> insert(List list) { - return applyFromDBToCache(() -> BaseXodusRepository.super.insert(list).join(), Repository::insert); - } - - @Override - default CompletableFuture> getOne(EntityId id) { - return applyToBothConditionally(c -> c.getOne(id).join(), () -> BaseXodusRepository.super.getOne(id).join()); - } - - @Override - default CompletableFuture delete(Function> query) { - return applyFromDBToCache(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - List toDelete = new ArrayList<>(); - query.apply(txn).forEach(entity -> { - toDelete.add(entity.getId()); - entity.delete(); - }); - return txn.commit() ? toDelete : Collections.emptyList(); - }), (c, toDelete) -> toDelete.forEach(id -> c.deleteOne(id).join())) - .thenApplyAsync(result -> !result.isEmpty()); - } - - @Override - default CompletableFuture deleteOne(EntityId id) { - return applyFromDBToCache(() -> BaseXodusRepository.super.deleteOne(id).join(), (c, b) -> { - if (b) { - c.deleteOne(id).join(); - } - }); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusComponent.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusComponent.java deleted file mode 100644 index a063a6d78..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusComponent.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import org.anvilpowered.anvil.api.datastore.Component; - -import java.util.Optional; - -public interface BaseXodusComponent extends Component { - - @Override - default EntityId parseUnsafe(Object object) { - if (object instanceof EntityId) { - return (EntityId) object; - } else if (object instanceof Optional) { - Optional optional = (Optional) object; - if (optional.isPresent()) return parseUnsafe(optional.get()); - throw new IllegalArgumentException("Error while parsing " + object + ". Optional not present"); - } - String string = object.toString(); - String[] stringParts = string.split("-"); - if (stringParts.length != 2) { - throw new IllegalArgumentException("Not a valid EntityId. Must follow format (int)-(long)"); - } - return new PersistentEntityId(Integer.parseInt(stringParts[0]), Long.parseLong(stringParts[1])); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusRepository.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusRepository.java deleted file mode 100644 index 31ad01e43..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/datastore/BaseXodusRepository.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.datastore; - -import com.google.common.collect.ImmutableList; -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.EntityIterable; -import jetbrains.exodus.entitystore.EntityIterator; -import jetbrains.exodus.entitystore.EntityRemovedInDatabaseException; -import jetbrains.exodus.entitystore.StoreTransaction; -import kotlin.collections.CollectionsKt; -import kotlin.sequences.SequencesKt; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.datastore.XodusRepository; -import org.anvilpowered.anvil.api.model.Mappable; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.anvilpowered.anvil.api.util.TimeFormatService; - -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.Function; - -public interface BaseXodusRepository< - T extends ObjectWithId> - extends XodusRepository, BaseXodusComponent { - - @Override - default CompletableFuture> insertOne(T item) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - final Entity entity = txn.newEntity(getTClass().getSimpleName()); - ((Mappable) item).writeTo(entity); - item.setId(entity.getId()); - return txn.commit() ? Optional.of(item) : Optional.empty(); - }) - ); - } - - @Override - default CompletableFuture> insert(List list) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - list.forEach(item -> { - final Entity entity = txn.newEntity(getTClass().getSimpleName()); - ((Mappable) item).writeTo(entity); - item.setId(entity.getId()); - }); - txn.commit(); - return list; - }) - ); - } - - @Override - default Iterator iterator(Function> query) { - return getDataStoreContext().getDataStore().computeInReadonlyTransaction(txn -> - SequencesKt.map(CollectionsKt.asSequence(query.apply(txn)), entity -> { - T item = generateEmpty(); - ((Mappable) item).readFrom(entity); - return item; - }).iterator() - ); - } - - default Iterator iterator() { - return iterator(txn -> txn.getAll(getTClass().getSimpleName())); - } - - @Override - default CompletableFuture> getAll(Function> query) { - return CompletableFuture.supplyAsync(() -> ImmutableList.copyOf(iterator(query))); - } - - @Override - default CompletableFuture> getAll() { - return CompletableFuture.supplyAsync(() -> ImmutableList.copyOf(iterator())); - } - - @Override - default CompletableFuture> getOne( - Function> query) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInReadonlyTransaction(txn -> { - Iterator iterator = query.apply(txn).iterator(); - if (iterator.hasNext()) { - T item = generateEmpty(); - ((Mappable) item).readFrom(iterator.next()); - return Optional.of(item); - } else { - return Optional.empty(); - } - }) - ); - } - - @Override - default CompletableFuture> getOne(EntityId id) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInReadonlyTransaction(txn -> { - Entity entity; - try { - entity = txn.getEntity(id); - } catch (EntityRemovedInDatabaseException ignored) { - return Optional.empty(); - } - T item = generateEmpty(); - ((Mappable) item).readFrom(entity); - return Optional.of(item); - }) - ); - } - - @Override - default CompletableFuture> getOne(Instant createdUtc) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInReadonlyTransaction(txn -> { - Entity entity; - try { - Iterator it = asQuery(createdUtc).apply(txn).iterator(); - if (!it.hasNext()) { - return Optional.empty(); - } - entity = it.next(); - } catch (EntityRemovedInDatabaseException ignored) { - return Optional.empty(); - } - T item = generateEmpty(); - ((Mappable) item).readFrom(entity); - return Optional.of(item); - }) - ); - } - - @Override - default CompletableFuture> getAllIds() { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInReadonlyTransaction(txn -> { - final EntityIterable iterable = txn.getAll(getTClass().getSimpleName()); - final EntityIterator iterator = iterable.iterator(); - final long roughCount = iterable.getRoughCount(); - final int buffer = 50; - int listSize = roughCount > Integer.MAX_VALUE - buffer - ? Integer.MAX_VALUE - buffer // woah - : (int) (roughCount + buffer); - final List list = new ArrayList<>(listSize); - while (iterator.hasNext()) { - list.add(iterator.nextId()); - } - if (iterator.shouldBeDisposed()) { - iterator.dispose(); - } - return list; - }) - ); - } - - @Override - default CompletableFuture delete( - Function> query) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - boolean success = false; - for (Entity entity : query.apply(txn)) { - if (entity.delete()) { - success = true; - } - } - return txn.commit() && success; - }) - ); - } - - @Override - default CompletableFuture deleteOne(EntityId id) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> - txn.getEntity(id).delete() && txn.commit()) - ); - } - - @Override - default CompletableFuture deleteOne(Instant createdUtc) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - Iterator it = asQuery(createdUtc).apply(txn).iterator(); - return it.hasNext() && it.next().delete() && txn.commit(); - }) - ); - } - - @Override - default CompletableFuture update( - Function> query, - Consumer update) { - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - query.apply(txn).forEach(e -> { - update.accept(e); - Instant now = OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - e.setProperty("updatedUtcSeconds", now.getEpochSecond()); - e.setProperty("updatedUtcNanos", now.getNano()); - }); - return txn.commit(); - }) - ); - } - - @Override - default CompletableFuture update( - Optional>> optionalQuery, - Consumer update) { - return optionalQuery.map(q -> update(q, update)) - .orElse(CompletableFuture.completedFuture(false)); - } - - @Override - default Function> asQuery( - EntityId id) { - return txn -> Collections.singletonList(txn.getEntity(id)); - } - - @Override - default Function> asQuery( - Instant createdUtc) { - return txn -> txn.find(getTClass().getSimpleName(), - "createdUtcSeconds", createdUtc.getEpochSecond()) - .union(txn.find(getTClass().getSimpleName(), - "createdUtcNanos", createdUtc.getNano())); - } - - @Override - default Optional>> - asQueryForIdOrTime(String idOrTime) { - return parse(idOrTime).>>> - map(entityId -> Optional.of(asQuery(entityId))) - .orElseGet(() -> Anvil.getEnvironmentManager().getCoreEnvironment() - .getInjector().getInstance(TimeFormatService.class).parseInstant(idOrTime) - .map(Instant::getEpochSecond) - .map(s -> txn -> txn.find(getTClass().getSimpleName(), "createdUtcSeconds", s))); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/MongoDbo.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/MongoDbo.java deleted file mode 100644 index b82d42abc..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/MongoDbo.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.model; - -import dev.morphia.annotations.Id; -import dev.morphia.annotations.PrePersist; -import org.anvilpowered.anvil.api.model.ObjectWithId; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; - -public abstract class MongoDbo implements ObjectWithId { - - @Id - private ObjectId id; - - private Instant updatedUtc; - - @Override - public ObjectId getId() { - return id; - } - - @Override - public void setId(ObjectId id) { - this.id = id; - } - - @Override - public String getIdAsString() { - return id.toHexString(); - } - - @Override - public Instant getCreatedUtc() { - return Instant.ofEpochSecond(id.getTimestamp()); - } - - @Override - public Instant getUpdatedUtc() { - return updatedUtc; - } - - @PrePersist - private void prePersist() { - updatedUtc = OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - } -} - diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/XodusDbo.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/XodusDbo.java deleted file mode 100644 index 26845cb70..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/model/XodusDbo.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.model; - -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import org.anvilpowered.anvil.api.model.Mappable; -import org.anvilpowered.anvil.api.model.ObjectWithId; - -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; - -public abstract class XodusDbo implements ObjectWithId, Mappable { - - private EntityId id; - - private long createdUtcSeconds; - private int createdUtcNanos; - private long updatedUtcSeconds; - private int updatedUtcNanos; - - protected XodusDbo() { - Instant now = OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - createdUtcSeconds = now.getEpochSecond(); - createdUtcNanos = now.getNano(); - prePersist(); - } - - @Override - public EntityId getId() { - return id; - } - - @Override - public void setId(EntityId id) { - this.id = id; - } - - @Override - public String getIdAsString() { - return id.toString(); - } - - @Override - public Instant getCreatedUtc() { - return Instant.ofEpochSecond(createdUtcSeconds, createdUtcNanos); - } - - @Override - public Instant getUpdatedUtc() { - return Instant.ofEpochSecond(updatedUtcSeconds, updatedUtcNanos); - } - - protected void prePersist() { - Instant now = OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - updatedUtcSeconds = now.getEpochSecond(); - updatedUtcNanos = now.getNano(); - } - - @Override - public Entity writeTo(Entity object) { - // id cannot be written to object - object.setProperty("createdUtcSeconds", createdUtcSeconds); - object.setProperty("createdUtcNanos", createdUtcNanos); - object.setProperty("updatedUtcSeconds", updatedUtcSeconds); - object.setProperty("updatedUtcNanos", updatedUtcNanos); - return object; - } - - @Override - public void readFrom(Entity object) { - id = object.getId(); - Comparable createdUtcSeconds = object.getProperty("createdUtcSeconds"); - if (createdUtcSeconds instanceof Long) { - this.createdUtcSeconds = (Long) createdUtcSeconds; - } - Comparable createdUtcNanos = object.getProperty("createdUtcNanos"); - if (createdUtcNanos instanceof Integer) { - this.createdUtcNanos = (Integer) createdUtcNanos; - } - Comparable updatedUtcSeconds = object.getProperty("updatedUtcSeconds"); - if (updatedUtcSeconds instanceof Long) { - this.updatedUtcSeconds = (Long) updatedUtcSeconds; - } - Comparable updatedUtcNanos = object.getProperty("updatedUtcNanos"); - if (updatedUtcNanos instanceof Integer) { - this.updatedUtcNanos = (Integer) updatedUtcNanos; - } - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/plugin/BasePlugin.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/plugin/BasePlugin.java deleted file mode 100644 index dffec8f3f..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/plugin/BasePlugin.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.plugin; - -import com.google.common.base.MoreObjects; -import com.google.common.reflect.TypeToken; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Module; -import com.google.inject.TypeLiteral; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.Environment; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.checkerframework.checker.nullness.qual.Nullable; - -/** - * A helper class for quickly creating an environment. While not strictly necessary, it can - * simplify the start up process in most cases. - */ -@SuppressWarnings("UnstableApiUsage") -public abstract class BasePlugin { - - protected Environment environment; - - protected BasePlugin( - String name, - @Nullable Injector rootInjector, - @Nullable Module module, - Key... earlyServices - ) { - createDefaultBuilder(name, rootInjector, module) - .addEarlyServices(earlyServices) - .register(this); - } - - protected BasePlugin( - String name, - @Nullable Injector rootInjector, - @Nullable Module module, - Class... earlyServices - ) { - createDefaultBuilder(name, rootInjector, module) - .addEarlyServices(earlyServices) - .register(this); - } - - protected BasePlugin( - String name, - @Nullable Injector rootInjector, - @Nullable Module module, - TypeLiteral... earlyServices - ) { - createDefaultBuilder(name, rootInjector, module) - .addEarlyServices(earlyServices) - .register(this); - } - - protected BasePlugin( - String name, - @Nullable Injector rootInjector, - @Nullable Module module, - TypeToken... earlyServices - ) { - createDefaultBuilder(name, rootInjector, module) - .addEarlyServices(earlyServices) - .register(this); - } - - protected BasePlugin( - String name, - @Nullable Injector rootInjector, - @Nullable Module module - ) { - createDefaultBuilder(name, rootInjector, module) - .register(this); - } - - protected Environment.Builder createDefaultBuilder( - String name, - @Nullable Injector rootInjector, - @Nullable Module module - ) { - Environment.Builder builder = Anvil.getEnvironmentBuilder() - .setName(name) - .setRootInjector(rootInjector) - .whenLoaded(this::whenLoaded) - .whenReady(e -> environment = e) - .whenReady(this::whenReady) - .whenReloaded(this::whenReloaded); - if (module != null) { - builder.addModules(module); - } - applyToBuilder(builder); - return builder; - } - - protected void applyToBuilder(Environment.Builder builder) { - } - - private void sendLoaded(String status) { - PluginInfo pluginInfo = environment.getPluginInfo(); - environment.getTextService().builder() - .append(pluginInfo.getPrefix()) - .green().append(pluginInfo.getVersion()) - .aqua().append(" by ") - .appendJoining(", ", pluginInfo.getAuthors()) - .append(" - ", status, "!") - .sendToConsole(); - } - - protected void whenLoaded(Environment environment) { - } - - protected void whenReady(Environment environment) { - sendLoaded("Loaded"); - } - - protected void whenReloaded(Environment environment) { - sendLoaded("Reloaded"); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("name", environment == null ? "null" : environment.getName()) - .toString(); - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseConfigurationService.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseConfigurationService.java deleted file mode 100644 index 8697ac439..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseConfigurationService.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.registry; - -import com.google.common.reflect.Invokable; -import com.google.common.reflect.TypeToken; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import ninja.leaping.configurate.ConfigurationOptions; -import ninja.leaping.configurate.commented.CommentedConfigurationNode; -import ninja.leaping.configurate.loader.ConfigurationLoader; -import ninja.leaping.configurate.objectmapping.ObjectMappingException; -import org.anvilpowered.anvil.api.registry.ConfigurationService; -import org.anvilpowered.anvil.api.registry.Key; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.RegistryScope; -import org.anvilpowered.anvil.api.registry.RegistryScoped; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * Service to load and save data from a config file - * - * @author Cableguy20 - */ -@Singleton -@SuppressWarnings({"unchecked", "UnstableApiUsage"}) -public class BaseConfigurationService extends BaseRegistry implements ConfigurationService { - - protected ConfigurationLoader configLoader; - private CommentedConfigurationNode rootConfigurationNode; - - /** - * Maps Keys to their verification function - */ - private final Map, Map, Function>> verificationMap; - - /** - * Maps ConfigKeys to configuration node names - */ - private final Map, String> nodeNameMap; - - /** - * Maps ConfigKeys to configuration node descriptions - */ - private final Map, String> nodeDescriptionMap; - - private boolean configValuesEdited; - private boolean isWithDataStore = false; - @Nullable - private ConfigurationOptions options; - - @Inject - public BaseConfigurationService(ConfigurationLoader configLoader) { - this.configLoader = configLoader; - verificationMap = new HashMap<>(); - nodeNameMap = new HashMap<>(); - nodeDescriptionMap = new HashMap<>(); - } - - protected void setOptions(@Nullable ConfigurationOptions options) { - this.options = options; - } - - protected void withCore() { - setName(Keys.SERVER_NAME, "server.name"); - setDescription(Keys.SERVER_NAME, "\nServer name"); - } - - private void withDataStoreCore0() { - setName(Keys.DATA_DIRECTORY, "datastore.dataDirectory"); - setName(Keys.DATA_STORE_NAME, "datastore.dataStoreName"); - setDescription(Keys.DATA_DIRECTORY, "\nDirectory for extra data" + - "\nPlease note that it is not recommended to change this value from the original"); - setDescription(Keys.DATA_STORE_NAME, "\nDetermines which storage option to use"); - } - - protected void withDataStoreCore() { - if (isWithDataStore) return; - isWithDataStore = true; - withDataStoreCore0(); - } - - protected void withDataStore() { - if (isWithDataStore) return; - isWithDataStore = true; - withDataStoreCore0(); - setName(Keys.USE_SHARED_CREDENTIALS, "datastore.anvil.useSharedCredentials"); - setName(Keys.USE_SHARED_ENVIRONMENT, "datastore.anvil.useSharedEnvironment"); - setDescription(Keys.USE_SHARED_CREDENTIALS, "\nWhether to use Anvil's shared credentials." - + "\nIf enabled, the following datastore settings will be inherited from Anvil's config (Requires useSharedEnvironment)" - + "\n\t- mongodb.authDb" - + "\n\t- mongodb.connectionString" - + "\n\t- mongodb.password" - + "\n\t- mongodb.username" - + "\n\t- mongodb.useAuth" - + "\n\t- mongodb.useConnectionString" - + "\n\t- mongodb.useSrv" - + "\nPlease note: If this is enabled, the values for above settings in this config file have no effect" - ); - setDescription(Keys.USE_SHARED_ENVIRONMENT, "\nWhether to use Anvil's shared environment." - + "\nIf enabled, the following datastore settings will be inherited from Anvil's config" - + "\n\t- mongodb.hostname" - + "\n\t- mongodb.port" - + "\nPlease note: If this is enabled, the values for above settings in this config file have no effect" - ); - } - - protected void withMongoDB() { - withDataStore(); - setName(Keys.MONGODB_CONNECTION_STRING, "datastore.mongodb.connectionString"); - setName(Keys.MONGODB_HOSTNAME, "datastore.mongodb.hostname"); - setName(Keys.MONGODB_PORT, "datastore.mongodb.port"); - setName(Keys.MONGODB_DBNAME, "datastore.mongodb.dbname"); - setName(Keys.MONGODB_USERNAME, "datastore.mongodb.username"); - setName(Keys.MONGODB_PASSWORD, "datastore.mongodb.password"); - setName(Keys.MONGODB_AUTH_DB, "datastore.mongodb.authDb"); - setName(Keys.MONGODB_USE_AUTH, "datastore.mongodb.useAuth"); - setName(Keys.MONGODB_USE_SRV, "datastore.mongodb.useSrv"); - setName(Keys.MONGODB_USE_CONNECTION_STRING, "datastore.mongodb.useConnectionString"); - setDescription(Keys.MONGODB_CONNECTION_STRING, "\n(Advanced) You will probably not need to use this." + - "\nCustom MongoDB connection string that will used instead of the connection info and credentials below" + - "\nWill only be used if useConnectionString=true"); - setDescription(Keys.MONGODB_HOSTNAME, "\nMongoDB hostname"); - setDescription(Keys.MONGODB_PORT, "\nMongoDB port"); - setDescription(Keys.MONGODB_DBNAME, "\nMongoDB database name"); - setDescription(Keys.MONGODB_USERNAME, "\nMongoDB username"); - setDescription(Keys.MONGODB_PASSWORD, "\nMongoDB password"); - setDescription(Keys.MONGODB_AUTH_DB, "\nMongoDB database to use for authentication"); - setDescription(Keys.MONGODB_USE_AUTH, "\nWhether to use authentication (username/password) for MongoDB connection"); - setDescription(Keys.MONGODB_USE_SRV, "\nWhether to interpret the MongoDB hostname as an SRV record"); - setDescription(Keys.MONGODB_USE_CONNECTION_STRING, "\n(Advanced) You will probably not need to use this." + - "\nWhether to use the connection string provided instead of the normal connection info and credentials" + - "\nOnly use this if you know what you are doing!" + - "\nPlease note that this plugin will inherit both useConnectionString and connectionString from" + - "\nAnvil if and only if useSharedEnvironment and useSharedCredentials are both true"); - } - - protected void withProxyMode() { - setName(Keys.PROXY_MODE, "server.proxyMode"); - setDescription(Keys.PROXY_MODE, "\nEnable this if your server is running behind a proxy" - + "\nIf true, this setting disables the join and chat listeners" - + "\nto prevent conflicts with the proxy's listeners."); - } - - protected void withDefault() { - withCore(); - withMongoDB(); - } - - protected void withAll() { - withDefault(); - withProxyMode(); - } - - protected void setVerification(Key key, - Map, Function> verification) { - verificationMap.put(key, - (Map, Function>) (Object) verification); - } - - protected void setName(Key key, String name) { - nodeNameMap.put(key, name); - } - - protected void setDescription(Key key, String description) { - nodeDescriptionMap.put(key, description); - } - - @Override - public void set(Key key, T value) { - super.set(key, value); - configValuesEdited = true; - } - - @Override - public void remove(Key key) { - super.remove(key); - configValuesEdited = true; - } - - @Override - public void transform(Key key, BiFunction, ? super T, ? extends T> transformer) { - super.transform(key, transformer); - configValuesEdited = true; - } - - @Override - public void transform(Key key, Function transformer) { - super.transform(key, transformer); - configValuesEdited = true; - } - - @Override - public void addToCollection(Key> key, T value) { - super.addToCollection(key, value); - configValuesEdited = true; - } - - @Override - public void removeFromCollection(Key> key, T value) { - super.removeFromCollection(key, value); - configValuesEdited = true; - } - - @Override - public void putInMap(Key> key, K mapKey, T mapValue) { - super.putInMap(key, mapKey, mapValue); - configValuesEdited = true; - } - - @Override - public void removeFromMap(Key> key, K mapKey) { - super.removeFromMap(key, mapKey); - configValuesEdited = true; - } - - @Override - public void load(RegistryScope registryScope) { - final int ordinal = registryScope.ordinal(); - if (ordinal <= RegistryScope.DEFAULT.ordinal()) { - loadDefaultScope(); - } - loadConfig(); - loadOrdinal(ordinal); - } - - @Override - public boolean save() { - if (configValuesEdited) { - for (Map.Entry, String> entry : nodeNameMap.entrySet()) { - CommentedConfigurationNode node = fromString(entry.getValue()); - try { - setNodeValue(node, entry.getKey()); - } catch (ObjectMappingException e) { - logger.error("Unable to set config value for " + entry.getKey(), e); - } - } - try { - configLoader.save(rootConfigurationNode); - configValuesEdited = false; - return true; - } catch (IOException e) { - e.printStackTrace(); - } - } - return false; - } - - private CommentedConfigurationNode fromString(String name) { - String[] path = name.split("[.]"); - CommentedConfigurationNode node = rootConfigurationNode; - for (String s : path) { - node = node.getNode(s); - } - return node; - } - - private void setNodeDefault(CommentedConfigurationNode node, Key key) throws ObjectMappingException { - T def = getDefault(key); - node.setValue(key.getType(), def); - set(key, def); - } - - private void setNodeValue(CommentedConfigurationNode node, Key key) throws ObjectMappingException { - node.setValue(key.getType(), getOrDefault(key)); - } - - @RegistryScoped - private void loadConfig() { - try { - if (options == null) { - rootConfigurationNode = configLoader.load(); - } else { - rootConfigurationNode = configLoader.load(options); - } - } catch (IOException e) { - e.printStackTrace(); - } - - int updatedCount = 0; - for (Map.Entry, String> entry : nodeNameMap.entrySet()) { - Key key = entry.getKey(); - CommentedConfigurationNode node = fromString(entry.getValue()); - if (node.isVirtual()) { - try { - setNodeDefault(node, key); - updatedCount++; - } catch (ObjectMappingException e) { - e.printStackTrace(); - } - } else { - boolean[] modified = {false}; - initConfigValue(key, node, modified); - if (modified[0]) { - updatedCount++; - } - } - - if (node.isVirtual() || !node.getComment().isPresent()) { - node.setComment(nodeDescriptionMap.get(key)); - updatedCount++; - } - } - if (updatedCount > 0) { - try { - configLoader.save(rootConfigurationNode); - configValuesEdited = false; - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Nullable - private T initConfigValue(Key key, CommentedConfigurationNode node, boolean[] modified) { - return initConfigValue(key, key.getType(), node, modified); - } - - /** - * @param typeToken {@link TypeToken} of node to parse. Pass a {@link Key} to save that value to the registry - * @param node {@link CommentedConfigurationNode} to get value from - */ - @Nullable - private T initConfigValue(@Nullable Key key, TypeToken typeToken, CommentedConfigurationNode node, boolean[] modified) { - - // it ain't pretty but it works - - if (key != null && typeToken.isSubtypeOf(List.class)) { - - // *** unwrap list *** // - try { - - Method getMethod = List.class.getMethod("get", int.class); - Invokable invokable = typeToken.method(getMethod); - T list = (T) verify(verificationMap.get(key), node.getList(invokable.getReturnType()), node, modified); - - set(key, list); - - return list; - - } catch (NoSuchMethodException | IllegalArgumentException | ObjectMappingException e) { - e.printStackTrace(); - return null; - } - - } else if (typeToken.isSubtypeOf(Map.class)) { - - // *** unwrap map *** // - try { - - Method getMethod = Map.class.getMethod("get", Object.class); - Invokable invokable = typeToken.method(getMethod); - TypeToken subType = invokable.getReturnType(); - - Map result = new HashMap<>(); - - for (Map.Entry entry : node.getChildrenMap().entrySet()) { - // here comes the recursion - result.put(entry.getValue().getKey(), initConfigValue(null, subType, entry.getValue(), modified)); - } - - if (key != null) { - T map = (T) verify(verificationMap.get(key), result, node, modified); - set(key, map); - } - - return (T) result; - - } catch (NoSuchMethodException | IllegalArgumentException e) { - e.printStackTrace(); - return null; - } - } else if (key != null) { - try { - T value = node.getValue(typeToken); - set(key, (T) verify(verificationMap.get(key), value, node, modified)); - return value; - } catch (ClassCastException | ObjectMappingException e) { - e.printStackTrace(); - return null; - } - } else { - try { - return node.getValue(typeToken); - } catch (ObjectMappingException e) { - e.printStackTrace(); - return null; - } - } - } - - private T verify(Map, Function> verificationMap, T value, CommentedConfigurationNode node, boolean[] modified) { - if (verificationMap == null) return value; // if there is no verification function defined - T result = value; - for (Map.Entry, Function> entry : verificationMap.entrySet()) { - if (entry.getKey().test(result)) { - modified[0] = true; - result = entry.getValue().apply(result); - } - } - if (modified[0]) { - node.setValue(result); - } - return result; - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseExtendedRegistry.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseExtendedRegistry.java deleted file mode 100644 index b9437a275..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseExtendedRegistry.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.registry; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.anvilpowered.anvil.api.registry.ConfigurationService; -import org.anvilpowered.anvil.api.registry.Key; -import org.anvilpowered.anvil.api.registry.RegistryScope; - -import java.util.Optional; - -/** - * A registry that is backed by the configuration service - */ -@Singleton -@SuppressWarnings("unchecked") -public class BaseExtendedRegistry extends BaseRegistry { - - @Inject - protected ConfigurationService configurationService; - - @Override - public Optional get(Key key) { - Optional result = super.get(key); - return result.isPresent() ? result : configurationService.get(key); - } - - @Override - public T getDefault(Key key) { - T result = (T) defaultMap.get(key); - return result == null ? configurationService.getDefault(key) : result; - } - - @Override - public void load(RegistryScope registryScope) { - configurationService.load(registryScope); - super.load(registryScope); - } - - @Override - public String toString() { - if (configurationService == null) { - return super.toString(); - } else { - return super.toString() + "\n" + configurationService; - } - } -} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseRegistry.java b/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseRegistry.java deleted file mode 100644 index 08e1999be..000000000 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/base/registry/BaseRegistry.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.base.registry; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.registry.Key; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.registry.RegistryScope; -import org.anvilpowered.anvil.api.registry.RegistryScoped; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Singleton -@SuppressWarnings("unchecked") -public class BaseRegistry implements Registry { - - @Inject - protected Logger logger; - - final Map, Object> defaultMap, valueMap; - private final Map> listeners; - private Registry coreRegistry; - @Nullable - private String stringRepresentation; - - public BaseRegistry() { - defaultMap = new HashMap<>(); - valueMap = new HashMap<>(); - listeners = new HashMap<>(); - } - - @Override - public T getUnsafe(Key key) { - T t = (T) valueMap.get(key); - if (t == null) { - throw new NoSuchElementException("Could not find value for key " + key); - } - return t; - } - - @Override - public Optional get(Key key) { - return Optional.ofNullable((T) valueMap.get(key)); - } - - @Override - public T getDefault(Key key) { - T result = (T) defaultMap.get(key); - return result == null ? key.getFallbackValue() : result; - } - - @Override - public void set(Key key, T value) { - valueMap.put(key, value); - stringRepresentation = null; - } - - @RegistryScoped - protected void setDefault(Key key, T value) { - defaultMap.put(key, value); - stringRepresentation = null; - } - - @Override - public T getExtraSafe(Key key) { - if (coreRegistry == null) { - coreRegistry = Anvil.getRegistry(); - } - if (this != coreRegistry - && getOrDefault(Keys.USE_SHARED_ENVIRONMENT)) { - if (key.equals(Keys.DATA_STORE_NAME) - || key.equals(Keys.MONGODB_HOSTNAME) - || key.equals(Keys.MONGODB_PORT) - || key.equals(Keys.MONGODB_USE_SRV)) { - return coreRegistry.getOrDefault(key); - } else if (getOrDefault(Keys.USE_SHARED_CREDENTIALS)) { - if (key.equals(Keys.MONGODB_USE_CONNECTION_STRING) - || key.equals(Keys.MONGODB_CONNECTION_STRING) - || key.equals(Keys.MONGODB_USERNAME) - || key.equals(Keys.MONGODB_PASSWORD) - || key.equals(Keys.MONGODB_AUTH_DB) - || key.equals(Keys.MONGODB_USE_AUTH)) { - return coreRegistry.getOrDefault(key); - } - } - } - return getOrDefault(key); - } - - @Override - public void remove(Key key) { - valueMap.remove(key); - stringRepresentation = null; - } - - @Override - public void transform(Key key, BiFunction, ? super T, ? extends T> transformer) { - valueMap.compute(key, (BiFunction, ? super Object, ?>) transformer); - stringRepresentation = null; - } - - @Override - public void transform(Key key, Function transformer) { - transform(key, (k, v) -> transformer.apply((T) v)); - stringRepresentation = null; - } - - @Override - public void addToCollection(Key> key, T value) { - ((Collection) valueMap.get(key)).add(value); - stringRepresentation = null; - } - - @Override - public void removeFromCollection(Key> key, T value) { - ((Collection) valueMap.get(key)).remove(value); - stringRepresentation = null; - } - - @Override - public void putInMap(Key> key, K mapKey, T mapValue) { - ((Map) valueMap.get(key)).put(mapKey, mapValue); - stringRepresentation = null; - } - - @Override - public void removeFromMap(Key> key, K mapKey) { - ((Map) valueMap.get(key)).remove(mapKey); - stringRepresentation = null; - } - - @Override - public ListenerRegistrationEnd whenLoaded(Runnable listener) { - return new ListenerRegistrationEndImpl(listener); - } - - private class ListenerRegistrationEndImpl implements ListenerRegistrationEnd { - - private final Runnable listener; - private int order; - private RegistryScope registryScope; - - public ListenerRegistrationEndImpl(Runnable listener) { - this.listener = listener; - order = 0; - registryScope = RegistryScope.DEFAULT; - } - - @Override - public ListenerRegistrationEnd order(int order) { - this.order = order; - return this; - } - - @Override - public ListenerRegistrationEnd scope(RegistryScope registryScope) { - this.registryScope = registryScope; - return this; - } - - @Override - public void register() { - listeners.computeIfAbsent(order, o -> new HashMap<>()) - .put(listener, registryScope); - } - } - - @Override - public void load(RegistryScope registryScope) { - final int ordinal = registryScope.ordinal(); - if (ordinal <= RegistryScope.DEFAULT.ordinal()) { - loadDefaultScope(); - } - loadOrdinal(ordinal); - } - - protected final void loadOrdinal(int ordinal) { - listeners.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) - .forEach(e -> e.getValue().forEach((r, c) -> { - if (ordinal <= c.ordinal()) { - r.run(); - } - })); - } - - /** - * Override this method to load values into this registry on normal reloads - */ - @RegistryScoped - protected void loadDefaultScope() { - } - - @Override - public String toString() { - if (stringRepresentation != null) { - return stringRepresentation; - } - Set> keys = new HashSet<>(); - int[] width = {0, 32, 32}; - Consumer> addToKeys = key -> { - final int keyLength = key.toString().length(); - if (keyLength > width[0]) { - width[0] = keyLength; - } - keys.add(key); - }; - valueMap.keySet().forEach(addToKeys); - defaultMap.keySet().forEach(addToKeys); - width[0] += 5; - return stringRepresentation = String.format("%-" + width[0] + "s", "Key") - + String.format("%-" + width[1] + "s", "Value") - + String.format("%-" + width[2] + "s", "Default") - + '\n' - + keys.stream().map(key -> - String.format("%-" + width[0] + "s", key.toString()) - + String.format("%-" + width[1] + "s", valueMap.get(key)) - + String.format("%-" + width[2] + "s", defaultMap.get(key)) - ).collect(Collectors.joining("\n")); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/AnvilImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/AnvilImpl.java deleted file mode 100644 index a7dc11494..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/AnvilImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.inject.Injector; -import com.google.inject.Module; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.slf4j.Logger; - -public class AnvilImpl extends Anvil { - - public AnvilImpl(Injector injector, Module module) { - super(AnvilPluginInfo.id, injector, module); - } - - @Override - protected void applyToBuilder(Environment.Builder builder) { - builder.withRootCommand(); - } - - public static Logger getLogger() { - return environment.getInjector().getInstance(Logger.class); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentBuilderImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentBuilderImpl.java deleted file mode 100644 index 1e91c4d34..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentBuilderImpl.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.base.Preconditions; -import com.google.common.reflect.TypeToken; -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Module; -import com.google.inject.TypeLiteral; -import com.google.inject.name.Names; -import com.google.inject.util.Modules; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.registry.RegistryScope; -import org.anvilpowered.anvil.common.module.PlatformModule; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class EnvironmentBuilderImpl implements Environment.Builder { - - private String name; - @Nullable - private Injector rootInjector; - private Object plugin; - private Supplier loggerSupplier; - private boolean withRootCommand = false; - private final Collection modules; - private final Map, Consumer> earlyServices; - private final Collection> loadedListeners; - private final Collection> readyListeners; - private final Collection> reloadedListeners; - private static final Collection builders = new ArrayList<>(); - private static boolean alreadyCompleted = false; - - public static void completeInitialization(Module platformModule, Module fallbackModule) { - if (alreadyCompleted) { - throw new IllegalStateException("This method should only be called exactly once (in Anvil Common)"); - } - alreadyCompleted = true; - Map>> loadedListeners = new HashMap<>(); - Map>> readyListeners = new HashMap<>(); - Map>> reloadedListeners = new HashMap<>(); - List environments = builders.stream().map(builder -> { - final String name = builder.name; - loadedListeners.put(name, builder.loadedListeners); - readyListeners.put(name, builder.readyListeners); - reloadedListeners.put(name, builder.reloadedListeners); - List modules = new ArrayList<>(); - modules.add(Modules.override(fallbackModule).with(builder.modules)); - return new EnvironmentImpl( - builder.rootInjector, - name, - builder.plugin, - builder.loggerSupplier, - builder.withRootCommand, - modules, - builder.earlyServices - ); - }).collect(Collectors.toList()); - AbstractModule commonModule = new AbstractModule() { - @Override - protected void configure() { - for (EnvironmentImpl environment : environments) { - bind(Environment.class) - .annotatedWith(Names.named(environment.getName())) - .toInstance(environment); - } - } - }; - environments.sort(Comparator.naturalOrder()); - for (EnvironmentImpl environment : environments) { - environment.addModule(platformModule); - environment.addModule(commonModule); - environment.addModule(new AbstractModule() { - @Override - protected void configure() { - bind(ClassLoader.class).toInstance(environment.getPlugin() - .getClass().getClassLoader()); - bind(Environment.class).toInstance(environment); - if (platformModule instanceof PlatformModule) { - Platform platform = ((PlatformModule) platformModule).getPlatform(); - if (platform instanceof PlatformImpl) { - ((PlatformImpl) platform).bindLoggerOptionally(environment, binder()); - } - } - } - }); - Injector injector = environment.getInjector(); - if (injector != null) { - injector = injector.createChildInjector(environment.getModules()); - } else { - injector = Guice.createInjector(environment.getModules()); - } - environment.setInjector(injector); - if ("anvil".equals(environment.getName())) { - Anvil.environment = environment; - ((ServiceManagerImpl) Anvil.getServiceManager()) - .setInjector(injector); - } - ServiceManagerImpl.environmentManager - .registerEnvironment(environment, environment.getPlugin()); - for (Map.Entry, Consumer> entry - : environment.getEarlyServices().entrySet()) { - ((Consumer) entry.getValue()) - .accept(injector.getInstance(entry.getKey())); - } - if (environment.withRootCommand()) { - environment.getInstance(CommandNode.class.getCanonicalName()); - } - Registry registry = injector.getInstance(Registry.class); - for (Consumer listener - : loadedListeners.get(environment.getName())) { - registry.whenLoaded(() -> listener.accept(environment)).register(); - } - registry.load(RegistryScope.DEEP); - for (Consumer listener - : reloadedListeners.get(environment.getName())) { - registry.whenLoaded(() -> listener.accept(environment)).register(); - } - for (Consumer listener - : readyListeners.get(environment.getName())) { - listener.accept(environment); - } - } - } - - EnvironmentBuilderImpl() { - modules = new ArrayList<>(); - earlyServices = new HashMap<>(); - loadedListeners = new ArrayList<>(); - readyListeners = new ArrayList<>(); - reloadedListeners = new ArrayList<>(); - } - - @Override - public Environment.Builder addModules(Module... modules) { - this.modules.addAll(Arrays.asList(modules)); - return this; - } - - @Override - public Environment.Builder addModules(Iterable modules) { - modules.forEach(this.modules::add); - return this; - } - - private Environment.Builder addEarlyServices( - Stream keys, - Function> keyTransformer - ) { - keys.forEach(key -> earlyServices.put(keyTransformer.apply(key), t -> { - })); - return this; - } - - @Override - public Environment.Builder addEarlyServices(Key... keys) { - return addEarlyServices(Stream.of(keys), Function.identity()); - } - - @Override - public Environment.Builder addEarlyServices(Iterable> keys) { - return addEarlyServices(StreamSupport.stream(keys.spliterator(), false), - Function.identity()); - } - - @Override - public Environment.Builder addEarlyServices(Class... classes) { - return addEarlyServices(Stream.of(classes), Key::get); - } - - @Override - public Environment.Builder addEarlyServices(TypeLiteral... typeLiterals) { - return addEarlyServices(Stream.of(typeLiterals), Key::get); - } - - @Override - public Environment.Builder addEarlyServices(TypeToken... typeTokens) { - return addEarlyServices(Stream.of(typeTokens), BindingExtensions::getKey); - } - - @Override - public Environment.Builder addEarlyServices(Key key, Consumer initializer) { - earlyServices.put(key, initializer); - return this; - } - - @Override - public Environment.Builder addEarlyServices(Class clazz, Consumer initializer) { - earlyServices.put(Key.get(clazz), initializer); - return this; - } - - @Override - public Environment.Builder addEarlyServices(TypeLiteral typeLiteral, Consumer initializer) { - earlyServices.put(Key.get(typeLiteral), initializer); - return this; - } - - @Override - public Environment.Builder addEarlyServices(TypeToken typeToken, Consumer initializer) { - earlyServices.put(BindingExtensions.getKey(typeToken), initializer); - return this; - } - - @Override - public Environment.Builder setName(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalStateException("Name may not be null or empty"); - } - this.name = name; - return this; - } - - @Override - public Environment.Builder setRootInjector(@Nullable Injector rootInjector) { - this.rootInjector = rootInjector; - return this; - } - - @Override - public Environment.Builder setLoggerSupplier(Supplier logger) { - this.loggerSupplier = logger; - return this; - } - - @Override - public Environment.Builder withRootCommand() { - withRootCommand = true; - return this; - } - - @Override - public Environment.Builder whenLoaded(Consumer listener) { - loadedListeners.add(listener); - return this; - } - - @Override - public Environment.Builder whenReady(Consumer listener) { - readyListeners.add(listener); - return this; - } - - @Override - public Environment.Builder whenReloaded(Consumer listener) { - reloadedListeners.add(listener); - return this; - } - - @Override - public void register(Object plugin) { - Preconditions.checkNotNull(name, "name"); - Preconditions.checkNotNull(plugin, "plugin"); - this.plugin = plugin; - builders.add(this); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentImpl.java deleted file mode 100644 index c6cdb25ad..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Module; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.util.TextService; - -import java.util.Collection; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class EnvironmentImpl implements Environment { - - private Injector injector; - private final String name; - private final Object plugin; - private final Supplier loggerSupplier; - private final boolean withRootCommand; - private final Collection modules; - private final Map, Consumer> earlyServices; - - EnvironmentImpl( - Injector injector, - String name, - Object plugin, - Supplier loggerSupplier, - boolean withRootCommand, - Collection modules, - Map, Consumer> earlyServices - ) { - this.injector = injector; - this.name = name; - this.plugin = plugin; - if (loggerSupplier == null) { - this.loggerSupplier = () -> null; - } else { - this.loggerSupplier = loggerSupplier; - } - this.withRootCommand = withRootCommand; - this.modules = modules; - this.earlyServices = earlyServices; - } - - void setInjector(Injector injector) { - this.injector = injector; - } - - public Supplier getLoggerSupplier() { - return loggerSupplier; - } - - boolean withRootCommand() { - return withRootCommand; - } - - void addModule(Module module) { - this.modules.add(module); - } - - Collection getModules() { - return modules; - } - - Map, Consumer> getEarlyServices() { - return earlyServices; - } - - @Override - public void reload() { - getRegistry().load(); - } - - @Override - public String getName() { - return name; - } - - @Override - public Injector getInjector() { - return injector; - } - - @Override - public Object getPlugin() { - return plugin; - } - - @Override - public PluginInfo getPluginInfo() { - return getInstance(PluginInfo.class.getCanonicalName()); - } - - @Override - public TextService getTextService() { - return getInstance(TextService.class.getCanonicalName()); - } - - @Override - public Registry getRegistry() { - return getInjector().getInstance(Registry.class); - } - - @Override - public int compareTo(Environment o) { - return getName().compareTo(o.getName()); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Environment && getName().equals(((Environment) obj).getName()); - } - - @Override - public String toString() { - return name; - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentManagerImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentManagerImpl.java deleted file mode 100644 index 1f208648f..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/EnvironmentManagerImpl.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.base.Preconditions; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -class EnvironmentManagerImpl implements EnvironmentManager{ - - private final Map environments; - final Map> pluginEnvironmentMap; - - public EnvironmentManagerImpl() { - environments = new HashMap<>(); - pluginEnvironmentMap = new HashMap<>(); - } - - @Override - public Environment getCoreEnvironment() { - return Preconditions.checkNotNull(environments.get("anvil"), - "Global environment not loaded"); - } - - @Override - public Environment getEnvironmentUnsafe(String name) { - return Preconditions.checkNotNull(environments.get(name), - "Could not find environment " + name); - } - - @Override - public Map getEnvironments() { - return Collections.unmodifiableMap(environments); - } - - @Override - public Stream getEnvironmentsAsStream(Pattern pattern) { - return environments.entrySet().stream().filter(e -> - pattern.matcher(e.getKey()).matches() - ).map(Map.Entry::getValue); - } - - @Override - public List getEnvironments(Pattern pattern) { - return getEnvironmentsAsStream(pattern).collect(Collectors.toList()); - } - - @Override - public Optional getEnvironment(Pattern pattern) { - return getEnvironmentsAsStream(pattern).findAny(); - } - - @Override - public Optional getEnvironment(String name) { - return Optional.ofNullable(environments.get(name)); - } - - void registerEnvironment(Environment environment, Object plugin) { - final String name = environment.getName(); - if (environments.containsKey(name)) { - throw new IllegalArgumentException("Environment " + name + " already exists"); - } - environments.put(name, environment); - Set envs = pluginEnvironmentMap.get(plugin); - if (envs == null) { - envs = new TreeSet<>(); - envs.add(environment); - pluginEnvironmentMap.put(plugin, envs); - } else { - envs.add(environment); - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/PlatformImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/PlatformImpl.java deleted file mode 100644 index 08c669282..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/PlatformImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.inject.Binder; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.function.BiConsumer; - -public class PlatformImpl implements Platform { - - private final boolean isProxy; - private final String name; - @Nullable - private final BiConsumer loggerBinder; - - public PlatformImpl( - boolean isProxy, - String name, - @Nullable BiConsumer loggerBinder - ) { - this.isProxy = isProxy; - this.name = name; - this.loggerBinder = loggerBinder; - } - - public PlatformImpl(boolean isProxy, String name) { - this(isProxy, name, null); - } - - @Override - public boolean isProxy() { - return isProxy; - } - - public void bindLoggerOptionally(Environment environment, Binder binder) { - if (loggerBinder != null) { - loggerBinder.accept(environment, binder); - } - } - - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return String.format("Platform(isProxy=%s, name=%s)", isProxy, name); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/api/ServiceManagerImpl.java b/anvil-common/src/main/java/org/anvilpowered/anvil/api/ServiceManagerImpl.java deleted file mode 100644 index 95ed3a40a..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/api/ServiceManagerImpl.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.api; - -import com.google.common.reflect.TypeToken; -import com.google.inject.Injector; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.common.misc.CommonBindingExtensions; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Supplier; - -@SuppressWarnings({"unchecked", "unused", "UnstableApiUsage"}) -class ServiceManagerImpl implements ServiceManager { - - private final Map, Supplier> supplierBindings; - private final Map, Function> functionBindings; - private Injector injector; - static final EnvironmentManagerImpl environmentManager - = new EnvironmentManagerImpl(); - - public ServiceManagerImpl() { - supplierBindings = new HashMap<>(); - functionBindings = new HashMap<>(); - registerBinding(EnvironmentManager.class, () -> environmentManager); - registerBinding(Environment.Builder.class, EnvironmentBuilderImpl::new); - registerBinding(BindingExtensions.class, CommonBindingExtensions::new); - } - - void setInjector(Injector injector) { - this.injector = injector; - } - - @Override - public Supplier provideSupplier(TypeToken typeToken) { - Supplier supplier = (Supplier) supplierBindings.get(typeToken); - if (supplier != null) { - return supplier; - } - return () -> injector.getInstance(BindingExtensions.getKey(typeToken)); - } - - @Override - public Supplier provideSupplier(Class clazz) { - return provideSupplier(TypeToken.of(clazz)); - } - - @Override - public Supplier provideSupplier(String name) { - Supplier[] suppliers = new Supplier[1]; - for (Map.Entry, Supplier> entry : supplierBindings.entrySet()) { - if (entry.getKey().getRawType().getName().equalsIgnoreCase(name)) { - suppliers[0] = (Supplier) entry.getValue(); - break; - } - } - if (suppliers[0] != null) { - return suppliers[0]; - } - return () -> Environment.getInstance(name, injector); - } - - @Override - public Function provideFunction(TypeToken typeToken) { - Function function = (Function) functionBindings.get(typeToken); - if (function != null) { - return function; - } - return injector -> ((Injector) injector) - .getInstance(BindingExtensions.getKey(typeToken)); - } - - @Override - public Function provideFunction(Class clazz) { - return provideFunction(TypeToken.of(clazz)); - } - - @Override - public Function provideFunction(String name) { - Function[] functions = new Function[1]; - for (Map.Entry, Function> entry : functionBindings.entrySet()) { - if (entry.getKey().getRawType().getName().equalsIgnoreCase(name)) { - functions[0] = (Function) entry.getValue(); - break; - } - } - if (functions[0] != null) { - return functions[0]; - } - return injector -> Environment.getInstance(name, (Injector) injector); - } - - @Override - public T provide(TypeToken typeToken) { - return provideSupplier(typeToken).get(); - } - - @Override - public T provide(Class clazz) { - return provideSupplier(clazz).get(); - } - - @Override - public T provide(String name) { - return this.provideSupplier(name).get(); - } - - @Override - public R provide(TypeToken typeToken, T input) { - return provideFunction(typeToken).apply(input); - } - - @Override - public R provide(Class clazz, T input) { - return provideFunction(clazz).apply(input); - } - - @Override - public R provide(String name, T input) { - return this.provideFunction(name).apply(input); - } - - @Override - public void registerBinding(TypeToken typeToken, Supplier supplier) { - supplierBindings.put(typeToken, supplier); - } - - @Override - public void registerBinding(Class clazz, Supplier supplier) { - supplierBindings.put(TypeToken.of(clazz), supplier); - } - - @Override - public void registerBinding(TypeToken typeToken, Function function) { - functionBindings.put(typeToken, function); - } - - @Override - public void registerBinding(Class clazz, Function function) { - functionBindings.put(TypeToken.of(clazz), function); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilCommandNode.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilCommandNode.java deleted file mode 100644 index c947e944a..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilCommandNode.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.Environment; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.api.command.CommandService; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Predicate; - -public abstract class CommonAnvilCommandNode - implements CommandNode { - - protected static final List PLUGINS_ALIAS = Collections.singletonList("plugins"); - protected static final List RELOAD_ALIAS = Collections.singletonList("reload"); - protected static final List REGEDIT_ALIAS = Collections.singletonList("regedit"); - protected static final List HELP_ALIAS = Collections.singletonList("help"); - protected static final List VERSION_ALIAS = Collections.singletonList("version"); - - protected static final String PLUGINS_DESCRIPTION - = String.format("%s plugins command", AnvilPluginInfo.name); - protected static final String RELOAD_DESCRIPTION - = String.format("%s reload command", AnvilPluginInfo.name); - protected static final String REGEDIT_DESCRIPTION - = String.format("%s regedit command", AnvilPluginInfo.name); - protected static final String HELP_DESCRIPTION - = String.format("%s help command", AnvilPluginInfo.name); - protected static final String VERSION_DESCRIPTION - = String.format("%s version command", AnvilPluginInfo.name); - protected static final String ROOT_DESCRIPTION - = String.format("%s root command", AnvilPluginInfo.name); - - protected static final String RELOAD_USAGE = "[-a|--all|-r|--regex] []"; - protected static final String REGEDIT_USAGE - = "[cancel|select|commit|start|key] [||] [info|set|unset|unstage] []"; - - protected static final String HELP_COMMAND = "/anvil help"; - - private boolean alreadyLoaded; - protected Map, Function> descriptions; - protected Map, Predicate> permissions; - protected Map, Function> usages; - - @Inject - protected CommandService commandService; - - @Inject - protected Environment environment; - - protected Registry registry; - - protected CommonAnvilCommandNode(Registry registry) { - this.registry = registry; - registry.whenLoaded(() -> { - if (alreadyLoaded) return; - loadCommands(); - alreadyLoaded = true; - }).register(); - alreadyLoaded = false; - descriptions = new HashMap<>(); - permissions = new HashMap<>(); - usages = new HashMap<>(); - descriptions.put(PLUGINS_ALIAS, c -> PLUGINS_DESCRIPTION); - descriptions.put(RELOAD_ALIAS, c -> RELOAD_DESCRIPTION); - descriptions.put(REGEDIT_ALIAS, c -> REGEDIT_DESCRIPTION); - descriptions.put(HELP_ALIAS, c -> HELP_DESCRIPTION); - descriptions.put(VERSION_ALIAS, c -> VERSION_DESCRIPTION); - usages.put(RELOAD_ALIAS, c -> RELOAD_USAGE); - usages.put(REGEDIT_ALIAS, c -> REGEDIT_USAGE); - } - - protected abstract void loadCommands(); - - private static final String ERROR_MESSAGE = "Anvil command has not been loaded yet"; - - @Nullable - private static String alias; - - public static String getAlias() { - if (alias == null) { - switch (Anvil.getPlatform().getName()) { - case "bungee": - alias = "anvilb"; - break; - case "velocity": - alias = "anvilv"; - break; - default: - alias = "anvil"; - break; - } - } - return alias; - } - - @Override - public Map, Function> getDescriptions() { - return Preconditions.checkNotNull(descriptions, ERROR_MESSAGE); - } - - @Override - public Map, Predicate> getPermissions() { - return Preconditions.checkNotNull(permissions, ERROR_MESSAGE); - } - - @Override - public Map, Function> getUsages() { - return Preconditions.checkNotNull(usages, ERROR_MESSAGE); - } - - @Override - public String getName() { - return getAlias(); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilPluginsCommand.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilPluginsCommand.java deleted file mode 100644 index 2c2f917cf..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilPluginsCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.plugin.PluginMessages; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.anvilpowered.anvil.api.util.TextService; -import org.jetbrains.annotations.Nullable; - -public class CommonAnvilPluginsCommand { - - @Inject - protected PermissionService permissionService; - - @Inject - protected PluginInfo pluginInfo; - - @Inject - protected PluginMessages pluginMessages; - - @Inject - protected Registry registry; - - @Inject - protected TextService textService; - - public void execute(TCommandSource source) { - execute(source, null); - } - - public void execute(TCommandSource source, String @Nullable [] context) { - if (permissionService.hasPermission(source, - registry.getOrDefault(Keys.PLUGINS_PERMISSION))) { - executeDirect(source); - } else { - textService.send(pluginMessages.getNoPermission(), source); - } - } - - public void executeDirect(TCommandSource source) { - String[] names = Anvil.getEnvironmentManager() - .getEnvironments().values() - .stream() - .map(e -> e.getPluginInfo().getName()) - .sorted().toArray(String[]::new); - textService.builder() - .append(pluginInfo.getPrefix()) - .green().append("Plugins (", names.length, "): ") - .appendJoining(", ", names) - .sendTo(source); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilReloadCommand.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilReloadCommand.java deleted file mode 100644 index 757acd7eb..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonAnvilReloadCommand.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.Environment; -import org.anvilpowered.anvil.api.misc.Named; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.plugin.PluginMessages; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.anvilpowered.anvil.api.util.TextService; -import org.jetbrains.annotations.Contract; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; -import java.util.stream.Collectors; - -public class CommonAnvilReloadCommand { - - private static final Function reloadEnvironment = e -> { - e.reload(); - return e.getPluginInfo().getName(); - }; - - @Inject - protected PermissionService permissionService; - - @Inject - protected PluginInfo pluginInfo; - - @Inject - protected PluginMessages pluginMessages; - - @Inject - protected Registry registry; - - @Inject - protected TextService textService; - - public void execute(TCommandSource source, String[] context) { - if (permissionService.hasPermission(source, - registry.getOrDefault(Keys.RELOAD_PERMISSION))) { - executeDirect(source, context); - } else { - textService.send(pluginMessages.getNoPermission(), source); - } - } - - public List suggest() { - List suggestions = Anvil.getEnvironmentManager() - .getEnvironments().values().stream() - .map(Named::getName) - .sorted().collect(Collectors.toList()); - suggestions.add("--all"); - suggestions.add("--regex"); - return suggestions; - } - - public List suggest(TCommandSource source, String[] context) { - return suggest(); - } - - public void executeDirect(TCommandSource source, String[] context) { - final int length = context.length; - if (length == 0) { - checkPresent(source, false); - return; - } - String[] reloadedResult = {""}; - if ("-a".equals(context[0]) || "--all".equals(context[0])) { - reloadedResult[0] = doAll(); - } else if ("-r".equals(context[0]) || "--regex".equals(context[0])) { - if (!checkPresent(source, length > 1) - || !doRegex(source, context[1], reloadedResult)) { - return; - } - } else { - if (!doDirect(source, context[0], reloadedResult)) { - return; - } - } - sendSuccess(source, reloadedResult); - } - - protected String doAll() { - return Anvil.getEnvironmentManager() - .getEnvironments().values().stream() - .map(reloadEnvironment) - .collect(Collectors.joining(", ")); - } - - @Contract("_, _ -> param2") - protected boolean checkPresent(TCommandSource source, boolean present) { - if (present) { - return true; - } - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Plugin is required if '--all' is not set") - .sendTo(source); - return false; - } - - protected boolean doRegex(TCommandSource source, String regex, String[] reloadedResult) { - try { - reloadedResult[0] = Anvil.getEnvironmentManager() - .getEnvironmentsAsStream(Pattern.compile(regex)) - .map(reloadEnvironment) - .collect(Collectors.joining(", ")); - if (reloadedResult[0].length() == 0) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Regex ") - .gold().append(regex) - .red().append(" did not match any plugins") - .sendTo(source); - return false; - } - } catch (PatternSyntaxException e) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Failed to parse ") - .gold().append(regex) - .sendTo(source); - return false; - } - return true; - } - - protected boolean doDirect(TCommandSource source, String plugin, String[] reloadedResult) { - Optional optionalReloaded = Anvil.getEnvironmentManager() - .getEnvironment(plugin) - .map(reloadEnvironment); - if (!optionalReloaded.isPresent()) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Could not find plugin ") - .gold().append(plugin) - .sendTo(source); - return false; - } - reloadedResult[0] = optionalReloaded.get(); - return true; - } - - protected void sendSuccess(TCommandSource source, String[] reloadedResult) { - textService.builder() - .append(pluginInfo.getPrefix()) - .green().append("Successfully reloaded ") - .gold().append(reloadedResult[0]) - .sendTo(source); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCallbackCommand.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCallbackCommand.java deleted file mode 100644 index 6a4af53e8..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCallbackCommand.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.util.TextService; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.function.Consumer; - -@Singleton -public class CommonCallbackCommand { - - @Inject - protected PluginInfo pluginInfo; - - @Inject - protected TextService textService; - - private final Map> callbacks; - - public CommonCallbackCommand() { - callbacks = new HashMap<>(); - } - - public void addCallback(UUID uuid, Consumer callback) { - callbacks.put(uuid, callback); - } - - public void execute(TCommandSource source, String[] context) { - if (context.length == 0) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Missing callback id") - .sendTo(source); - return; - } - UUID uuid; - try { - uuid = UUID.fromString(context[0]); - } catch (IllegalArgumentException e) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Callback id must be a valid UUID") - .sendTo(source); - return; - } - Consumer callback = callbacks.get(uuid); - if (callback == null) { - textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("Callback id ") - .gold().append(uuid) - .red().append(" does not match any callbacks") - .sendTo(source); - return; - } - callback.accept(source); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCommandService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCommandService.java deleted file mode 100644 index f272e86ff..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/command/CommonCommandService.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Environment; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.api.command.CommandService; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.util.TextService; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -public abstract class CommonCommandService< - TCommand, - TCommandExecutor, - TString, - TCommandSource> - implements CommandService { - - @Inject - protected Environment environment; - - @Inject - protected PluginInfo pluginInfo; - - @Inject - protected TextService textService; - - protected abstract void runExecutor( - TCommandExecutor executor, - TCommand command, - TCommandSource source, - String alias, - String[] context - ); - - protected abstract List getSuggestions( - TCommandExecutor executor, - TCommand command, - TCommandSource source, - String alias, - String[] context - ); - - protected abstract TCommandExecutor generateWrapperCommand( - CommandExecutorWrapper command); - - protected interface CommandExecutorWrapper { - void execute( - TCommand command, - TCommandSource source, - String alias, - String[] context - ); - - default List suggest( - TCommand command, - TCommandSource commandSource, - String alias, - String[] context - ) { - return ImmutableList.of(); - } - } - - private void sendSubCommandError( - TCommandSource source, - @Nullable String command, - Map, TCommandExecutor> children - ) { - textService.builder() - .red().append("Input command ", command == null ? "null" : command) - .append(" was not a valid subcommand!\n") - .appendIf(command != null, command, "\n^") - .append("\nAvailable: ") - .append(children.keySet().stream() - .filter(l -> !l.isEmpty()) - .map(l -> l.get(0)) - .collect(Collectors.joining(", ")) - ) - .sendTo(source); - } - - private class RoutingCommand implements CommandExecutorWrapper { - - @Nullable - private final TCommandExecutor root; - private final Map, TCommandExecutor> children; - private final boolean childCommandFallback; - - private RoutingCommand( - @Nullable TCommandExecutor root, - Map, TCommandExecutor> children, - boolean childCommandFallback - ) { - this.root = root; - this.children = children; - this.childCommandFallback = childCommandFallback; - } - - @Override - public void execute(TCommand command, TCommandSource source, String alias, String[] context) { - final int length = context.length; - if (length > 0) { - for (Map.Entry, TCommandExecutor> entry : children.entrySet()) { - final List key = entry.getKey(); - if (key.contains(context[0])) { - runExecutor(entry.getValue(), command, source, context[0], - // remove the first argument (the child selector) - Arrays.copyOfRange(context, 1, length)); - return; - } - } - if (!childCommandFallback) { - sendSubCommandError(source, context[0], children); - return; - } - } - // reached the end; if no children have - // matched, run the root command - if (root == null) { - sendSubCommandError(source, null, children); - return; - } - runExecutor(root, command, source, alias, context); - } - - @Override - public List suggest(TCommand command, TCommandSource source, String alias, String[] context) { - final int length = context.length; - if (length == 0) { - return ImmutableList.of(); - } - if (length == 1) { - List suggestions = new ArrayList<>(); - for (List aliases : children.keySet()) { - if (aliases.size() == 0) { - continue; - } - suggestions.add(aliases.get(0)); - } - return suggestions; - } - for (Map.Entry, TCommandExecutor> entry : children.entrySet()) { - final List key = entry.getKey(); - if (key.contains(context[0])) { - return getSuggestions(entry.getValue(), command, source, context[0], - // remove the first argument (the child selector) - Arrays.copyOfRange(context, 1, length)); - } - } - if (!childCommandFallback) { - return ImmutableList.of(); - } - return getSuggestions(root, command, source, alias, context); - } - } - - @Override - public TCommandExecutor generateRoutingCommand( - @Nullable TCommandExecutor root, - Map, TCommandExecutor> children, - boolean childCommandFallback - ) { - return generateWrapperCommand(new RoutingCommand(root, children, childCommandFallback)); - } - - protected void sendRoot(TCommandSource source, String helpUsage, boolean extended) { - textService.builder() - .append(pluginInfo.getPrefix()) - .aqua().append("Running version ") - .green().append(pluginInfo.getVersion()) - .aqua().append(" by ") - .appendJoining(", ", pluginInfo.getAuthors()) - .append("\n") - .appendIf(extended, textService.builder() - .green().append("Use ") - .gold().append(helpUsage) - .green().append(" for help") - ) - .appendIf(!extended, textService.builder() - .red().append("You do not have permission for any sub-commands") - ) - .sendTo(source); - } - - protected void sendVersion(TCommandSource source, String helpUsage, boolean extended) { - textService.builder() - .append(pluginInfo.getPrefix()) - .aqua().append("Running version ") - .green().append(pluginInfo.getVersion()) - .aqua().append(" by ") - .appendJoining(", ", pluginInfo.getAuthors()) - .gray().append("\nBuild date: ") - .aqua().append(pluginInfo.getBuildDate(), "\n") - .appendIf(extended, textService.builder() - .green().append("Use ") - .gold().append(helpUsage) - .green().append(" for help") - ) - .appendIf(!extended, textService.builder() - .red().append("You do not have permission for any sub-commands") - ) - .sendTo(source); - } - - protected void sendReload(TCommandSource source) { - environment.reload(); - textService.builder() - .append(pluginInfo.getPrefix()) - .green().append("Successfully reloaded!") - .sendTo(source); - } - - protected String getFullPath(CommandNode node) { - StringBuilder s = new StringBuilder(32); - s.append("/"); - for (String name : node.getPath()) { - s.append(name).append(" "); - } - s.append(node.getName()).append(" "); - return s.toString(); - } - - protected void sendHelp(TCommandSource source, CommandNode node) { - List helpList = new ArrayList<>(); - String fullPath = getFullPath(node); - - node.getDescriptions().forEach((aliases, command) -> { - Predicate permission = node.getPermissions().get(aliases); - if (permission != null && permission.test(source)) return; - - Function description = node.getDescriptions().get(aliases); - Function usage = node.getUsages().get(aliases); - - TextService.Builder builder = textService.builder() - .gold().append(fullPath).appendIf(aliases.size() > 0, aliases.get(0)); - if (description != null) { - builder.append(" - ", description.apply(source)); - } - builder.gray().append("\nUsage: ", fullPath) - .appendJoining(", ", aliases.toArray()); - if (usage != null) { - builder.append(" ", usage.apply(source)); - } - - helpList.add(builder.build()); - }); - textService.paginationBuilder() - .title(textService.builder().gold().append(pluginInfo.getName(), " - ", pluginInfo.getOrganizationName()).build()) - .padding(textService.builder().dark_green().append("-").build()) - .contents(helpList) - .build() - .sendTo(source); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberManager.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberManager.java deleted file mode 100644 index 14711e4a4..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.coremember; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.coremember.CoreMemberRepository; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.base.datastore.BaseManager; - -public class CommonCoreMemberManager extends BaseManager> implements CoreMemberManager { - - @Inject - public CommonCoreMemberManager(Registry registry) { - super(registry); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberRepository.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberRepository.java deleted file mode 100644 index 25096640e..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonCoreMemberRepository.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.coremember; - -import org.anvilpowered.anvil.api.coremember.CoreMemberRepository; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.base.datastore.BaseRepository; - -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public abstract class CommonCoreMemberRepository< - TKey, - TDataStore> - extends BaseRepository, TDataStore> - implements CoreMemberRepository { - - @Override - @SuppressWarnings("unchecked") - public Class> getTClass() { - return (Class>) getDataStoreContext().getEntityClassUnsafe("coremember"); - } - - @Override - public CompletableFuture>> getOneOrGenerateForUser(UUID userUUID, String userName, String ipAddress) { - return getOneOrGenerateForUser(userUUID, userName, ipAddress, new boolean[]{false, false, false, false, false, false, false, false}); - } - - @Override - public boolean checkBanned(CoreMember coreMember) { - if (coreMember.isBanned() && coreMember.getBanEndUtc().isAfter(OffsetDateTime.now(ZoneOffset.UTC).toInstant())) { - return true; - } else if (coreMember.isBanned()) { - unBanUser(coreMember.getUserUUID()); - } - return false; - } - - @Override - public CompletableFuture checkBanned(TKey id) { - return getOne(id).thenApplyAsync(o -> o.map(this::checkBanned).orElse(false)); - } - - @Override - public CompletableFuture checkBannedForUser(UUID userUUID) { - return getOneForUser(userUUID).thenApplyAsync(o -> o.map(this::checkBanned).orElse(false)); - } - - @Override - public CompletableFuture checkBannedForUser(String userName) { - return getOneForUser(userName).thenApplyAsync(o -> o.map(this::checkBanned).orElse(false)); - } - - @Override - public boolean checkMuted(CoreMember coreMember) { - if (coreMember.isMuted() && coreMember.getMuteEndUtc().isAfter(OffsetDateTime.now(ZoneOffset.UTC).toInstant())) { - return true; - } else if (coreMember.isMuted()) { - unMuteUser(coreMember.getUserUUID()); - } - return false; - } - - @Override - public CompletableFuture checkMuted(TKey id) { - return getOne(id).thenApplyAsync(o -> o.map(this::checkMuted).orElse(false)); - } - - @Override - public CompletableFuture checkMutedForUser(UUID userUUID) { - return getOneForUser(userUUID).thenApplyAsync(o -> o.map(this::checkMuted).orElse(false)); - } - - @Override - public CompletableFuture checkMutedForUser(String userName) { - return getOneForUser(userName).thenApplyAsync(o -> o.map(this::checkMuted).orElse(false)); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonMongoCoreMemberRepository.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonMongoCoreMemberRepository.java deleted file mode 100644 index 9ff3d05c2..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonMongoCoreMemberRepository.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.coremember; - -import dev.morphia.Datastore; -import dev.morphia.query.Query; -import dev.morphia.query.UpdateOperations; -import org.anvilpowered.anvil.api.coremember.MongoCoreMemberRepository; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.base.datastore.BaseMongoRepository; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public class CommonMongoCoreMemberRepository - extends CommonCoreMemberRepository - implements BaseMongoRepository>, - MongoCoreMemberRepository { - - @Override - public CompletableFuture>> getOneOrGenerateForUser(UUID userUUID, String userName, String ipAddress, boolean[] flags) { - final int length = flags.length; - if (length != 8) throw new IllegalArgumentException("Flags must be an array of length 8"); - for (int i = 0; i < length; i++) { - flags[i] = false; - } - return getOneForUser(userUUID).thenApplyAsync(optionalMember -> { - if (!optionalMember.isPresent()) { - CoreMember member = generateEmpty(); - member.setUserUUID(userUUID); - member.setUserName(userName); - member.setIpAddress(ipAddress); - member.setLastJoinedUtc(OffsetDateTime.now(ZoneOffset.UTC).toInstant()); - flags[0] = true; - return insertOne(member).join(); - } - - CoreMember member = optionalMember.get(); - UpdateOperations> updateOperations = createUpdateOperations(); - boolean updateName = false; - boolean updateIpAddress = false; - if (!userName.equals(member.getUserName())) { - updateOperations.set("userName", userName); - updateName = true; - } - if (!ipAddress.equals(member.getIpAddress())) { - updateOperations.set("ipAddress", ipAddress); - updateIpAddress = true; - } - updateOperations.set("lastJoinedUtc", OffsetDateTime.now(ZoneOffset.UTC).toInstant()); - if (getDataStoreContext().getDataStore() - .update(asQuery(member.getId()), updateOperations) - .getUpdatedCount() > 0) { - if (updateName) { - member.setUserName(userName); - flags[1] = true; - } - if (updateIpAddress) { - member.setIpAddress(ipAddress); - flags[2] = true; - } - } - return optionalMember; - }); - } - - @Override - public CompletableFuture>> getOneForUser(UUID userUUID) { - return getOne(asQuery(userUUID)); - } - - @Override - public CompletableFuture>> getOneForUser(String userName) { - return getOne(asQuery(userName)); - } - - @Override - public CompletableFuture>> getForIpAddress(String ipAddress) { - return getAll(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture ban(ObjectId id, Instant endUtc, String reason) { - return ban(asQuery(id), endUtc, reason); - } - - @Override - public CompletableFuture banUser(UUID userUUID, Instant endUtc, String reason) { - return ban(asQuery(userUUID), endUtc, reason); - } - - @Override - public CompletableFuture banUser(String userName, Instant endUtc, String reason) { - return ban(asQuery(userName), endUtc, reason); - } - - @Override - public CompletableFuture banIpAddress(String ipAddress, Instant endUtc, String reason) { - return ban(asQueryForIpAddress(ipAddress), endUtc, reason); - } - - @Override - public CompletableFuture unBan(ObjectId id) { - return unBan(asQuery(id)); - } - - @Override - public CompletableFuture unBanUser(UUID userUUID) { - return unBan(asQuery(userUUID)); - } - - @Override - public CompletableFuture unBanUser(String userName) { - return unBan(asQuery(userName)); - } - - @Override - public CompletableFuture unBanIpAddress(String ipAddress) { - return unBan(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture mute(ObjectId id, Instant endUtc, String reason) { - return mute(asQuery(id), endUtc, reason); - } - - @Override - public CompletableFuture muteUser(UUID userUUID, Instant endUtc, String reason) { - return mute(asQuery(userUUID), endUtc, reason); - } - - @Override - public CompletableFuture muteUser(String userName, Instant endUtc, String reason) { - return mute(asQuery(userName), endUtc, reason); - } - - @Override - public CompletableFuture muteIpAddress(String ipAddress, Instant endUtc, String reason) { - return mute(asQueryForIpAddress(ipAddress), endUtc, reason); - } - - @Override - public CompletableFuture unMute(ObjectId id) { - return unMute(asQuery(id)); - } - - @Override - public CompletableFuture unMuteUser(UUID userUUID) { - return unMute(asQuery(userUUID)); - } - - @Override - public CompletableFuture unMuteUser(String userName) { - return unMute(asQuery(userName)); - } - - @Override - public CompletableFuture unMuteIpAddress(String ipAddress) { - return unMute(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture setNickName(ObjectId id, String nickName) { - return setNickName(asQuery(id), nickName); - } - - @Override - public CompletableFuture setNickNameForUser(UUID userUUID, String nickName) { - return setNickName(asQuery(userUUID), nickName); - } - - @Override - public CompletableFuture setNickNameForUser(String userName, String nickName) { - return setNickName(asQuery(userName), nickName); - } - - @Override - public CompletableFuture deleteNickName(ObjectId id) { - return deleteNickName(asQuery(id)); - } - - @Override - public CompletableFuture deleteNickNameForUser(UUID userUUID) { - return deleteNickName(asQuery(userUUID)); - } - - @Override - public CompletableFuture deleteNickNameForUser(String userName) { - return deleteNickName(asQuery(userName)); - } - - @Override - public Query> asQuery(UUID userUUID) { - return asQuery().field("userUUID").equal(userUUID); - } - - @Override - public Query> asQuery(String userName) { - return asQuery().field("userName").containsIgnoreCase(userName); - } - - @Override - public Query> asQueryForIpAddress(String ipAddress) { - return asQuery().field("ipAddress").equal(ipAddress); - } - - @Override - public CompletableFuture ban(Query> query, Instant endUtc, String reason) { - return update(query, set("banned", true) - .set("banEndUtc", endUtc) - .set("banReason", reason) - ); - } - - @Override - public CompletableFuture unBan(Query> query) { - return update(query, set("banned", false)); - } - - @Override - public CompletableFuture mute(Query> query, Instant endUtc, String reason) { - return update(query, set("muted", true) - .set("muteEndUtc", endUtc) - .set("muteReason", reason) - ); - } - - @Override - public CompletableFuture unMute(Query> query) { - return update(query, set("muted", false)); - } - - @Override - public CompletableFuture setNickName(Query> query, String nickName) { - return update(query, set("nickName", nickName)); - } - - @Override - public CompletableFuture deleteNickName(Query> query) { - return update(query, unSet("nickName")); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonXodusCoreMemberRepository.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonXodusCoreMemberRepository.java deleted file mode 100644 index 92658d377..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/coremember/CommonXodusCoreMemberRepository.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.coremember; - -import com.google.inject.Inject; -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import jetbrains.exodus.entitystore.StoreTransaction; -import org.anvilpowered.anvil.api.coremember.XodusCoreMemberRepository; -import org.anvilpowered.anvil.api.model.Mappable; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.base.datastore.BaseXodusRepository; -import org.slf4j.Logger; - -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -public class CommonXodusCoreMemberRepository - extends CommonCoreMemberRepository - implements BaseXodusRepository>, - XodusCoreMemberRepository { - - @Inject - private Logger logger; - - @Override - public CompletableFuture>> getOneOrGenerateForUser(UUID userUUID, String userName, String ipAddress, boolean[] flags) { - final int length = flags.length; - if (length != 8) throw new IllegalArgumentException("Flags must be an array of length 8"); - for (int i = 0; i < length; i++) { - flags[i] = false; - } - return CompletableFuture.supplyAsync(() -> - getDataStoreContext().getDataStore().computeInTransaction(txn -> { - Iterator iterator = asQuery(userUUID).apply(txn).iterator(); - if (!iterator.hasNext()) { - CoreMember member = generateEmpty(); - member.setUserUUID(userUUID); - member.setUserName(userName); - member.setIpAddress(ipAddress); - member.setLastJoinedUtc(OffsetDateTime.now(ZoneOffset.UTC).toInstant()); - flags[0] = true; - return insertOne(member).join(); - } - - CoreMember member = generateEmpty(); - Entity entity = iterator.next(); - ((Mappable) member).readFrom(entity); - - boolean updateUsername = false; - boolean updateIPAddress = false; - - if (!userName.equals(member.getUserName())) { - entity.setProperty("userName", userName); - updateUsername = true; - } - - if (!ipAddress.equals(member.getIpAddress())) { - entity.setProperty("ipAddress", ipAddress); - updateIPAddress = true; - } - Instant now = OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - long nowSeconds = now.getEpochSecond(); - int nowNanos = now.getNano(); - entity.setProperty("lastJoinedUtcSeconds", nowSeconds); - entity.setProperty("lastJoinedUtcNanos", nowNanos); - entity.setProperty("updatedUtcSeconds", nowSeconds); - entity.setProperty("updatedUtcNanos", nowNanos); - if (txn.commit()) { - if (updateUsername) { - member.setUserName(userName); - flags[1] = true; - } - if (updateIPAddress) { - member.setIpAddress(ipAddress); - flags[2] = true; - } - member.setLastJoinedUtc(now); - return Optional.of(member); - } - logger.error("Failed to update {} please report this on github!", userName); - return Optional.empty(); - }) - ); - } - - @Override - public CompletableFuture>> getOneForUser(UUID userUUID) { - return getOne(asQuery(userUUID)); - } - - @Override - public CompletableFuture>> getOneForUser(String userName) { - return getOne(asQuery(userName)); - } - - @Override - public CompletableFuture>> getForIpAddress(String ipAddress) { - return getAll(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture ban(EntityId id, Instant endUtc, String reason) { - return ban(asQuery(id), endUtc, reason); - } - - @Override - public CompletableFuture banUser(UUID userUUID, Instant endUtc, String reason) { - return ban(asQuery(userUUID), endUtc, reason); - } - - @Override - public CompletableFuture banUser(String userName, Instant endUtc, String reason) { - return ban(asQuery(userName), endUtc, reason); - } - - @Override - public CompletableFuture banIpAddress(String ipAddress, Instant endUtc, String reason) { - return ban(asQueryForIpAddress(ipAddress), endUtc, reason); - } - - @Override - public CompletableFuture unBan(EntityId id) { - return unBan(asQuery(id)); - } - - @Override - public CompletableFuture unBanUser(UUID userUUID) { - return unBan(asQuery(userUUID)); - } - - @Override - public CompletableFuture unBanUser(String userName) { - return unBan(asQuery(userName)); - } - - @Override - public CompletableFuture unBanIpAddress(String ipAddress) { - return unBan(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture mute(EntityId id, Instant endUtc, String reason) { - return mute(asQuery(id), endUtc, reason); - } - - @Override - public CompletableFuture muteUser(UUID userUUID, Instant endUtc, String reason) { - return mute(asQuery(userUUID), endUtc, reason); - } - - @Override - public CompletableFuture muteUser(String userName, Instant endUtc, String reason) { - return mute(asQuery(userName), endUtc, reason); - } - - @Override - public CompletableFuture muteIpAddress(String ipAddress, Instant endUtc, String reason) { - return mute(asQueryForIpAddress(ipAddress), endUtc, reason); - } - - @Override - public CompletableFuture unMute(EntityId id) { - return unMute(asQuery(id)); - } - - @Override - public CompletableFuture unMuteUser(UUID userUUID) { - return unMute(asQuery(userUUID)); - } - - @Override - public CompletableFuture unMuteUser(String userName) { - return unMute(asQuery(userName)); - } - - @Override - public CompletableFuture unMuteIpAddress(String ipAddress) { - return unMute(asQueryForIpAddress(ipAddress)); - } - - @Override - public CompletableFuture setNickName(EntityId id, String nickName) { - return setNickName(asQuery(id), nickName); - } - - @Override - public CompletableFuture setNickNameForUser(UUID userUUID, String nickName) { - return setNickName(asQuery(userUUID), nickName); - } - - @Override - public CompletableFuture setNickNameForUser(String userName, String nickName) { - return setNickName(asQuery(userName), nickName); - } - - @Override - public CompletableFuture deleteNickName(EntityId id) { - return deleteNickName(asQuery(id)); - } - - @Override - public CompletableFuture deleteNickNameForUser(UUID userUUID) { - return deleteNickName(asQuery(userUUID)); - } - - @Override - public CompletableFuture deleteNickNameForUser(String userName) { - return deleteNickName(asQuery(userName)); - } - - @Override - public Function> asQuery(UUID userUUID) { - return txn -> txn.find(getTClass().getSimpleName(), "userUUID", userUUID.toString()); - } - - @Override - public Function> asQuery(String userName) { - return txn -> txn.find(getTClass().getSimpleName(), "userName", userName); - } - - @Override - public Function> asQueryForIpAddress(String ipAddress) { - return txn -> txn.find(getTClass().getSimpleName(), "ipAddress", ipAddress); - } - - @Override - public CompletableFuture ban(Function> query, Instant endUtc, String reason) { - return update(query, e -> { - e.setProperty("banned", true); - e.setProperty("banEndUtcSeconds", endUtc.getEpochSecond()); - e.setProperty("banEndUtcNanos", endUtc.getNano()); - e.setProperty("banReason", reason); - }); - } - - @Override - public CompletableFuture unBan(Function> query) { - return update(query, e -> e.setProperty("banned", false)); - } - - @Override - public CompletableFuture mute(Function> query, Instant endUtc, String reason) { - return update(query, e -> { - e.setProperty("muted", true); - e.setProperty("muteEndUtcSeconds", endUtc.getEpochSecond()); - e.setProperty("muteEndUtcNanos", endUtc.getNano()); - e.setProperty("muteReason", reason); - }); - } - - @Override - public CompletableFuture unMute(Function> query) { - return update(query, e -> e.setProperty("muted", false)); - } - - @Override - public CompletableFuture setNickName(Function> query, String nickName) { - return update(query, e -> e.setProperty("nickName", nickName)); - } - - @Override - public CompletableFuture deleteNickName(Function> query) { - return update(query, e -> e.deleteProperty("nickName")); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/CommonRestrictionService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/CommonRestrictionService.java deleted file mode 100644 index ee60972d6..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/CommonRestrictionService.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.entity; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.anvilpowered.anvil.api.entity.RestrictionCriteria; -import org.anvilpowered.anvil.api.entity.RestrictionService; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -@Singleton -public class CommonRestrictionService implements RestrictionService { - - @Inject - private EntityUtils entityUtils; - - private final Map entityRestrictions; - private final Map uuidRestrictions; - - public CommonRestrictionService() { - entityRestrictions = new HashMap<>(); - uuidRestrictions = new HashMap<>(); - } - - @Override - public void put(Object entity, RestrictionCriteria criteria) { - Optional optionalUUID = entityUtils.extractUUID(entity); - if (optionalUUID.isPresent()) { - // register with UUID instead, we don't want to persist the instances of identifiable entities - put(optionalUUID.get(), criteria); - return; - } - if (criteria.equals(RestrictionCriteria.none())) { - entityRestrictions.remove(entity); - } - entityRestrictions.put(entity, criteria); - } - - @Override - public void put(UUID uuid, RestrictionCriteria criteria) { - if (criteria.equals(RestrictionCriteria.none())) { - uuidRestrictions.remove(uuid); - } - uuidRestrictions.put(uuid, criteria); - } - - @Override - public Optional remove(Object entity) { - Optional optionalUUID = entityUtils.extractUUID(entity); - if (optionalUUID.isPresent()) { - return remove(optionalUUID.get()); - } - return Optional.ofNullable(entityRestrictions.remove(entity)); - } - - @Override - public Optional remove(UUID uuid) { - return Optional.ofNullable(uuidRestrictions.remove(uuid)); - } - - @Override - public RestrictionCriteria get(Object entity) { - Optional optionalUUID = entityUtils.extractUUID(entity); - if (optionalUUID.isPresent()) { - return get(optionalUUID.get()); - } - return entityRestrictions.getOrDefault(entity, RestrictionCriteria.none()); - } - - @Override - public RestrictionCriteria get(UUID uuid) { - return uuidRestrictions.getOrDefault(uuid, RestrictionCriteria.none()); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/misc/CommonBindingExtensions.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/misc/CommonBindingExtensions.java deleted file mode 100644 index 51af0e7eb..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/misc/CommonBindingExtensions.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.misc; - -import com.google.common.reflect.TypeToken; -import com.google.inject.Binder; -import com.google.inject.TypeLiteral; -import dev.morphia.Datastore; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import org.anvilpowered.anvil.api.datastore.Component; -import org.anvilpowered.anvil.api.datastore.DataStoreContext; -import org.anvilpowered.anvil.api.datastore.MongoContext; -import org.anvilpowered.anvil.api.datastore.XodusContext; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.bson.types.ObjectId; - -import java.lang.annotation.Annotation; - -@SuppressWarnings({"unchecked", "UnstableApiUsage"}) -public class CommonBindingExtensions implements BindingExtensions { - - private final Binder binder; - - public CommonBindingExtensions(Binder binder) { - this.binder = binder; - } - - @Override - public , - From2 extends Component, - From3 extends From1, - Target extends From1> - void bind( - TypeToken from1, - TypeToken from2, - TypeToken from3, - TypeToken target, - Annotation componentAnnotation - ) { - binder.bind((TypeLiteral) TypeLiteral.get(from2.getType())) - .annotatedWith(componentAnnotation) - .to(BindingExtensions.getTypeLiteral(target)); - - binder.bind((TypeLiteral) TypeLiteral.get(from3.getType())) - .to(BindingExtensions.getTypeLiteral(target)); - } - - @Override - public , - From2 extends From1, - Target extends From1> - void bind( - TypeToken from1, - TypeToken from2, - TypeToken target, - Annotation componentAnnotation - ) { - bind(from1, from1, from2, target, componentAnnotation); - } - - @Override - public void bind( - TypeToken from, - TypeToken target, - Annotation annotation - ) { - binder.bind(BindingExtensions.getTypeLiteral(from)) - .annotatedWith(annotation) - .to(BindingExtensions.getTypeLiteral(target)); - } - - @Override - public void bind( - TypeToken from, - TypeToken target, - Class annotation - ) { - binder.bind(BindingExtensions.getTypeLiteral(from)) - .annotatedWith(annotation) - .to(BindingExtensions.getTypeLiteral(target)); - } - - @Override - public void bind( - TypeToken from, - TypeToken target - ) { - binder.bind(BindingExtensions.getTypeLiteral(from)) - .to(BindingExtensions.getTypeLiteral(target)); - } - - @Override - public void withMongoDB() { - binder.bind(new TypeLiteral>() { - }).to(MongoContext.class); - } - - @Override - public void withXodus() { - binder.bind(new TypeLiteral>() { - }).to(XodusContext.class); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/MongoCoreMember.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/MongoCoreMember.java deleted file mode 100644 index eea648529..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/MongoCoreMember.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.model.coremember; - -import dev.morphia.annotations.Entity; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.base.model.MongoDbo; -import org.bson.types.ObjectId; - -import java.time.Instant; -import java.util.UUID; - -@Entity("coreMembers") -public class MongoCoreMember extends MongoDbo implements CoreMember { - - private UUID userUUID; - private String userName; - private String ipAddress; - private Instant lastJoinedUtc; - private String nickName; - private boolean banned; - private boolean muted; - private Instant banEndUtc; - private Instant muteEndUtc; - private String banReason; - private String muteReason; - - @Override - public UUID getUserUUID() { - return userUUID; - } - - @Override - public void setUserUUID(UUID userUUID) { - this.userUUID = userUUID; - } - - @Override - public String getUserName() { - return userName; - } - - @Override - public void setUserName(String userName) { - this.userName = userName; - } - - @Override - public String getIpAddress() { - return ipAddress; - } - - @Override - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - @Override - public Instant getLastJoinedUtc() { - return lastJoinedUtc; - } - - @Override - public void setLastJoinedUtc(Instant lastJoinedUtc) { - this.lastJoinedUtc = lastJoinedUtc; - } - - @Override - public String getNickName() { - return nickName; - } - - @Override - public void setNickName(String nickName) { - this.nickName = nickName; - } - - @Override - public boolean isBanned() { - return banned; - } - - @Override - public void setBanned(boolean banned) { - this.banned = banned; - } - - @Override - public boolean isMuted() { - return muted; - } - - @Override - public void setMuted(boolean muted) { - this.muted = muted; - } - - @Override - public Instant getBanEndUtc() { - return banEndUtc; - } - - @Override - public void setBanEndUtc(Instant banEndUtc) { - this.banEndUtc = banEndUtc; - } - - @Override - public Instant getMuteEndUtc() { - return muteEndUtc; - } - - @Override - public void setMuteEndUtc(Instant muteEndUtc) { - this.muteEndUtc = muteEndUtc; - } - - @Override - public String getBanReason() { - return banReason; - } - - @Override - public void setBanReason(String banReason) { - this.banReason = banReason; - } - - @Override - public String getMuteReason() { - return muteReason; - } - - @Override - public void setMuteReason(String muteReason) { - this.muteReason = muteReason; - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/XodusCoreMember.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/XodusCoreMember.java deleted file mode 100644 index cc7771f32..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/model/coremember/XodusCoreMember.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.model.coremember; - -import jetbrains.exodus.entitystore.Entity; -import jetbrains.exodus.entitystore.EntityId; -import org.anvilpowered.anvil.api.datastore.XodusEntity; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.base.model.XodusDbo; - -import java.time.Instant; -import java.util.UUID; - -@XodusEntity -public class XodusCoreMember extends XodusDbo implements CoreMember { - - private String userUUID; - private String userName; - private String ipAddress; - private long lastJoinedUtcSeconds; - private int lastJoinedUtcNanos; - private String nickName; - private boolean banned; - private boolean muted; - private long banEndUtcSeconds; - private int banEndUtcNanos; - private long muteEndUtcSeconds; - private int muteEndUtcNanos; - private String banReason; - private String muteReason; - - @Override - public UUID getUserUUID() { - return UUID.fromString(userUUID); - } - - @Override - public void setUserUUID(UUID userUUID) { - this.userUUID = userUUID.toString(); - } - - @Override - public String getUserName() { - return userName; - } - - @Override - public void setUserName(String userName) { - this.userName = userName; - } - - @Override - public String getIpAddress() { - return ipAddress; - } - - @Override - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - @Override - public Instant getLastJoinedUtc() { - return Instant.ofEpochSecond(lastJoinedUtcSeconds, lastJoinedUtcNanos); - } - - @Override - public void setLastJoinedUtc(Instant lastJoinedUtc) { - lastJoinedUtcSeconds = lastJoinedUtc.getEpochSecond(); - lastJoinedUtcNanos = lastJoinedUtc.getNano(); - } - - @Override - public String getNickName() { - return nickName; - } - - @Override - public void setNickName(String nickName) { - this.nickName = nickName; - } - - @Override - public boolean isBanned() { - return banned; - } - - @Override - public void setBanned(boolean banned) { - this.banned = banned; - } - - @Override - public boolean isMuted() { - return muted; - } - - @Override - public void setMuted(boolean muted) { - this.muted = muted; - } - - @Override - public Instant getBanEndUtc() { - return Instant.ofEpochSecond(banEndUtcSeconds, banEndUtcNanos); - } - - @Override - public void setBanEndUtc(Instant banEndUtc) { - banEndUtcSeconds = banEndUtc.getEpochSecond(); - banEndUtcNanos = banEndUtc.getNano(); - } - - @Override - public Instant getMuteEndUtc() { - return Instant.ofEpochSecond(muteEndUtcSeconds, muteEndUtcNanos); - } - - @Override - public void setMuteEndUtc(Instant muteEndUtc) { - muteEndUtcSeconds = muteEndUtc.getEpochSecond(); - muteEndUtcNanos = muteEndUtc.getNano(); - } - - @Override - public String getBanReason() { - return banReason; - } - - @Override - public void setBanReason(String banReason) { - this.banReason = banReason; - } - - @Override - public String getMuteReason() { - return muteReason; - } - - @Override - public void setMuteReason(String muteReason) { - this.muteReason = muteReason; - } - - @Override - public Entity writeTo(Entity object) { - super.writeTo(object); - if (userUUID != null) { - object.setProperty("userUUID", userUUID); - } - if (userName != null) { - object.setProperty("userName", userName); - } - if (ipAddress != null) { - object.setProperty("ipAddress", ipAddress); - } - object.setProperty("lastJoinedUtcSeconds", lastJoinedUtcSeconds); - object.setProperty("lastJoinedUtcNanos", lastJoinedUtcNanos); - if (nickName != null) { - object.setProperty("nickname", nickName); - } - object.setProperty("banned", banned); - object.setProperty("muted", muted); - object.setProperty("banEndUtcSeconds", banEndUtcSeconds); - object.setProperty("banEndUtcNanos", banEndUtcNanos); - object.setProperty("muteEndUtcSeconds", muteEndUtcSeconds); - object.setProperty("muteEndUtcNanos", muteEndUtcNanos); - if (banReason != null) { - object.setProperty("banReason", banReason); - } - if (muteReason != null) { - object.setProperty("muteReason", muteReason); - } - return object; - } - - @Override - public void readFrom(Entity object) { - super.readFrom(object); - Comparable userUUID = object.getProperty("userUUID"); - if (userUUID instanceof String) { - this.userUUID = (String) userUUID; - } - Comparable userName = object.getProperty("userName"); - if (userName instanceof String) { - this.userName = (String) userName; - } - Comparable ipAddress = object.getProperty("ipAddress"); - if (ipAddress instanceof String) { - this.ipAddress = (String) ipAddress; - } - Comparable lastJoinedUtcSeconds = object.getProperty("lastJoinedUtcSeconds"); - if (lastJoinedUtcSeconds instanceof Long) { - this.lastJoinedUtcSeconds = (Long) lastJoinedUtcSeconds; - } - Comparable lastJoinedUtcNanos = object.getProperty("lastJoinedUtcNanos"); - if (lastJoinedUtcNanos instanceof Integer) { - this.lastJoinedUtcNanos = (Integer) lastJoinedUtcNanos; - } - Comparable nickName = object.getProperty("nickName"); - if (nickName instanceof String) { - this.nickName = (String) nickName; - } - Comparable banned = object.getProperty("banned"); - if (banned instanceof Boolean) { - this.banned = (Boolean) banned; - } - Comparable muted = object.getProperty("muted"); - if (muted instanceof Boolean) { - this.muted = (Boolean) muted; - } - Comparable banEndUtcSeconds = object.getProperty("banEndUtcSeconds"); - if (banEndUtcSeconds instanceof Long) { - this.banEndUtcSeconds = (Long) banEndUtcSeconds; - } - Comparable banEndUtcNanos = object.getProperty("banEndUtcNanos"); - if (banEndUtcNanos instanceof Integer) { - this.banEndUtcNanos = (Integer) banEndUtcNanos; - } - Comparable muteEndUtcSeconds = object.getProperty("muteEndUtcSeconds"); - if (muteEndUtcSeconds instanceof Long) { - this.muteEndUtcSeconds = (Long) muteEndUtcSeconds; - } - Comparable muteEndUtcNanos = object.getProperty("muteEndUtcNanos"); - if (muteEndUtcNanos instanceof Integer) { - this.muteEndUtcNanos = (Integer) muteEndUtcNanos; - } - Comparable banReason = object.getProperty("banReason"); - if (banReason instanceof String) { - this.banReason = (String) banReason; - } - Comparable muteReason = object.getProperty("muteReason"); - if (muteReason instanceof String) { - this.muteReason = (String) muteReason; - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/ApiCommonModule.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/ApiCommonModule.java deleted file mode 100644 index d3d6d68db..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/ApiCommonModule.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.module; - -import com.google.inject.AbstractModule; -import org.anvilpowered.anvil.api.entity.RestrictionService; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.util.TimeFormatService; -import org.anvilpowered.anvil.common.entity.CommonRestrictionService; -import org.anvilpowered.anvil.common.util.CommonTimeFormatService; - -public class ApiCommonModule extends AbstractModule { - - @Override - protected void configure() { - bind(TimeFormatService.class).to(CommonTimeFormatService.class); - bind(RestrictionService.class).toProvider( - BindingExtensions.asInternalProvider(CommonRestrictionService.class)); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/CommonModule.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/CommonModule.java deleted file mode 100644 index 0bbc1b113..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/CommonModule.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.module; - -import com.google.common.reflect.TypeToken; -import com.google.inject.name.Names; -import dev.morphia.Datastore; -import jetbrains.exodus.entitystore.EntityId; -import jetbrains.exodus.entitystore.PersistentEntityStore; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.coremember.CoreMemberRepository; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.plugin.BasicPluginInfo; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.plugin.PluginMessages; -import org.anvilpowered.anvil.api.registry.ConfigurationService; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.base.registry.BaseExtendedRegistry; -import org.anvilpowered.anvil.common.coremember.CommonCoreMemberManager; -import org.anvilpowered.anvil.common.coremember.CommonMongoCoreMemberRepository; -import org.anvilpowered.anvil.common.coremember.CommonXodusCoreMemberRepository; -import org.anvilpowered.anvil.common.misc.CommonBindingExtensions; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.common.plugin.AnvilPluginMessages; -import org.anvilpowered.anvil.common.registry.CommonConfigurationService; -import org.bson.types.ObjectId; - -@SuppressWarnings("UnstableApiUsage") -public class CommonModule extends ApiCommonModule { - - @Override - protected void configure() { - - BindingExtensions be = new CommonBindingExtensions(binder()); - - be.bind(new TypeToken>(getClass()) { - }, new TypeToken>(getClass()) { - }); - - be.bind(new TypeToken(getClass()) { - }, new TypeToken>(getClass()) { - }); - - be.bind(new TypeToken>(getClass()) { - }, new TypeToken>(getClass()) { - }); - - be.bind( - new TypeToken>() { - }, - new TypeToken>() { - }, - new TypeToken() { - }, - Names.named("mongodb") - ); - - be.bind( - new TypeToken>() { - }, - new TypeToken>() { - }, - new TypeToken() { - }, - Names.named("xodus") - ); - - bind(CoreMemberManager.class).to(CommonCoreMemberManager.class); - - be.withMongoDB(); - be.withXodus(); - - bind(Registry.class).to(BaseExtendedRegistry.class); - - bind(ConfigurationService.class).to(CommonConfigurationService.class); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/JavaUtilLoggingAdapter.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/JavaUtilLoggingAdapter.java deleted file mode 100644 index cb2286cf4..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/JavaUtilLoggingAdapter.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.module; - -import com.google.inject.Binder; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Environment; -import org.slf4j.Marker; -import org.slf4j.helpers.FormattingTuple; -import org.slf4j.helpers.MarkerIgnoringBase; -import org.slf4j.helpers.MessageFormatter; -import org.slf4j.spi.LocationAwareLogger; - -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -/** - * @author Jacob Allen - */ -public class JavaUtilLoggingAdapter extends MarkerIgnoringBase implements LocationAwareLogger { - - @Inject - private Logger logger; - - private final String name; - - public static void bindLogger(Environment environment, Binder binder) { - binder.bind(org.slf4j.Logger.class).toInstance(new JavaUtilLoggingAdapter(environment.getName())); - } - - public JavaUtilLoggingAdapter(String name) { - this.name = name; - } - - private void log(Level level, String message, Throwable throwable) { - String color; - switch (level.getName()) { - case "WARNING": - color = "\033[0;33m"; // Yellow - break; - case "SEVERE": - color = "\033[0;31m"; // Red - break; - default: - color = ""; - break; - } - - String message0 = color + message + "\033[0m"; //Always reset the color - LogRecord record = new LogRecord(level, message0); - record.setLoggerName(name); - record.setThrown(throwable); - logger.log(record); - } - - @Override - public boolean isTraceEnabled() { - return logger.isLoggable(Level.FINEST); - } - - @Override - public void trace(String message) { - if (isTraceEnabled()) { - log(Level.FINEST, message, null); - } - } - - @Override - public void trace(String format, Object arg) { - if (isTraceEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg); - log(Level.FINEST, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void trace(String format, Object arg1, Object arg2) { - if (isTraceEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg1, arg2); - log(Level.FINEST, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void trace(String format, Object... arguments) { - if (isTraceEnabled()) { - FormattingTuple tuple = MessageFormatter.arrayFormat(format, arguments); - log(Level.FINEST, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void trace(String message, Throwable throwable) { - if (isTraceEnabled()) { - log(Level.FINEST, message, throwable); - } - } - - @Override - public boolean isDebugEnabled() { - return logger.isLoggable(Level.FINE); - } - - @Override - public void debug(String message) { - if (isDebugEnabled()) { - log(Level.FINE, message, null); - } - } - - @Override - public void debug(String format, Object arg) { - if (isDebugEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg); - log(Level.FINE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void debug(String format, Object arg1, Object arg2) { - if (isDebugEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg1, arg2); - log(Level.FINE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void debug(String format, Object... arguments) { - if (isDebugEnabled()) { - FormattingTuple tuple = MessageFormatter.arrayFormat(format, arguments); - log(Level.FINE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void debug(String message, Throwable throwable) { - if (isDebugEnabled()) { - log(Level.FINE, message, throwable); - } - } - - @Override - public boolean isInfoEnabled() { - return logger.isLoggable(Level.INFO); - } - - @Override - public void info(String message) { - if (isInfoEnabled()) { - log(Level.INFO, message, null); - } - } - - @Override - public void info(String format, Object arg) { - if (isInfoEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg); - log(Level.INFO, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void info(String format, Object arg1, Object arg2) { - if (isInfoEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg1, arg2); - log(Level.INFO, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void info(String format, Object... arguments) { - if (isInfoEnabled()) { - FormattingTuple tuple = MessageFormatter.arrayFormat(format, arguments); - log(Level.INFO, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void info(String message, Throwable throwable) { - if (isInfoEnabled()) { - log(Level.INFO, message, throwable); - } - } - - @Override - public boolean isWarnEnabled() { - return logger.isLoggable(Level.WARNING); - } - - @Override - public void warn(String message) { - if (isWarnEnabled()) { - log(Level.WARNING, message, null); - } - } - - @Override - public void warn(String format, Object arg) { - if (isWarnEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg); - log(Level.WARNING, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void warn(String format, Object... arguments) { - if (isWarnEnabled()) { - FormattingTuple tuple = MessageFormatter.arrayFormat(format, arguments); - log(Level.WARNING, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void warn(String format, Object arg1, Object arg2) { - if (isWarnEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg1, arg2); - log(Level.WARNING, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void warn(String message, Throwable throwable) { - if (isWarnEnabled()) { - log(Level.WARNING, message, throwable); - } - } - - @Override - public boolean isErrorEnabled() { - return logger.isLoggable(Level.SEVERE); - } - - @Override - public void error(String message) { - if (isErrorEnabled()) { - log(Level.SEVERE, message, null); - } - } - - @Override - public void error(String format, Object arg) { - if (isErrorEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg); - log(Level.SEVERE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void error(String format, Object arg1, Object arg2) { - if (isErrorEnabled()) { - FormattingTuple tuple = MessageFormatter.format(format, arg1, arg2); - log(Level.SEVERE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void error(String format, Object... arguments) { - if (isErrorEnabled()) { - FormattingTuple tuple = MessageFormatter.arrayFormat(format, arguments); - log(Level.SEVERE, tuple.getMessage(), tuple.getThrowable()); - } - } - - @Override - public void error(String message, Throwable throwable) { - if (isErrorEnabled()) { - log(Level.SEVERE, message, throwable); - } - } - - @Override - public void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable throwable) { - Level level0; - switch (level) { - case LocationAwareLogger.TRACE_INT: - level0 = Level.FINEST; - break; - case LocationAwareLogger.DEBUG_INT: - level0 = Level.FINE; - break; - case LocationAwareLogger.INFO_INT: - level0 = Level.INFO; - break; - case LocationAwareLogger.WARN_INT: - level0 = Level.WARNING; - break; - case LocationAwareLogger.ERROR_INT: - level0 = Level.SEVERE; - break; - default: - throw new IllegalStateException(level + " is not a supported logging level!"); - } - if (logger.isLoggable(level0)) { - log(level0, message, throwable); - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/PlatformModule.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/PlatformModule.java deleted file mode 100644 index c51646320..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/module/PlatformModule.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.module; - -import org.anvilpowered.anvil.api.Platform; - -public class PlatformModule extends ApiCommonModule { - - private final Platform platform; - - public PlatformModule(Platform platform) { - this.platform = platform; - } - - public Platform getPlatform() { - return platform; - } - - @Override - protected void configure() { - super.configure(); - bind(Platform.class).toInstance(getPlatform()); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginInfo.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginInfo.java deleted file mode 100644 index 8c240680a..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginInfo.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.plugin; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.util.TextService; - -public class AnvilPluginInfo implements PluginInfo { - public static final String id = "anvil"; - public static final String name = "Anvil"; - public static final String version = "$modVersion"; - public static final String description = "A cross-platform Minecraft plugin framework"; - public static final String url = "https://github.com/AnvilPowered/Anvil"; - public static final String organizationName = "AnvilPowered"; - public static final String[] authors = {organizationName}; - public static final String buildDate = "$buildDate"; - public TString pluginPrefix; - - @Inject - public void setPluginPrefix(TextService textService) { - pluginPrefix = textService.builder().blue().append("[").aqua().append(name).blue().append("] ").build(); - } - - @Override - public String getId() { - return id; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getVersion() { - return version; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public String getUrl() { - return url; - } - - @Override - public String[] getAuthors() { - return authors; - } - - @Override - public String getOrganizationName() { - return organizationName; - } - - @Override - public String getBuildDate() { - return buildDate; - } - - @Override - public TString getPrefix() { - return pluginPrefix; - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginMessages.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginMessages.java deleted file mode 100644 index 28429fffb..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/plugin/AnvilPluginMessages.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.plugin; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.plugin.PluginMessages; -import org.anvilpowered.anvil.api.util.TextService; -import org.anvilpowered.anvil.api.util.TimeFormatService; - -import java.time.Duration; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; - -public class AnvilPluginMessages implements PluginMessages { - - @Inject - protected PluginInfo pluginInfo; - - @Inject - protected TextService textService; - - @Inject - protected TimeFormatService timeFormatService; - - @Override - public TString getBanMessage(String reason, Instant endUtc) { - return textService.builder() - .red().append("You have been banned for: ", textService.deserialize(reason)) - .yellow().append("\n\nFor another ", timeFormatService.format(Duration.between(OffsetDateTime.now(ZoneOffset.UTC).toInstant(), endUtc))) - .append("\n\nUntil ", timeFormatService.format(endUtc)) - .build(); - } - - @Override - public TString getMuteMessage(String reason, Instant endUtc) { - return textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("You have been muted for: ", textService.deserialize(reason)) - .yellow().append("\nFor another ", timeFormatService.format(Duration.between(OffsetDateTime.now(ZoneOffset.UTC).toInstant(), endUtc))) - .build(); - } - - @Override - public TString getNoPermission() { - return textService.builder() - .append(pluginInfo.getPrefix()) - .red().append("You do not have permission for this command!") - .build(); - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTextService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTextService.java deleted file mode 100644 index c214ec835..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTextService.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.util; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.Platform; -import org.anvilpowered.anvil.api.plugin.PluginInfo; -import org.anvilpowered.anvil.api.util.TextService; -import org.anvilpowered.anvil.common.command.CommonCallbackCommand; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public abstract class CommonTextService - implements TextService { - - @Inject - private Platform platform; - - @Inject - private PluginInfo pluginInfo; - - @Inject - protected CommonCallbackCommand callbackCommand; - - @Override - public TString success(String s) { - return builder().green().append(s).build(); - } - - @Override - public TString fail(String s) { - return builder().red().append(s).build(); - } - - @Override - public PaginationBuilder paginationBuilder() { - return new CommonExtendedPaginationBuilder(); - } - - @Override - public void send(TString text, TCommandSource receiver, UUID sourceUUID) { - send(text, receiver); - } - - @Override - public void send(TString text, TCommandSource receiver, Object source) { - send(text, receiver); - } - - @Override - public String toPlain(String text) { - return text.replaceAll("&[0-9a-fklmnor]", ""); - } - - private static final Pattern LINE_BREAK_PATTERN = Pattern.compile("\r\n|\r|\n"); - - @Override - public int lineCount(TString text) { - if (text == null) { - return -1; - } - String s = serializePlain(text); - if (s.isEmpty()) { - return 0; - } - Matcher m = LINE_BREAK_PATTERN.matcher(s); - int lines = 1; - while (m.find()) { - lines++; - } - return lines; - } - - protected abstract class CommonTextBuilder - implements Builder { - - @Nullable - protected Consumer callback; - - @Override - public Builder append(CharSequence... contents) { - return append((Object[]) contents); - } - - @Override - public Builder appendCount( - int count, Object... contents) { - for (int i = 0; i < count; i++) { - append(contents); - } - return this; - } - - @Override - public Builder appendCount( - int count, CharSequence... contents) { - for (int i = 0; i < count; i++) { - append(contents); - } - return this; - } - - protected Builder appendWithPadding( - @Nullable BiConsumer before, - @Nullable BiConsumer after, - int width, Object padding, Object... contents) { - if (width < 1) { - throw new IllegalArgumentException("Width must be at least 1"); - } - final TString paddingText = of(padding); - final int paddingLength = length(paddingText); - if (paddingLength < 1) { - throw new IllegalArgumentException("Padding length must be at least 1"); - } else if (width < paddingLength) { - throw new IllegalArgumentException("Padding length must not be greater than width"); - } - final TString contentsText = of(contents); - final int contentsLength = length(contentsText); - if (width < contentsLength) { - throw new IllegalArgumentException("Contents length must not be greater than width"); - } - int missingSpace = (width - contentsLength) / paddingLength; - boolean add = missingSpace != 0; - if (add && before != null) { - before.accept(missingSpace, paddingText); - } - append(contentsText); - if (add && after != null) { - after.accept(missingSpace, paddingText); - } - return this; - } - - @Override - public Builder appendWithPaddingLeft(int width, Object padding, Object... contents) { - return appendWithPadding(this::appendCount, null, width, padding, contents); - } - - @Override - public Builder appendWithPaddingLeft(int width, Object padding, CharSequence... contents) { - return appendWithPaddingLeft(width, padding, (Object[]) contents); - } - - @Override - public Builder appendWithPaddingAround(int width, Object padding, Object... contents) { - BiConsumer bothEnds = (m, c) -> appendCount(m / 2, c); - return appendWithPadding(bothEnds, bothEnds, width, padding, contents); - } - - @Override - public Builder appendWithPaddingAround(int width, Object padding, CharSequence... contents) { - return appendWithPaddingAround(width, padding, (Object[]) contents); - } - - @Override - public Builder appendWithPaddingRight(int width, Object padding, Object... contents) { - return appendWithPadding(null, this::appendCount, width, padding, contents); - } - - @Override - public Builder appendWithPaddingRight(int width, Object padding, CharSequence... contents) { - return appendWithPaddingRight(width, padding, (Object[]) contents); - } - - @Override - public Builder appendIf( - boolean condition, Object... contents) { - return condition ? append(contents) : this; - } - - @Override - public Builder appendIf( - boolean condition, CharSequence... contents) { - return condition ? append(contents) : this; - } - - @Override - public Builder appendJoining( - Object delimiter, CharSequence... contents) { - return appendJoining(delimiter, (Object[]) contents); - } - - @Override - public Builder appendJoiningIf( - boolean condition, Object delimiter, Object... contents) { - return condition ? appendJoining(delimiter, contents) : this; - } - - @Override - public Builder appendJoiningIf( - boolean condition, Object delimiter, CharSequence... contents) { - return condition ? appendJoining(delimiter, contents) : this; - } - - @Override - public Builder appendPrefix() { - return append(pluginInfo.getPrefix()); - } - - @Override - public Builder onHoverShowText( - Builder builder) { - return onHoverShowText(builder.build()); - } - - @Override - public Builder onClickExecuteCallback( - Consumer callback) { - this.callback = callback; - return this; - } - - protected void initializeCallback() { - UUID uuid = UUID.randomUUID(); - callbackCommand.addCallback(uuid, callback); - String platform = Anvil.getPlatform().getName(); - String command; - switch (platform) { - case "bungee": - command = "/anvilb:callback "; - break; - case "velocity": - command = "/anvilv:callback "; - break; - default: - command = "/anvil:callback "; - break; - } - onClickRunCommand(command + uuid); - } - - @Override - public void sendTo(TCommandSource receiver) { - send(build(), receiver); - } - - @Override - public void sendToConsole() { - CommonTextService.this.sendToConsole(build()); - } - } - - protected abstract class CommonPaginationBuilder - implements PaginationBuilder { - - @Override - public PaginationBuilder title( - @Nullable Builder title) { - if (title == null) { - return title((TString) null); - } - return title(title.build()); - } - - @Override - public PaginationBuilder header( - @Nullable Builder header) { - if (header == null) { - return header((TString) null); - } - return header(header.build()); - } - - @Override - public PaginationBuilder footer( - @Nullable Builder footer) { - if (footer == null) { - return footer((TString) null); - } - return footer(footer.build()); - } - - @Override - public PaginationBuilder padding( - Builder padding) { - return padding(padding.build()); - } - } - - protected class CommonExtendedPaginationBuilder - extends CommonPaginationBuilder { - - List contents; - @Nullable - TString title; - @Nullable - TString header; - @Nullable - TString footer; - TString padding; - int linesPerPage; - - public CommonExtendedPaginationBuilder() { - padding = builder().dark_green().append("-").build(); - linesPerPage = 20; - } - - @Override - public PaginationBuilder contents( - TString... contents) { - this.contents = Arrays.asList(contents); - return this; - } - - @Override - public PaginationBuilder contents( - Iterable contents) { - this.contents = new ArrayList<>(64); - contents.forEach(c -> this.contents.add(c)); - return this; - } - - @Override - public PaginationBuilder title( - @Nullable TString title) { - this.title = title; - return this; - } - - @Override - public PaginationBuilder header( - @Nullable TString header) { - this.header = header; - return this; - } - - @Override - public PaginationBuilder footer( - @Nullable TString footer) { - this.footer = footer; - return this; - } - - @Override - public PaginationBuilder padding( - TString padding) { - this.padding = padding; - return this; - } - - @Override - public PaginationBuilder linesPerPage( - int linesPerPage) { - if (linesPerPage < 1) { - throw new IllegalArgumentException("Lines per page must be at least 1"); - } - this.linesPerPage = linesPerPage; - return this; - } - - @Override - public Pagination build() { - return new CommonExtendedPagination( - contents, - title, - header, - footer, - padding, - linesPerPage - ); - } - } - - protected class CommonExtendedPagination - implements Pagination { - - protected final List contents; - - @Nullable - protected final TString title; - - @Nullable - protected final TString header; - - @Nullable - protected final TString footer; - - protected final TString padding; - - protected final int linesPerPage; - - @Nullable - protected List pages; - - protected CommonExtendedPagination( - List contents, - @Nullable TString title, - @Nullable TString header, - @Nullable TString footer, - TString padding, - int linesPerPage - ) { - this.contents = Preconditions.checkNotNull(contents, "contents"); - this.title = title; - this.header = header; - this.footer = footer; - this.padding = Preconditions.checkNotNull(padding, "padding"); - this.linesPerPage = linesPerPage; - } - - @Override - public Iterable getContents() { - return contents; - } - - @Override - public Optional getTitle() { - return Optional.ofNullable(title); - } - - @Override - public Optional getHeader() { - return Optional.ofNullable(header); - } - - @Override - public Optional getFooter() { - return Optional.ofNullable(footer); - } - - @Override - public TString getPadding() { - return padding; - } - - @Override - public int getLinesPerPage() { - return linesPerPage; - } - - protected void buildPages() { - final int LINE_WIDTH; - if (platform.getName().equals("sponge")) { - LINE_WIDTH = 91; - } else { - LINE_WIDTH = 51; - } - pages = new ArrayList<>(); - int contentsIndex = 0; // index in contents list - final int contentsSize = contents.size(); - boolean isFirstPage = true; - outer: - while (contentsIndex < contentsSize) { - Builder page = builder(); - int linesAvailable = linesPerPage - 1; - if (title != null) { - page.appendWithPaddingAround(LINE_WIDTH, ' ', title).append("\n"); - linesAvailable -= lineCount(title); - } - if (header != null) { - page.appendWithPaddingAround(LINE_WIDTH, ' ', header).append("\n"); - linesAvailable -= lineCount(header); - } else { - page.appendWithPaddingAround(LINE_WIDTH, padding).append("\n"); - } - boolean withFooter = false; - if (footer != null) { - // reserve space for footer - // will be added later - withFooter = true; - linesAvailable -= lineCount(footer); - } - for (; linesAvailable > 0; --linesAvailable) { - // check if there are any contents left - if (contentsIndex >= contentsSize) { - // dont add empty lines on first page - if (isFirstPage) { - break; - } - // no more content, add an empty line - page.append("\n"); - } - TString next = contents.get(contentsIndex); - // make sure there's enough space - if (linesAvailable < lineCount(next)) { - continue outer; - } - page.append(next, "\n"); - ++contentsIndex; - } - if (isFirstPage) { - isFirstPage = false; - } - if (withFooter) { - page.appendWithPaddingAround(LINE_WIDTH, padding, footer); - } else { - page.appendWithPaddingAround(LINE_WIDTH, padding); - } - pages.add(page.build()); - } - } - - @Override - public void sendTo(TCommandSource receiver) { - if (pages == null) { - buildPages(); - } - if (pages.size() == 0) { - return; - } - send(pages.get(0), receiver); - } - - @Override - public void sendToConsole() { - sendTo(getConsole()); - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTimeFormatService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTimeFormatService.java deleted file mode 100644 index 2a374ed68..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonTimeFormatService.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.util; - -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.util.TimeFormatService; - -import java.time.DateTimeException; -import java.time.Duration; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.TemporalAccessor; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class CommonTimeFormatService implements TimeFormatService { - - private static final long SECONDS_IN_YEAR = 31536000; - private static final long SECONDS_IN_MONTH = 2628000; - private static final long SECONDS_IN_WEEK = 604800; - private static final long SECONDS_IN_DAY = 86400; - private static final long SECONDS_IN_HOUR = 3600; - private static final long SECONDS_IN_MINUTE = 60; - - private static final DateTimeFormatter[] dateTimeFormat = { - DateTimeFormatter.ofPattern("ss").withZone(ZoneOffset.UTC), - DateTimeFormatter.ofPattern("mm:ss").withZone(ZoneOffset.UTC), - DateTimeFormatter.ofPattern("HH:mm:ss").withZone(ZoneOffset.UTC), - DateTimeFormatter.ofPattern("dd-HH:mm:ss").withZone(ZoneOffset.UTC), - DateTimeFormatter.ofPattern("MM-dd-HH:mm:ss").withZone(ZoneOffset.UTC), - DateTimeFormatter.ofPattern("uuuu-MM-dd-HH:mm:ss").withZone(ZoneOffset.UTC) - }; - - private static final DateTimeFormatter[] dateTimeFormatZoned = dateTimeFormat.clone(); - - private static final Pattern timePattern = Pattern.compile( - "\\s*((?-?[0-9]*)\\s*[yY])?" + - "\\s*((?-?[0-9]*)\\s*M)?" + - "\\s*((?-?[0-9]*)\\s*[wW])?" + - "\\s*((?-?[0-9]*)\\s*[dD])?" + - "\\s*((?-?[0-9]*)\\s*[hH])?" + - "\\s*((?-?[0-9]*)\\s*m)?" + - "\\s*((?-?[0-9]*)\\s*[sS])?\\s*" - ); - - private static DateTimeFormatter getZonedFormatter(int index) { - DateTimeFormatter result = dateTimeFormatZoned[index]; - ZoneId zone = getZone(); - if (result.getZone().equals(zone)) { - return result; - } - return dateTimeFormatZoned[index] = dateTimeFormat[index].withZone(zone); - } - - private static ZoneId getZone() { - return Anvil.getRegistry().getOrDefault(Keys.TIME_ZONE); - } - - private static Instant utcNow() { - return OffsetDateTime.now(ZoneOffset.UTC).toInstant(); - } - - @Override - public long parseSecondsUnsafe(String input) { - Matcher matcher = timePattern.matcher(input); - if (!matcher.matches()) { - throw new IllegalStateException("Input does not match"); - } - return Optional.ofNullable(matcher.group("years")) - .map(g -> Long.parseLong(g) * SECONDS_IN_YEAR).orElse(0L) - + Optional.ofNullable(matcher.group("months")) - .map(g -> Long.parseLong(g) * SECONDS_IN_MONTH).orElse(0L) - + Optional.ofNullable(matcher.group("weeks")) - .map(g -> Long.parseLong(g) * SECONDS_IN_WEEK).orElse(0L) - + Optional.ofNullable(matcher.group("days")) - .map(g -> Long.parseLong(g) * SECONDS_IN_DAY).orElse(0L) - + Optional.ofNullable(matcher.group("hours")) - .map(g -> Long.parseLong(g) * SECONDS_IN_HOUR).orElse(0L) - + Optional.ofNullable(matcher.group("minutes")) - .map(g -> Long.parseLong(g) * SECONDS_IN_MINUTE).orElse(0L) - + Optional.ofNullable(matcher.group("seconds")) - .map(Long::parseLong).orElse(0L); - } - - @Override - public Optional parseSeconds(String input) { - try { - return Optional.of(parseSecondsUnsafe(input)); - } catch (NumberFormatException | IndexOutOfBoundsException | IllegalStateException ignored) { - return Optional.empty(); - } - } - - @Override - public Duration parseDurationUnsafe(String input) { - return Duration.ofSeconds(parseSecondsUnsafe(input)); - } - - @Override - public Optional parseDuration(String input) { - return parseSeconds(input).map(Duration::ofSeconds); - } - - @Override - public Instant parseFutureInstantUnsafe(String input) { - return utcNow().plusSeconds(parseSecondsUnsafe(input)); - } - - @Override - public Optional parseFutureInstant(String input) { - return parseSeconds(input).map(s -> utcNow().plusSeconds(s)); - } - - @Override - public Instant parseInstantUnsafe(String input) { - return Instant.from(getZonedFormatter(5).parse(input)); - } - - @Override - public Optional parseInstant(String input) { - try { - return Optional.of(parseInstantUnsafe(input)); - } catch (DateTimeException | NullPointerException ignored) { - return Optional.empty(); - } - } - - @Override - public ZonedDateTime fromUTC(Instant instant) { - return instant.atZone(getZone()); - } - - @Override - public FormatResult format(Duration duration) { - return new DurationFormatResult(duration); - } - - @Override - public FormatResult format(TemporalAccessor temporal) { - return new TemporalFormatResult(temporal); - } - - @Override - public FormatResult formatDurationUnsafe(String input) { - return format(parseDurationUnsafe(input)); - } - - @Override - public Optional formatDuration(String input) { - return parseDuration(input).map(this::format); - } - - @Override - public FormatResult formatInstantUnsafe(String input) { - return format(parseInstantUnsafe(input)); - } - - @Override - public Optional formatInstant(String input) { - return parseInstant(input).map(this::format); - } - - private static final class DurationFormatResult implements FormatResult { - - private final Duration duration; - int maxCharacters; - int maxUnits; - boolean withoutNano; - - private DurationFormatResult(Duration duration) { - this.duration = duration; - maxCharacters = -1; - maxUnits = -1; - withoutNano = false; - } - - @Override - public FormatResult maxCharacters(int maxCharacters) { - this.maxCharacters = maxCharacters; - return this; - } - - @Override - public FormatResult maxUnits(int maxUnits) { - this.maxUnits = maxUnits; - return this; - } - - @Override - public FormatResult withoutNano() { - withoutNano = true; - return this; - } - - @Override - public String toString() { - if (maxCharacters == 0 || maxUnits == 0) { - return ""; - } - StringBuilder s = new StringBuilder(); - long seconds = duration.getSeconds(); - int nanos = duration.getNano(); - if (seconds == 0) { - return nanos > 0 ? nanos + " nanoseconds" : "0 seconds"; - } - long years = seconds / SECONDS_IN_YEAR; - seconds -= SECONDS_IN_YEAR * years; - long months = seconds / SECONDS_IN_MONTH; - seconds -= SECONDS_IN_MONTH * months; - long weeks = seconds / SECONDS_IN_WEEK; - seconds -= SECONDS_IN_WEEK * weeks; - long days = seconds / SECONDS_IN_DAY; - seconds -= SECONDS_IN_DAY * days; - long hours = seconds / SECONDS_IN_HOUR; - seconds -= SECONDS_IN_HOUR * hours; - long minutes = seconds / SECONDS_IN_MINUTE; - seconds -= SECONDS_IN_MINUTE * minutes; - int units = maxUnits < 0 ? Integer.MIN_VALUE : 0; - int maxCharacters = this.maxCharacters < 0 ? Integer.MAX_VALUE : this.maxCharacters; - if (years != 0) { - String t = years + (years == 1 ? " year, " : " years, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (months != 0 && units <= maxUnits) { - String t = months + (months == 1 ? " month, " : " months, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (weeks != 0 && units <= maxUnits) { - String t = weeks + (weeks == 1 ? " week, " : " weeks, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (days != 0 && units <= maxUnits) { - String t = days + (days == 1 ? " day, " : " days, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (hours != 0 && units <= maxUnits) { - String t = hours + (hours == 1 ? " hour, " : " hours, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (minutes != 0 && units <= maxUnits) { - String t = minutes + (minutes == 1 ? " minute, " : " minutes, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (seconds != 0 && units <= maxUnits) { - String t = seconds + (seconds == 1 ? " second, " : " seconds, "); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - ++units; - } - } - if (nanos != 0 && !withoutNano && units <= maxUnits) { - String t = nanos + (nanos == 1 ? " nanosecond" : " nanoseconds"); - if (s.length() + t.length() <= maxCharacters) { - s.append(t); - return s.toString(); - } - } - if (s.length() > 1) { - s.deleteCharAt(s.length() - 1); - s.deleteCharAt(s.length() - 1); - } - return s.toString(); - } - } - - private static final class TemporalFormatResult implements FormatResult { - - private final TemporalAccessor temporal; - int maxUnits; - boolean withoutNano; - - private TemporalFormatResult(TemporalAccessor temporal) { - this.temporal = temporal; - maxUnits = -1; - withoutNano = false; - } - - @Override - public FormatResult maxCharacters(int maxCharacters) { - if (maxCharacters < 0 || maxCharacters > 18) { - maxUnits = -1; - } else if (maxCharacters > 13) { - maxUnits = 5; - } else if (maxCharacters > 10) { - maxUnits = 4; - } else if (maxCharacters > 7) { - maxUnits = 3; - } else if (maxCharacters > 4) { - maxUnits = 2; - } else if (maxCharacters > 1) { - maxUnits = 1; - } else { - maxUnits = 0; - } - return this; - } - - @Override - public FormatResult maxUnits(int maxUnits) { - this.maxUnits = maxUnits; - return this; - } - - @Override - public FormatResult withoutNano() { - return this; - } - - @Override - public String toString() { - if (maxUnits == 0) { - return ""; - } - if (maxUnits < 0 || maxUnits > 6) { - return getZonedFormatter(5).format(temporal); - } - return getZonedFormatter(maxUnits - 1).format(temporal); - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonUserService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonUserService.java deleted file mode 100644 index 0ef27ca50..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/CommonUserService.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.util; - -import com.google.common.collect.ImmutableList; -import org.anvilpowered.anvil.api.Anvil; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.api.util.UserService; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -@SuppressWarnings("unchecked") -public abstract class CommonUserService implements UserService { - - private static final UUID constant = UUID.nameUUIDFromBytes(new byte[0]); - - private final Class userClass; - - protected CommonUserService(Class userClass) { - this.userClass = userClass; - } - - @Override - public List matchPlayerNames(String[] context, int index, int length) { - if (context.length == length) { - return matchPlayerNames(context[index]); - } - return ImmutableList.of(); - } - - @Override - public CompletableFuture> getUUID(String userName) { - return Anvil.getCoreMemberRepository() - .getOneForUser(userName).thenApplyAsync(c -> c.map(CoreMember::getUserUUID)); - } - - @Override - public CompletableFuture> getUserName(UUID userUUID) { - return Anvil.getCoreMemberRepository() - .getOneForUser(userUUID).thenApplyAsync(c -> c.map(CoreMember::getUserName)); - } - - @Override - public UUID getUUIDSafe(Object object) { - if (userClass.isInstance(object)) { - return getUUID((TUser) object); - } else { - return constant; - } - } -} diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/StringTextService.java b/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/StringTextService.java deleted file mode 100644 index d0c123506..000000000 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/util/StringTextService.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.util; - -import java.net.URL; -import java.util.function.Consumer; - -public abstract class StringTextService - extends CommonTextService { - - @Override - public String deserialize(String text) { - return text; - } - - @Override - public String serializePlain(String text) { - return toPlain(text); - } - - @Override - public String serialize(String text) { - return text; - } - - protected class StringTextBuilder extends CommonTextBuilder { - protected final StringBuilder elements; - - public StringTextBuilder() { - elements = new StringBuilder(); - } - - @Override - public Builder aqua() { - elements.append("\u00a7b"); - return this; - } - - @Override - public Builder black() { - elements.append("\u00a70"); - return this; - } - - @Override - public Builder blue() { - elements.append("\u00a79"); - return this; - } - - @Override - public Builder dark_aqua() { - elements.append("\u00a73"); - return this; - } - - @Override - public Builder dark_blue() { - elements.append("\u00a71"); - return this; - } - - @Override - public Builder dark_gray() { - elements.append("\u00a78"); - return this; - } - - @Override - public Builder dark_green() { - elements.append("\u00a72"); - return this; - } - - @Override - public Builder dark_purple() { - elements.append("\u00a75"); - return this; - } - - @Override - public Builder dark_red() { - elements.append("\u00a74"); - return this; - } - - @Override - public Builder gold() { - elements.append("\u00a76"); - return this; - } - - @Override - public Builder gray() { - elements.append("\u00a77"); - return this; - } - - @Override - public Builder green() { - elements.append("\u00a7a"); - return this; - } - - @Override - public Builder light_purple() { - elements.append("\u00a7d"); - return this; - } - - @Override - public Builder red() { - elements.append("\u00a7c"); - return this; - } - - @Override - public Builder reset() { - elements.append("\u00a7r"); - return this; - } - - @Override - public Builder white() { - elements.append("\u00a7f"); - return this; - } - - @Override - public Builder yellow() { - elements.append("\u00a7e"); - return this; - } - - @Override - public Builder bold() { - elements.append("\u00a7l"); - return this; - } - - @Override - public Builder italic() { - elements.append("\u00a7o"); - return this; - } - - @Override - public Builder obfuscated() { - elements.append("\u00a7k"); - return this; - } - - @Override - public Builder strikethrough() { - elements.append("\u00a7m"); - return this; - } - - @Override - public Builder underlined() { - elements.append("\u00a7n"); - return this; - } - - @Override - public Builder append(Object... contents) { - for (Object o : contents) { - if (o instanceof Builder) { - elements.append(((Builder) o).build()); - } else { - elements.append(o); - } - } - return this; - } - - @Override - public Builder appendJoining(Object delimiter, Object... contents) { - if (delimiter instanceof Builder) { - delimiter = ((Builder) delimiter).build(); - } - final int indexOfLast = contents.length - 1; - for (int i = 0; i <= indexOfLast; i++) { - Object o = contents[i]; - if (o instanceof Builder) { - elements.append(((Builder) o).build()); - } else { - elements.append(o); - } - if (i != indexOfLast) { - elements.append(delimiter); - } - } - return this; - } - - @Override - public Builder onHoverShowText(String content) { - return this; - } - - @Override - public Builder onClickSuggestCommand(String command) { - return this; - } - - @Override - public Builder onClickRunCommand(String command) { - return this; - } - - @Override - public Builder onClickExecuteCallback(Consumer callback) { - return this; - } - - @Override - public Builder onClickOpenUrl(URL url) { - return this; - } - - @Override - public Builder onClickOpenUrl(String url) { - return this; - } - - @Override - public String build() { - return elements.toString(); - } - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Change.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Change.kt deleted file mode 100644 index b1d6db12c..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Change.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.common.command.regedit - -import org.anvilpowered.anvil.api.registry.Key -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.api.util.TextService - -class Change( - private val registry: Registry, - private val textService: TextService, - val key: Key, - var newValue: T? = null, -) { - - private val remove: TString by lazy { - textService.builder() - .red().append("[R]") - .onHoverShowText(textService.builder() - .red().append("Remove this change\n") - .gray().append("/$alias regedit key $key unstage") - ).onClickRunCommand("/$alias regedit key $key unstage") - .build() - } - - constructor(stage: Stage, key: Key, newValue: T? = null) - : this(stage.registry.second, stage.textService, key, newValue) - - fun apply(registry: Registry) { - registry.set(key, newValue) - } - - fun print(): TString { - return textService.builder() - .append(remove, " ") - .gold().append(key.name, " > ") - .append(textService.printValueYellow(key, registry.get(key).orElse(null))) - .gray().append(" -> ") - .append(textService.printValueGreen(key, newValue)) - .build() - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditBaseCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditBaseCommand.kt deleted file mode 100644 index 1fa19401b..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditBaseCommand.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject -import org.anvilpowered.anvil.api.plugin.PluginInfo -import org.anvilpowered.anvil.api.plugin.PluginMessages -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.api.util.PermissionService -import org.anvilpowered.anvil.api.util.TextService -import org.anvilpowered.anvil.api.util.UserService - -open class CommonRegistryEditBaseCommand { - - @Inject - protected lateinit var registry: Registry - - @Inject - protected lateinit var permissionService: PermissionService - - @Inject - protected lateinit var pluginInfo: PluginInfo - - @Inject - protected lateinit var pluginMessages: PluginMessages - - @Inject - protected lateinit var textService: TextService - - @Inject - protected lateinit var userService: UserService - - fun testPermission(source: Any?): Boolean { - return permissionService.hasPermission(source ?: return false, registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - fun hasNoPerms(source: TCommandSource): Boolean { - if (!testPermission(source)) { - textService.send(pluginMessages.noPermission, source) - return true - } - return false - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCancelCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCancelCommand.kt deleted file mode 100644 index f4b3447ac..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCancelCommand.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject - -open class CommonRegistryEditCancelCommand - : CommonRegistryEditBaseCommand() { - - @Inject - private lateinit var registryEditRootCommand: CommonRegistryEditRootCommand - - fun execute(source: TCommandSource, context: Array? = null) { - if (hasNoPerms(source)) return - val builder = textService.builder().append(pluginInfo.prefix) - val removed = registryEditRootCommand.stages.remove(userService.getUUIDSafe(source)) - if (removed == null) { - builder.red().append("Could not find stage") - } else { - builder.green().append("Successfully cancelled changes. Didn't mean to? ") - .append(textService.undo("/$alias regedit start ${removed.envName}")) - }.sendTo(source) - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommandNode.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommandNode.kt deleted file mode 100644 index de50cff47..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommandNode.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject -import org.anvilpowered.anvil.api.Environment -import org.anvilpowered.anvil.api.command.CommandNode -import org.anvilpowered.anvil.api.command.CommandService -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.common.command.CommonAnvilCommandNode -import java.util.function.Function -import java.util.function.Predicate - -abstract class CommonRegistryEditCommandNode( - val registry: Registry, -) : CommandNode { - - companion object { - val CANCEL_ALIAS = listOf("cancel") - val COMMIT_ALIAS = listOf("commit") - val KEY_ALIAS = listOf("key") - val SELECT_ALIAS = listOf("select") - val START_ALIAS = listOf("start") - val HELP_ALIAS = listOf("help") - - const val CANCEL_DESCRIPTION = "Cancel a stage" - const val COMMIT_DESCRIPTION = "Commit changes" - const val KEY_DESCRIPTION = "Do stuff with a key" - const val SELECT_DESCRIPTION = "Select a registry" - const val START_DESCRIPTION = "Start a regedit with the specified environment" - const val ROOT_DESCRIPTION = "Root regedit command" - - const val KEY_USAGE = " [info|set|unset|unstage] []" - const val SELECT_USAGE = "" - const val START_USAGE = "" - - const val REGEDIT = "regedit" - lateinit var PATH: Array - } - - private var alreadyLoaded = false - private val descriptions: MutableMap, Function> = HashMap() - private val permissions: MutableMap, Predicate> = HashMap() - private val usages: MutableMap, Function> = HashMap() - - @Inject - protected lateinit var commandService: CommandService - - @Inject - protected lateinit var environment: Environment - - init { - registry.whenLoaded { - if (alreadyLoaded) return@whenLoaded - PATH = arrayOf(CommonAnvilCommandNode.getAlias()) - loadCommands() - alreadyLoaded = true - }.order(-10).register() // has to load before main node - descriptions.put(CANCEL_ALIAS) { CANCEL_DESCRIPTION } - descriptions.put(COMMIT_ALIAS) { COMMIT_DESCRIPTION } - descriptions.put(KEY_ALIAS) { KEY_DESCRIPTION } - descriptions.put(SELECT_ALIAS) { SELECT_DESCRIPTION } - descriptions.put(START_ALIAS) { START_DESCRIPTION } - usages.put(KEY_ALIAS) { KEY_USAGE } - usages.put(SELECT_ALIAS) { SELECT_USAGE } - usages.put(START_ALIAS) { START_USAGE } - } - - protected abstract fun loadCommands() - override fun getName(): String = REGEDIT - override fun getDescriptions(): Map, Function> = descriptions - override fun getPermissions(): Map, Predicate> = permissions - override fun getUsages(): Map, Function> = usages - override fun getPath(): Array = PATH -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommitCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommitCommand.kt deleted file mode 100644 index 06f4dc9e6..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditCommitCommand.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject - -open class CommonRegistryEditCommitCommand - : CommonRegistryEditBaseCommand() { - - @Inject - private lateinit var registryEditRootCommand: CommonRegistryEditRootCommand - - fun execute(source: TCommandSource, context: Array? = null) { - if (hasNoPerms(source)) return - val uuid = userService.getUUIDSafe(source) - val stage = registryEditRootCommand.stages[uuid] - if (stage == null) { - textService.send(registryEditRootCommand.notInStage, source) - return - } - if (stage.commit(source)) { - registryEditRootCommand.stages.remove(uuid) - } - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditKeyCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditKeyCommand.kt deleted file mode 100644 index f4649bd6c..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditKeyCommand.kt +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject -import org.anvilpowered.anvil.api.registry.Key -import org.anvilpowered.anvil.api.registry.Keys -import kotlin.streams.toList - -open class CommonRegistryEditKeyCommand - : CommonRegistryEditBaseCommand() { - - @Inject - private lateinit var registryEditRootCommand: CommonRegistryEditRootCommand - - private val keyActions = listOf("info", "set", "unset", "unstage") - - private val usage: TString by lazy { - textService.builder() - .red().append("Usage: /$alias regedit key [info|set|unset|unstage] []") - .build() - } - - private val setUsage: TString by lazy { - textService.builder() - .append(pluginInfo.prefix) - .red().append("Value required for set subcommand. Usage: /$alias regedit key set ") - .build() - } - - private fun unknownKey(keyName: String) = textService.builder() - .append(pluginInfo.prefix) - .red().append("Unknown key: ") - .gold().append(keyName) - .build() - - private fun String.resolveKey(envName: String): Key? { - return Keys.resolveLocalAndGlobal(this, envName).orElse(null) - } - - open fun execute(source: TCommandSource, context: Array) { - if (hasNoPerms(source)) return - val stage = registryEditRootCommand.stages[userService.getUUIDSafe(source)] - if (stage == null) { - textService.send(registryEditRootCommand.notInStage, source) - return - } - textService.send(when (context.size) { - 0, 1 -> usage - 2 -> when (val key = context[0].resolveKey(stage.envName)) { - null -> unknownKey(context[0]) - else -> when (context[1]) { - "info" -> stage.info(key) - "set" -> setUsage - "unset" -> stage.addChange(key) - "unstage" -> stage.unstageChange(key) - else -> usage - } - } - 3 -> when (val key = context[0].resolveKey(stage.envName)) { - null -> unknownKey(context[0]) - else -> when (context[1]) { - "set" -> { - try { - stage.addChange(key, key.parse(context[2])) - } catch (e: Exception) { - textService.builder() - .append(pluginInfo.prefix) - .red().append("Error: ", e.message) - .build() - } - } - "info", "unset", "unstage" -> textService.builder() - .append(pluginInfo.prefix) - .red().append("Too many args for ${context[1]}! ", usage) - .build() - else -> usage - } - } - else -> usage - }, source) - } - - open fun suggest(source: TCommandSource, context: Array): List { - if (!testPermission(source)) return listOf() - val stage = registryEditRootCommand.stages[userService.getUUIDSafe(source)] ?: return listOf() - return when (context.size) { - 1 -> Keys.getAll(stage.envName).keys.stream().filter { it.startsWith(context[0]) }.toList() - 2 -> keyActions.stream().filter { it.startsWith(context[1]) }.toList() - else -> listOf() - } - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditRootCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditRootCommand.kt deleted file mode 100644 index c67c54202..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditRootCommand.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import java.util.UUID - -open class CommonRegistryEditRootCommand - : CommonRegistryEditBaseCommand() { - - val stages: MutableMap> = HashMap() - - val notInStage: TString by lazy { - textService.builder() - .append(pluginInfo.prefix) - .red().append("You are not currently in a regedit session. Use /$alias regedit help") - .build() - } - - fun execute(source: TCommandSource, context: Array? = null) { - if (hasNoPerms(source)) return - textService.send(stages[userService.getUUIDSafe(source)]?.print() ?: notInStage, source) - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditSelectCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditSelectCommand.kt deleted file mode 100644 index f09609a80..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditSelectCommand.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject -import kotlin.streams.toList - -open class CommonRegistryEditSelectCommand - : CommonRegistryEditBaseCommand() { - - @Inject - private lateinit var registryEditRootCommand: CommonRegistryEditRootCommand - - private val usage: TString by lazy { - textService.builder() - .append(pluginInfo.prefix) - .red().append("Please provide exactly one argument!\nUsage: /$alias regedit select ") - .build() - } - - open fun execute(source: TCommandSource, context: Array) { - if (hasNoPerms(source)) return - val uuid = userService.getUUIDSafe(source) - val stage = registryEditRootCommand.stages[uuid] - textService.send(when { - stage == null -> registryEditRootCommand.notInStage - context.size == 1 -> stage.setRegistry(context[0]) - else -> usage - }, source) - } - - open fun suggest(source: TCommandSource, context: Array): List { - if (!testPermission(source)) return listOf() - val stage = registryEditRootCommand.stages[userService.getUUIDSafe(source)] ?: return listOf() - return when (context.size) { - 1 -> stage.registries.keys.stream().filter { it.startsWith(context[0]) }.toList() - else -> listOf() - } - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditStartCommand.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditStartCommand.kt deleted file mode 100644 index b893dc09e..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/CommonRegistryEditStartCommand.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.anvilpowered.anvil.api.Anvil -import org.anvilpowered.anvil.api.Environment -import org.anvilpowered.anvil.api.registry.ConfigurationService -import org.anvilpowered.anvil.api.registry.Registry -import java.util.stream.Collectors -import java.util.stream.Stream -import kotlin.streams.toList - -open class CommonRegistryEditStartCommand - : CommonRegistryEditBaseCommand() { - - @Inject - private lateinit var registryEditRootCommand: CommonRegistryEditRootCommand - - private val envRegs: MutableMap> = HashMap() - - private val environments: Stream - get() = Anvil.getEnvironmentManager() - .environments.values.stream() - .map { it.name } - .sorted() - - private val environmentsPrinted: String - get() = Anvil.getEnvironmentManager() - .environments.values.stream() - .map { it.name } - .sorted().collect(Collectors.joining(", ")) - - private fun parseEnv(envName: String?): Environment? { - return Anvil.getEnvironmentManager().getEnvironment(envName).orElse(null) - } - - private fun parseEnv(envName: String?, then: (Environment) -> TString): TString { - return parseEnv(envName)?.let { then(it) } - ?: textService.builder() - .append(pluginInfo.prefix) - .red().append("Could not find environment ") - .gold().append(envName) - .build() - } - - private fun Environment.getRegistries(): Map { - return envRegs[name] ?: run { - val registries: MutableMap = HashMap() - val main = injector.getInstance(Registry::class.java) - val config = injector.getInstance(ConfigurationService::class.java) - for ((key, value) in injector.bindings) { - if (key.typeLiteral.type == Registry::class) { - val reg = value.provider.get() as? Registry ?: continue - if (reg !== main && reg !== config) { - registries[(key.annotation as? Named)?.value ?: continue] = reg - } - } - } - registries["main"] = main - registries["config"] = config - envRegs[name] = registries - return registries - } - } - - open fun execute(source: TCommandSource, context: Array) { - if (hasNoPerms(source)) return - if (context.isEmpty()) { - textService.builder() - .append(pluginInfo.prefix) - .red().append("Please select an environment. Usage: /$alias regedit select \n") - .append("Available environments: ").gold().append(environmentsPrinted) - .sendTo(source) - return - } - textService.send(parseEnv(context[0]) { - val newStage = Stage(context[0], it.getRegistries().toMutableMap(), - it.getPluginInfo(), textService) - registryEditRootCommand.stages[userService.getUUIDSafe(source)] = newStage - newStage.print() - }, source) - } - - open fun suggest(source: TCommandSource, context: Array): List { - if (!testPermission(source)) return listOf() - return when (context.size) { - 1 -> environments.filter { it.startsWith(context[0]) }.toList() - else -> listOf() - } - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/RegEdit.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/RegEdit.kt deleted file mode 100644 index cb17dd9ad..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/RegEdit.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.command.regedit - -import org.anvilpowered.anvil.api.registry.Key -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.api.util.TextService -import org.anvilpowered.anvil.common.command.CommonAnvilCommandNode - -val alias by lazy { CommonAnvilCommandNode.getAlias()!! } - -val whitespace = "\\s+".toRegex() - -fun TextService.undo(cmd: String): TString { - return builder() - .light_purple().append("[ Undo ]") - .onHoverShowText(builder() - .light_purple().append("Undo this action\n") - .gray().append(cmd) - ).onClickRunCommand(cmd) - .build() -} - -fun TextService.info(key: Key, registry: Registry): TString { - return builder() - .gold().append(key, " >").gray() - .append("\nValue: ", printValueYellow(key, registry.get(key).orElse(null))) - .append("\nDefault: ", printValueYellow(key, registry.getDefault(key))) - .append("\nFallback: ", printValueYellow(key, key.fallbackValue)) - .build() -} - -fun TextService.printValueGreen(key: Key, value: T?): TString { - if (value == null) { - return builder().red().append("none").build() - } - val primary = key.toString(value) - val secondary = value.toString() - val builder = builder().green().append(primary) - if (primary != secondary) { - builder.gray().append(" (", secondary, ")") - } - return builder.build() -} - -fun TextService.printValueYellow(key: Key, value: T?): TString { - if (value == null) { - return builder().red().append("none").build() - } - val primary = key.toString(value) - val secondary = value.toString() - val builder = builder().yellow().append(primary) - if (primary != secondary) { - builder.gray().append(" (", secondary, ")") - } - return builder.build() -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Stage.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Stage.kt deleted file mode 100644 index 9f077e5c5..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/command/regedit/Stage.kt +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.common.command.regedit - -import org.anvilpowered.anvil.api.plugin.PluginInfo -import org.anvilpowered.anvil.api.registry.ConfigurationService -import org.anvilpowered.anvil.api.registry.Key -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.api.util.TextService - -class Stage( - val envName: String, - val registries: MutableMap, - val pluginInfo: PluginInfo, - val textService: TextService, -) { - - lateinit var registry: Pair - - private val changes: MutableList> = ArrayList() - private val availableRegistries: TString - - private val border = textService.builder() - .dark_gray().appendCount(15, '=') - .append(" [ ").gold().append("Anvil RegEdit") - .dark_gray().append(" ] ").appendCount(15, '=') - .build() - - private val view = textService.builder() - .aqua().append("[ Key ]") - .onHoverShowText(textService.builder() - .aqua().append("Key\n") - .gray().append("/$alias regedit key [info|set|unset|unstage]") - ).onClickSuggestCommand("/$alias regedit key ") - .build() - - private val cancel = textService.builder() - .red().append("[ Cancel ]") - .onHoverShowText(textService.builder() - .red().append("Cancel\n") - .gray().append("/$alias regedit cancel") - ).onClickRunCommand("/$alias regedit cancel") - .build() - - private val commit = textService.builder() - .gold().append("[ Commit ]") - .onHoverShowText(textService.builder() - .gold().append("Commit\n") - .gray().append("/$alias regedit commit") - ).onClickRunCommand("/$alias regedit commit") - .build() - - private val noSuchChange = textService.builder() - .append(pluginInfo.prefix) - .red().append("Could not find change") - .build() - - private val selectRegistry = textService.builder() - .append(pluginInfo.prefix) - .red().append("You must select a registry") - .build() - - private val sensitive = textService.builder() - .append(pluginInfo.prefix) - .red().append("This key is sensitive and may only be viewed or edited if ") - .gold().append("server.regeditAllowSensitive ") - .red().append("is enabled in the config") - .build() - - private val userImmutable = textService.builder() - .append(pluginInfo.prefix) - .red().append("This key is user immutable and may not be edited with the regedit command") - .build() - - fun setRegistry(name: String?): TString { - val newReg = when (name) { - null, "internal", "r", "registry" -> Pair("main", registries["main"]) - "c" -> Pair("config", registries["config"]) - else -> Pair(name, registries[name]) - } - return if (newReg.second == null) { - textService.fail("Could not find registry $name") - } else { - registry = Pair(newReg.first, newReg.second!!) - print() - } - } - - init { - val builder = textService.builder().aqua() - // reference equality, we want to check specifically for the same instance - // if these are the same, don't show [ Internal ] and [ Config ] separately - if (registries["main"] !== registries["config"]) { - builder.append(textService.builder() - .aqua().append("[ Internal ]") - .onHoverShowText(textService.builder() - .aqua().append("The main registry\n") - .gray().append("/$alias regedit select internal") - ).onClickRunCommand("/$alias regedit select internal") - ).append(" ") - } - builder.append(textService.builder() - .aqua().append("[ Config ]") - .onHoverShowText(textService.builder() - .aqua().append("The configuration\n") - .gray().append("/$alias regedit select config") - ).onClickRunCommand("/$alias regedit select config") - ) - for ((name, _) in registries) { - if (name == "main" || name == "config") { - continue - } - val cmd = "/$alias regedit select $name" - builder.append(" ", textService.builder() - .aqua().append("[ ", name, " ]") - .onHoverShowText(textService.builder() - .aqua().append(name) - .gray().append(cmd) - ).onClickRunCommand(cmd) - ) - } - availableRegistries = builder.build() - } - - fun info(key: Key<*>): TString { - return when { - !::registry.isInitialized -> selectRegistry - else -> when (key.isSensitive(registry.second)) { - true -> sensitive - false -> textService.info(key, registry.second) - } - } - } - - fun commit(source: TCommandSource): Boolean { - if (!::registry.isInitialized) { - textService.send(selectRegistry, source) - return false - } - val reg = registry.second - if (changes.isEmpty()) { - textService.builder() - .append(pluginInfo.prefix) - .red().append("You have no changes!") - .sendTo(source) - return false - } - changes.forEach { it.apply(reg) } - if (reg is ConfigurationService) { - if (reg.save()) { - reg.load() - textService.builder() - .append(pluginInfo.prefix) - .green().append("Successfully committed and saved ") - .gold().append(changes.size) - .green().append(" changes!") - .sendTo(source) - } else { - textService.builder() - .append(pluginInfo.prefix) - .red().append("There was an error saving the config!") - .sendTo(source) - return false - } - } else { - reg.load() - textService.builder() - .append(pluginInfo.prefix) - .green().append("Successfully committed ") - .gold().append(changes.size) - .green().append(" changes!") - .sendTo(source) - } - return true - } - - fun addChange(key: Key, newValue: T? = null): TString { - if (!::registry.isInitialized) { - return selectRegistry - } - if (key.isUserImmutable) { - return userImmutable - } - if (key.isSensitive(registry.second)) { - return sensitive - } - val existing = changes.stream() - .filter { it.key == key } - .findAny().orElse(null) as? Change - val action: String - if (existing == null) { - changes += Change(this, key, newValue) - action = "added" - } else { - existing.newValue = newValue - action = "edited" - } - return print(textService.builder() - .green().append("Successfully $action change for ") - .gold().append(key, " ", textService.undo("/$alias regedit key $key unstage")) - .build()) - } - - fun unstageChange(key: Key): TString { - if (!::registry.isInitialized) { - return selectRegistry - } - val index = changes.indexOfFirst { it.key == key } - if (index == -1) { - return noSuchChange - } - val removed = changes.removeAt(index) as Change - return print(textService.builder() - .green().append("Successfully unstaged change for ") - .gold().append(key, " ", textService.undo("/$alias regedit key $key set ${key.toString(removed.newValue)}")) - .build()) - } - - fun print(message: TString? = null): TString { - if (!::registry.isInitialized) { - return textService.builder() - .append(border, "\n\n") - .green().append("Started a regedit session for ") - .gold().append(pluginInfo.name, "\n\n") - .gray().append("Please select one of the following registries:\n\n", availableRegistries) - .gray().append("\nor ", cancel, "\n\n", border) - .build() - } - val builder = textService.builder() - .append(border, "\n\n") - .appendIf(message != null, message, "\n\n") - .aqua().append("[ ", registry.first, " ]") - .gray().append(" Queued changes:") - if (changes.isEmpty()) { - builder.red().append(" (none)") - } else { - builder.append("\n") - for (change in changes) { - builder.append("\n", change.print()) - } - } - return builder.gray().append("\n\nPlease select an action:\n\n") - .append(view, " ", commit, " ", cancel, "\n\n", border) - .build() - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/module/FallbackModule.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/module/FallbackModule.kt deleted file mode 100644 index e830af85a..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/module/FallbackModule.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.module - -import com.google.common.reflect.TypeToken -import com.google.inject.AbstractModule -import org.anvilpowered.anvil.api.Anvil -import org.anvilpowered.anvil.api.plugin.BasicPluginInfo -import org.anvilpowered.anvil.api.plugin.PluginInfo -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.base.registry.BaseRegistry -import org.anvilpowered.anvil.common.plugin.FallbackPluginInfo - -@Suppress("UnstableApiUsage") -open class FallbackModule : AbstractModule() { - override fun configure() { - val be = Anvil.getBindingExtensions(binder()); - val fallbackPluginInfoToken = object : TypeToken>(javaClass) {} - be.bind(TypeToken.of(BasicPluginInfo::class.java), fallbackPluginInfoToken) - be.bind(object : TypeToken>(javaClass) {}, fallbackPluginInfoToken) - bind(Registry::class.java).to(BaseRegistry::class.java) - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/plugin/FallbackPluginInfo.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/plugin/FallbackPluginInfo.kt deleted file mode 100644 index 4a8a5fe1a..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/plugin/FallbackPluginInfo.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.plugin - -import com.google.inject.Inject -import org.anvilpowered.anvil.api.Environment -import org.anvilpowered.anvil.api.plugin.PluginInfo -import org.anvilpowered.anvil.api.util.TextService - -class FallbackPluginInfo : PluginInfo { - companion object { - const val version = "v0" - const val description = "description" - const val url = "URL" - val authors = arrayOf("author") - const val organizationName = "organizationName" - const val buildDate = "last night" - } - - @Inject - private lateinit var environment: Environment - - lateinit var pluginPrefix: TString - - @Inject - fun setPluginPrefix(textService: TextService) { - pluginPrefix = textService.builder().gold().append("[", name, "] ").build() - } - - override fun getId(): String = environment.name - override fun getName(): String = environment.name - override fun getVersion(): String = Companion.version - override fun getDescription(): String = Companion.description - override fun getUrl(): String = Companion.url - override fun getAuthors(): Array = Companion.authors - override fun getOrganizationName(): String = Companion.organizationName - override fun getBuildDate(): String = Companion.buildDate - override fun getPrefix(): TString = pluginPrefix -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonConfigurationService.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonConfigurationService.kt deleted file mode 100644 index 92f640441..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonConfigurationService.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.common.registry - -import com.google.inject.Inject -import com.google.inject.Singleton -import ninja.leaping.configurate.ConfigurationOptions -import ninja.leaping.configurate.commented.CommentedConfigurationNode -import ninja.leaping.configurate.loader.ConfigurationLoader -import ninja.leaping.configurate.objectmapping.serialize.TypeSerializerCollection -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.base.registry.BaseConfigurationService - -@Singleton -open class CommonConfigurationService @Inject constructor( - configLoader: ConfigurationLoader, -) : BaseConfigurationService(configLoader) { - init { - withDataStoreCore() - withDefault() - withProxyMode() - setName(Keys.REGEDIT_ALLOW_SENSITIVE, "server.regeditAllowSensitive") - setName(Keys.TIME_ZONE, "server.timezone") - setDescription(Keys.REGEDIT_ALLOW_SENSITIVE, """ -Whether the regedit command should have access to sensitive settings such as connection details. -""") - setDescription(Keys.TIME_ZONE, """ -The server's timezone id. Use "auto" for the local system time, otherwise -please see https://nodatime.org/TimeZones (note that your system's available timezones may differ). -This option is useful if your server machine and community are based in different timezones. -""") - val serializers = TypeSerializerCollection.defaults().newChild() - serializers.register(Keys.TIME_ZONE.type, CommonZoneIdSerializer()) - val options = ConfigurationOptions.defaults() - setOptions(options.withSerializers(serializers)) - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonZoneIdSerializer.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonZoneIdSerializer.kt deleted file mode 100644 index bd554e6c5..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/registry/CommonZoneIdSerializer.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.registry - -import com.google.common.reflect.TypeToken -import ninja.leaping.configurate.ConfigurationNode -import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer -import org.anvilpowered.anvil.api.registry.ZoneIdSerializer -import java.time.ZoneId - -@Suppress("UnstableApiUsage") -class CommonZoneIdSerializer : ZoneIdSerializer(), TypeSerializer { - - override fun deserialize(type: TypeToken<*>, node: ConfigurationNode): ZoneId = parse(node.string) - override fun serialize(type: TypeToken<*>, zoneId: ZoneId?, node: ConfigurationNode) { - node.value = toString(zoneId) - } -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonBackendServer.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonBackendServer.kt deleted file mode 100644 index 5034b2a29..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonBackendServer.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.server - -import org.anvilpowered.anvil.api.server.BackendServer -import org.anvilpowered.anvil.api.util.UserService -import java.util.Optional -import java.util.UUID -import java.util.concurrent.CompletableFuture - -abstract class CommonBackendServer( - val userService: UserService, -) : BackendServer { - abstract fun Optional.connect(): CompletableFuture - override fun connect(userUUID: UUID): CompletableFuture = userService.getPlayer(userUUID).connect() - override fun connect(userName: String): CompletableFuture = userService.getPlayer(userName).connect() -} diff --git a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonLocationService.kt b/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonLocationService.kt deleted file mode 100644 index f68e1d580..000000000 --- a/anvil-common/src/main/kotlin/org/anvilpowered/anvil/common/server/CommonLocationService.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.common.server - -import com.flowpowered.math.vector.Vector3d -import org.anvilpowered.anvil.api.server.BackendServer -import org.anvilpowered.anvil.api.server.LocationService -import java.util.Optional -import java.util.UUID -import java.util.concurrent.CompletableFuture - -abstract class CommonLocationService : LocationService { - - override fun getServer(userUUID: UUID): Optional { - return Optional.empty() - } - - override fun getServer(userName: String): Optional { - return Optional.empty() - } - - override fun getServerForName(serverName: String): Optional { - return Optional.empty() - } - - override fun getServers(): List { - return listOf() - } - - override fun getWorldName(userUUID: UUID): Optional { - return Optional.empty() - } - - override fun getWorldName(userName: String): Optional { - return Optional.empty() - } - - override fun getPosition(userUUID: UUID): Optional { - return Optional.empty() - } - - override fun getPosition(userName: String): Optional { - return Optional.empty() - } - - override fun teleport(teleportingUserUUID: UUID, targetUserUUID: UUID): CompletableFuture { - return CompletableFuture.completedFuture(false) - } -} diff --git a/anvil-md5/build.gradle.kts b/anvil-md5/build.gradle.kts deleted file mode 100644 index f4d50d605..000000000 --- a/anvil-md5/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - java -} - -dependencies { - api(project(":anvil-core")) - implementation("net.md-5:bungeecord-api:1.16-R0.4") -} diff --git a/anvil-md5/src/main/java/org/anvilpowered/anvil/md5/util/MD5TextService.java b/anvil-md5/src/main/java/org/anvilpowered/anvil/md5/util/MD5TextService.java deleted file mode 100644 index 4bee8d2bd..000000000 --- a/anvil-md5/src/main/java/org/anvilpowered/anvil/md5/util/MD5TextService.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.md5.util; - -import com.google.inject.Inject; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.common.util.CommonTextService; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; - -import java.net.URL; -import java.util.Deque; -import java.util.LinkedList; - -public abstract class MD5TextService - extends CommonTextService { - - @Inject - private Logger logger; - - @Override - public Builder builder() { - return new MD5TextBuilder(); - } - - @Override - public TextComponent deserialize(String text) { - return new TextComponent(ChatColor.translateAlternateColorCodes('&', text)); - } - - @Override - public String serialize(TextComponent text) { - return text.toLegacyText(); - } - - @Override - public String serializePlain(TextComponent text) { - return text.toPlainText(); - } - - protected class MD5TextBuilder extends CommonTextBuilder { - - private final Deque elements; - @Nullable - private HoverEvent hoverEvent; - @Nullable - private ClickEvent clickEvent; - - protected MD5TextBuilder() { - this.elements = new LinkedList<>(); - } - - @Override - public Builder aqua() { - elements.add(ChatColor.AQUA); - return this; - } - - @Override - public Builder black() { - elements.add(ChatColor.BLACK); - return this; - } - - @Override - public Builder blue() { - elements.add(ChatColor.BLUE); - return this; - } - - @Override - public Builder dark_aqua() { - elements.add(ChatColor.DARK_AQUA); - return this; - } - - @Override - public Builder dark_blue() { - elements.add(ChatColor.DARK_BLUE); - return this; - } - - @Override - public Builder dark_gray() { - elements.add(ChatColor.DARK_GRAY); - return this; - } - - @Override - public Builder dark_green() { - elements.add(ChatColor.DARK_GREEN); - return this; - } - - @Override - public Builder dark_purple() { - elements.add(ChatColor.DARK_PURPLE); - return this; - } - - @Override - public Builder dark_red() { - elements.add(ChatColor.DARK_RED); - return this; - } - - @Override - public Builder gold() { - elements.add(ChatColor.GOLD); - return this; - } - - @Override - public Builder gray() { - elements.add(ChatColor.GRAY); - return this; - } - - @Override - public Builder green() { - elements.add(ChatColor.GREEN); - return this; - } - - @Override - public Builder light_purple() { - elements.add(ChatColor.LIGHT_PURPLE); - return this; - } - - @Override - public Builder red() { - elements.add(ChatColor.RED); - return this; - } - - @Override - public Builder reset() { - elements.add(ChatColor.RESET); - return this; - } - - @Override - public Builder white() { - elements.add(ChatColor.WHITE); - return this; - } - - @Override - public Builder yellow() { - elements.add(ChatColor.YELLOW); - return this; - } - - @Override - public Builder bold() { - elements.add(ChatColor.BOLD); - return this; - } - - @Override - public Builder italic() { - elements.add(ChatColor.ITALIC); - return this; - } - - @Override - public Builder obfuscated() { - elements.add(ChatColor.MAGIC); - return this; - } - - @Override - public Builder strikethrough() { - elements.add(ChatColor.STRIKETHROUGH); - return this; - } - - @Override - public Builder underlined() { - elements.add(ChatColor.UNDERLINE); - return this; - } - - @Override - public Builder append(Object... contents) { - for (Object o : contents) { - if (o instanceof Builder || o instanceof TextComponent || o instanceof ChatColor) { - elements.add(o); - } else { - elements.add(new TextComponent(String.valueOf(o))); - } - } - return this; - } - - @Override - public Builder appendJoining( - Object delimiter, Object... contents) { - final int indexOfLast = contents.length - 1; - for (int i = 0; i <= indexOfLast; i++) { - Object o = contents[i]; - if (o instanceof Builder || o instanceof TextComponent || o instanceof ChatColor) { - elements.add(o); - } else { - elements.add(new TextComponent(String.valueOf(o))); - } - if (i != indexOfLast) { - if (delimiter instanceof Builder || delimiter instanceof TextComponent) { - elements.add(delimiter); - } else { - elements.add(new TextComponent(String.valueOf(delimiter))); - } - } - } - return this; - } - - @Override - public Builder onHoverShowText(TextComponent content) { - hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new ComponentBuilder(content).create()); - return this; - } - - @Override - public Builder onClickSuggestCommand(String command) { - callback = null; - clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command); - return this; - } - - @Override - public Builder onClickRunCommand(String command) { - callback = null; - clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, command); - return this; - } - - @Override - public Builder onClickOpenUrl(String url) { - callback = null; - clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, url); - return this; - } - - @Override - public Builder onClickOpenUrl(URL url) { - return onClickOpenUrl(url.toString()); - } - - @Override - @SuppressWarnings("unchecked") - public TextComponent build() { - boolean hover = hoverEvent != null; - if (callback != null) { - initializeCallback(); - } - boolean click = clickEvent != null; - - if (elements.isEmpty()) { - return new TextComponent(); - } else if (elements.size() == 1 && !hover && !click) { - Object o = elements.getFirst(); - if (o instanceof Builder) { - return ((Builder) o).build(); - } else if (o instanceof TextComponent) { - return (TextComponent) o; - } - } - - // one builder for every color - final Deque components = new LinkedList<>(); - - // create first builder - TextComponent currentBuilder = new TextComponent(); - Object firstColor = elements.peekFirst(); - if (firstColor instanceof ChatColor) { - currentBuilder.setColor((ChatColor) firstColor); - elements.pollFirst(); // remove color because its already added to builder - } - - for (Object o : elements) { - if (o instanceof Builder) { - currentBuilder.addExtra(((Builder) o).build()); - } else if (o instanceof BaseComponent) { - currentBuilder.addExtra((BaseComponent) o); - } else if (o instanceof ChatColor) { - // build current builder - components.offer(currentBuilder); - // create new builder starting at this point until the next color - currentBuilder = new TextComponent(); - currentBuilder.setColor((ChatColor) o); - } else { - logger.error("Skipping {} because it does not match any of the correct types.", o); - } - } - - // build last builder - components.offer(currentBuilder); - - // create new builder with all previous components - currentBuilder = new TextComponent(components.toArray(new BaseComponent[0])); - - if (hover) { - currentBuilder.setHoverEvent(hoverEvent); - } - if (click) { - currentBuilder.setClickEvent(clickEvent); - } - return currentBuilder; - } - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/AnvilSpigot.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/AnvilSpigot.java deleted file mode 100644 index cf905a143..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/AnvilSpigot.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot; - -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; -import org.anvilpowered.anvil.api.AnvilImpl; -import org.anvilpowered.anvil.api.Environment; -import org.anvilpowered.anvil.api.EnvironmentBuilderImpl; -import org.anvilpowered.anvil.api.registry.ConfigurationService; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.spigot.listener.SpigotPlayerListener; -import org.anvilpowered.anvil.spigot.module.ApiSpigotModule; -import org.anvilpowered.anvil.spigot.module.SpigotFallbackModule; -import org.anvilpowered.anvil.spigot.module.SpigotModule; -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.server.ServerLoadEvent; -import org.bukkit.plugin.java.JavaPlugin; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class AnvilSpigot extends JavaPlugin { - - protected final Inner inner; - - public AnvilSpigot() { - AbstractModule module = new AbstractModule() { - @Override - protected void configure() { - bind(JavaPlugin.class).toInstance(AnvilSpigot.this); - bind(AnvilSpigot.class).toInstance(AnvilSpigot.this); - } - }; - Injector injector = Guice.createInjector(module); - inner = new Inner(injector); - } - - private final class Inner extends AnvilImpl { - - public Inner(Injector injector) { - super(injector, new SpigotModule()); - } - - @Override - protected void applyToBuilder(Environment.Builder builder) { - super.applyToBuilder(builder); - builder.addEarlyServices(SpigotPlayerListener.class, t -> - Bukkit.getPluginManager().registerEvents(t, AnvilSpigot.this)); - } - - @Override - protected void whenLoaded(Environment environment) { - super.whenLoaded(environment); - - // Attempt to autodetect proxy mode - boolean serverProxyMode = false; - - // Check for Paper-specific Velocity mode first - try { - Method getPaperConfigMethod = Server.Spigot.class.getMethod("getPaperConfig"); - YamlConfiguration paperConfig = (YamlConfiguration) getPaperConfigMethod - .invoke(Bukkit.spigot()); - serverProxyMode = paperConfig.getBoolean("settings.velocity-support.enabled", false); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Unable to get Paper configuration", e); - } catch (NoSuchMethodException ignored) { - } - - // Check BungeeCord mode if Velocity setting was not enabled or server implementation is not Paper - if (!serverProxyMode) { - serverProxyMode = Bukkit.spigot().getConfig() - .getBoolean("settings.bungeecord", false); - } - - ConfigurationService configurationService = environment.getInjector() - .getInstance(ConfigurationService.class); - boolean anvilProxyMode = configurationService.getOrDefault(Keys.PROXY_MODE); - - if (serverProxyMode && !anvilProxyMode) { - getLogger().error( - "It looks like you are running this server behind a proxy. " + - "If this is the case, set server.proxyMode=true in the anvil config" - ); - } else if (anvilProxyMode && !serverProxyMode) { - getLogger().error( - "It looks like you are not running this server behind a proxy. " + - "If this is the case, set server.proxyMode=false in the anvil config" - ); - } - } - } - - @Override - public void onEnable() { - Bukkit.getPluginManager().registerEvents(new Listener() { - @EventHandler - public void onLoad(ServerLoadEvent event) { - EnvironmentBuilderImpl.completeInitialization(new ApiSpigotModule(), new SpigotFallbackModule()); - } - }, this); - } - - @Override - public String toString() { - return inner.toString(); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilCommandNode.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilCommandNode.java deleted file mode 100644 index 6092ddf4e..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilCommandNode.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.common.command.CommonAnvilCommandNode; -import org.anvilpowered.anvil.spigot.AnvilSpigot; -import org.anvilpowered.anvil.spigot.command.regedit.SpigotRegistryEditCommandNode; -import org.anvilpowered.anvil.spigot.command.regedit.SpigotRegistryEditRootCommand; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.PluginCommand; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class SpigotAnvilCommandNode - extends CommonAnvilCommandNode { - - @Inject - private SpigotAnvilPluginsCommand anvilPluginsCommand; - - @Inject - private SpigotAnvilReloadCommand anvilReloadCommand; - - @Inject - private SpigotCallbackCommand callbackCommand; - - @Inject - private SpigotRegistryEditRootCommand registryEditRootCommand; - - @Inject - private SpigotRegistryEditCommandNode registryEditCommandNode; - - @Inject - private AnvilSpigot plugin; - - @Inject - public SpigotAnvilCommandNode(Registry registry) { - super(registry); - } - - @Override - protected void loadCommands() { - Map, CommandExecutor> subCommands = new HashMap<>(); - - subCommands.put(PLUGINS_ALIAS, anvilPluginsCommand); - subCommands.put(RELOAD_ALIAS, anvilReloadCommand); - subCommands.put(REGEDIT_ALIAS, commandService.generateRoutingCommand( - registryEditRootCommand, registryEditCommandNode.getSubCommands(), false) - ); - subCommands.put(HELP_ALIAS, commandService.generateHelpCommand(this)); - subCommands.put(VERSION_ALIAS, commandService.generateVersionCommand(HELP_COMMAND)); - - PluginCommand root = plugin.getCommand(getName()); - - Preconditions.checkNotNull(root, "Anvil command not registered"); - - root.setExecutor(commandService.generateRoutingCommand( - commandService.generateRootCommand(HELP_COMMAND), subCommands, false)); - - PluginCommand callback = plugin.getCommand("callback"); - - Preconditions.checkNotNull(callback, "Callback command not registered"); - - callback.setExecutor(callbackCommand); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilPluginsCommand.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilPluginsCommand.java deleted file mode 100644 index cfef75530..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilPluginsCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.common.command.CommonAnvilPluginsCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -public class SpigotAnvilPluginsCommand - extends CommonAnvilPluginsCommand - implements CommandExecutor { - - @Override - public boolean onCommand( - CommandSender source, - Command command, - String alias, - String[] context - ) { - execute(source); - return true; - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilReloadCommand.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilReloadCommand.java deleted file mode 100644 index f02921f51..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotAnvilReloadCommand.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.common.command.CommonAnvilReloadCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; - -import java.util.List; - -public class SpigotAnvilReloadCommand - extends CommonAnvilReloadCommand - implements CommandExecutor, TabCompleter { - - @Override - public boolean onCommand( - CommandSender source, - Command command, - String alias, - String[] context - ) { - execute(source, context); - return true; - } - - @Override - public List onTabComplete( - CommandSender source, - Command command, - String alias, - String[] context - ) { - return suggest(source, context); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCallbackCommand.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCallbackCommand.java deleted file mode 100644 index 9605ff586..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCallbackCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import com.google.inject.Singleton; -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.common.command.CommonCallbackCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -@Singleton -public class SpigotCallbackCommand - extends CommonCallbackCommand - implements CommandExecutor { - - @Override - public boolean onCommand( - CommandSender source, - Command command, - String alias, - String[] context - ) { - execute(source, context); - return true; - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandExecuteService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandExecuteService.java deleted file mode 100644 index 0a3082f9f..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandExecuteService.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.AnvilImpl; -import org.anvilpowered.anvil.api.command.CommandExecuteService; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; - -public class SpigotCommandExecuteService implements CommandExecuteService { - - @Inject(optional = true) - private Plugin plugin; - - private void executeDirect(String command) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } - - @Override - public void execute(String command) { - if (Bukkit.isPrimaryThread()) { - executeDirect(command); - } else if (plugin != null) { - Bukkit.getScheduler().runTask(plugin, () -> executeDirect(command)); - } else { - AnvilImpl.getLogger() - .error("You must bind org.bukkit.plugin.Plugin to your plugin instance to be able to run commands async"); - } - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandService.java deleted file mode 100644 index 05707b880..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/command/SpigotCommandService.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command; - -import com.google.common.collect.ImmutableList; -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.CommonCommandService; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; - -import java.util.List; -import java.util.function.Predicate; - -public class SpigotCommandService extends CommonCommandService { - - private static class WrapperCommand implements CommandExecutor, TabCompleter { - private final CommandExecutorWrapper wrapper; - - public WrapperCommand(CommandExecutorWrapper wrapper) { - this.wrapper = wrapper; - } - - @Override - public boolean onCommand(CommandSender source, Command command, String label, String[] args) { - wrapper.execute(command, source, label, args); - return true; - } - - @Override - public List onTabComplete(CommandSender source, Command command, String label, String[] args) { - return wrapper.suggest(command, source, label, args); - } - } - - private static abstract class SCommand implements CommandExecutor { - protected final String helpUsage; - protected final Predicate extended; - - public SCommand(String helpUsage, Predicate extended) { - this.helpUsage = helpUsage; - this.extended = extended; - } - } - - private class RootCommand extends SCommand { - - public RootCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public boolean onCommand(CommandSender source, Command command, String label, String[] args) { - sendRoot(source, helpUsage, extended.test(source)); - return true; - } - } - - private class VersionCommand extends SCommand { - - public VersionCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public boolean onCommand(CommandSender source, Command command, String label, String[] args) { - sendVersion(source, helpUsage, extended.test(source)); - return true; - } - } - - private class HelpCommand implements CommandExecutor { - - private final CommandNode node; - - public HelpCommand(CommandNode node) { - this.node = node; - } - - @Override - public boolean onCommand(CommandSender source, Command command, String label, String[] args) { - sendHelp(source, node); - return true; - } - } - - private class ReloadCommand implements CommandExecutor { - - @Override - public boolean onCommand(CommandSender source, Command command, String label, String[] args) { - sendReload(source); - return true; - } - } - - @Override - protected void runExecutor( - CommandExecutor executor, - Command command, - CommandSender source, - String alias, - String[] context - ) { - executor.onCommand(source, command, alias, context); - } - - @Override - protected List getSuggestions( - CommandExecutor executor, - Command command, - CommandSender source, - String alias, - String[] context - ) { - if (executor instanceof TabCompleter) { - return ((TabCompleter) executor).onTabComplete(source, command, alias, context); - } - return ImmutableList.of(); - } - - @Override - protected CommandExecutor generateWrapperCommand(CommandExecutorWrapper command) { - return new WrapperCommand(command); - } - - @Override - public CommandExecutor generateRootCommand(String helpUsage, Predicate extended) { - return new RootCommand(helpUsage, extended); - } - - @Override - public CommandExecutor generateVersionCommand(String helpUsage, Predicate extended) { - return new VersionCommand(helpUsage, extended); - } - - @Override - public CommandExecutor generateHelpCommand(CommandNode node) { - return new HelpCommand(node); - } - - @Override - public CommandExecutor generateReloadCommand() { - return new ReloadCommand(); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/entity/SpigotEntityUtils.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/entity/SpigotEntityUtils.java deleted file mode 100644 index f0240b926..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/entity/SpigotEntityUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.entity; - -import org.anvilpowered.anvil.common.entity.EntityUtils; -import org.bukkit.entity.Entity; - -import java.util.Optional; -import java.util.UUID; - -public class SpigotEntityUtils implements EntityUtils { - - @Override - public Optional extractUUID(Object entity) { - if (!(entity instanceof Entity)) { - return Optional.empty(); - } - return Optional.of(((Entity) entity).getUniqueId()); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/listener/SpigotPlayerListener.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/listener/SpigotPlayerListener.java deleted file mode 100644 index 053b6502e..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/listener/SpigotPlayerListener.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.listener; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.entity.RestrictionService; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityInteractEvent; -import org.bukkit.event.inventory.InventoryInteractEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerMoveEvent; - -public class SpigotPlayerListener implements Listener { - - @Inject - private CoreMemberManager coreMemberManager; - - @Inject - private Registry registry; - - @Inject - private RestrictionService restrictionService; - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - if (registry.getOrDefault(Keys.PROXY_MODE)) { - return; - } - Player player = event.getPlayer(); - coreMemberManager.getPrimaryComponent() - .getOneOrGenerateForUser( - player.getUniqueId(), - player.getName(), - player.getAddress().getHostString() - ); - } - - @EventHandler - public void onMovement(PlayerMoveEvent event) { - if (restrictionService.get(event.getPlayer().getUniqueId()).movement()) { - event.setCancelled(true); - } - } - - @EventHandler - public void onInteraction(EntityInteractEvent event) { - if (restrictionService.get(event.getEntity().getUniqueId()).interaction()) { - event.setCancelled(true); - } - } - - @EventHandler - public void onInventory(InventoryInteractEvent event) { - if (restrictionService.get(event.getWhoClicked().getUniqueId()).inventory()) { - event.setCancelled(true); - } - } - - @EventHandler - public void onCommands(PlayerCommandPreprocessEvent event) { - if (restrictionService.get(event.getPlayer().getUniqueId()).commands()) { - event.setCancelled(true); - } - } - - @EventHandler - public void onReceiveDamage(EntityDamageEvent event) { - if (restrictionService.get(event.getEntity().getUniqueId()).damage()) { - event.setCancelled(true); - } - } - - @EventHandler - public void onDealDamage(EntityDamageByEntityEvent event) { - if (restrictionService.get(event.getDamager().getUniqueId()).damage()) { - event.setCancelled(true); - } - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/ApiSpigotModule.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/ApiSpigotModule.java deleted file mode 100644 index 3dfb361cb..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/ApiSpigotModule.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.module; - -import com.google.inject.TypeLiteral; -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.api.PlatformImpl; -import org.anvilpowered.anvil.api.command.CommandExecuteService; -import org.anvilpowered.anvil.api.command.CommandService; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.server.LocationService; -import org.anvilpowered.anvil.api.util.KickService; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.anvilpowered.anvil.api.util.TextService; -import org.anvilpowered.anvil.api.util.UserService; -import org.anvilpowered.anvil.common.command.CommonCallbackCommand; -import org.anvilpowered.anvil.common.entity.EntityUtils; -import org.anvilpowered.anvil.common.module.JavaUtilLoggingAdapter; -import org.anvilpowered.anvil.common.module.PlatformModule; -import org.anvilpowered.anvil.spigot.command.SpigotCallbackCommand; -import org.anvilpowered.anvil.spigot.command.SpigotCommandExecuteService; -import org.anvilpowered.anvil.spigot.command.SpigotCommandService; -import org.anvilpowered.anvil.spigot.entity.SpigotEntityUtils; -import org.anvilpowered.anvil.spigot.server.SpigotLocationService; -import org.anvilpowered.anvil.spigot.util.SpigotKickService; -import org.anvilpowered.anvil.spigot.util.SpigotPermissionService; -import org.anvilpowered.anvil.spigot.util.SpigotTextService; -import org.anvilpowered.anvil.spigot.util.SpigotUserService; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class ApiSpigotModule extends PlatformModule { - - public ApiSpigotModule() { - super(new PlatformImpl(false, "spigot", JavaUtilLoggingAdapter::bindLogger)); - } - - @Override - protected void configure() { - super.configure(); - bind(new TypeLiteral>() { - }).toProvider(BindingExtensions.asInternalProvider(SpigotCallbackCommand.class)); - bind(CommandExecuteService.class).to(SpigotCommandExecuteService.class); - bind(new TypeLiteral>() { - }).to(SpigotCommandService.class); - bind(KickService.class).to(SpigotKickService.class); - bind(EntityUtils.class).to(SpigotEntityUtils.class); - bind(LocationService.class).to(SpigotLocationService.class); - bind(PermissionService.class).to(SpigotPermissionService.class); - bind(new TypeLiteral>() { - }).to(SpigotTextService.class); - bind(new TypeLiteral>() { - }).to(SpigotUserService.class); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/SpigotModule.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/SpigotModule.java deleted file mode 100644 index 33ed08d97..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/module/SpigotModule.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.module; - -import com.google.inject.TypeLiteral; -import net.md_5.bungee.api.chat.TextComponent; -import ninja.leaping.configurate.commented.CommentedConfigurationNode; -import ninja.leaping.configurate.hocon.HoconConfigurationLoader; -import ninja.leaping.configurate.loader.ConfigurationLoader; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand; -import org.anvilpowered.anvil.common.module.CommonModule; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.spigot.command.SpigotAnvilCommandNode; -import org.anvilpowered.anvil.spigot.command.regedit.SpigotRegistryEditRootCommand; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.io.File; -import java.nio.file.Paths; - -public class SpigotModule extends CommonModule { - - @Override - protected void configure() { - super.configure(); - File configFilesLocation = Paths.get("plugins/" + AnvilPluginInfo.id).toFile(); - if (!configFilesLocation.exists()) { - if (!configFilesLocation.mkdirs()) { - throw new IllegalStateException("Unable to create config directory"); - } - } - bind(new TypeLiteral>() { - }).toInstance(HoconConfigurationLoader.builder().setPath(Paths.get(configFilesLocation + "/anvil.conf")).build()); - bind(new TypeLiteral>() { - }).to(SpigotAnvilCommandNode.class); - bind(new TypeLiteral>() { - }).to(SpigotRegistryEditRootCommand.class); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotKickService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotKickService.java deleted file mode 100644 index fc71b33de..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotKickService.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.util; - -import com.google.inject.Inject; -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.api.util.KickService; -import org.anvilpowered.anvil.api.util.UserService; -import org.bukkit.entity.Player; - -import java.util.UUID; - -public class SpigotKickService implements KickService { - - @Inject - private UserService userService; - - private TextComponent getReason(Object reason) { - return reason instanceof TextComponent ? (TextComponent) reason : new TextComponent(reason.toString()); - } - - @Override - public void kick(UUID userUUID, Object reason) { - userService.getPlayer(userUUID).ifPresent(player -> player.kickPlayer(reason.toString())); - } - - @Override - public void kick(String userName, Object reason) { - userService.getPlayer(userName).ifPresent(player -> player.kickPlayer(reason.toString())); - } - - @Override - public void kick(UUID userUUID) { - kick(userUUID, "You have been kicked"); - } - - @Override - public void kick(String userName) { - kick(userName, "You have been kicked"); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotPermissionService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotPermissionService.java deleted file mode 100644 index 26e68d605..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotPermissionService.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.util; - -import org.anvilpowered.anvil.api.util.PermissionService; -import org.bukkit.permissions.Permissible; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class SpigotPermissionService implements PermissionService { - - @Override - public boolean hasPermission(@Nullable Object subject, String permission) { - return subject instanceof Permissible && ((Permissible) subject).hasPermission(permission); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotTextService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotTextService.java deleted file mode 100644 index 3f48fb24a..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotTextService.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.util; - -import net.md_5.bungee.api.chat.TextComponent; -import org.anvilpowered.anvil.md5.util.MD5TextService; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; - -public class SpigotTextService extends MD5TextService { - - @Override - public void send(TextComponent text, CommandSender receiver) { - receiver.spigot().sendMessage(text); - } - - @Override - public CommandSender getConsole() { - return Bukkit.getConsoleSender(); - } -} diff --git a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotUserService.java b/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotUserService.java deleted file mode 100644 index 1795cbf9c..000000000 --- a/anvil-spigot/src/main/java/org/anvilpowered/anvil/spigot/util/SpigotUserService.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.util; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.common.util.CommonUserService; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class SpigotUserService extends CommonUserService { - - @Inject - public SpigotUserService() { - super(Player.class); - } - - @Override - public Optional get(String userName) { - return Optional.ofNullable(Bukkit.getPlayer(userName)); - } - - @Override - public Optional get(UUID userUUID) { - return Optional.ofNullable(Bukkit.getPlayer(userUUID)); - } - - @Override - public Optional getPlayer(String userName) { - return get(userName); - } - - @Override - public Optional getPlayer(UUID userUUID) { - return get(userUUID); - } - - @Override - public Optional getPlayer(Player player) { - return Optional.of(player); - } - - @Override - public List matchPlayerNames(String startsWith) { - String startsWithLowerCase = startsWith.toLowerCase(); - return Stream.of(Bukkit.getOfflinePlayers()) - .map(OfflinePlayer::getName) - .filter(Objects::nonNull) - .filter(name -> name.toLowerCase().startsWith(startsWithLowerCase)) - .collect(Collectors.toList()); - } - - @Override - public Collection getOnlinePlayers() { - return (Collection) Bukkit.getOnlinePlayers(); - } - - @Override - public CompletableFuture> getUUID(String userName) { - Optional userUUID = getPlayer(userName).map(Player::getUniqueId); - if (userUUID.isPresent()) { - return CompletableFuture.completedFuture(userUUID); - } - return super.getUUID(userName); - } - - @Override - public CompletableFuture> getUserName(UUID userUUID) { - Optional userName = getPlayer(userUUID).map(Player::getName); - if (userName.isPresent()) { - return CompletableFuture.completedFuture(userName); - } - return super.getUserName(userUUID); - } - - @Override - public UUID getUUID(Player user) { - return user.getUniqueId(); - } - - @Override - public String getUserName(Player user) { - return user.getName(); - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCancelCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCancelCommand.kt deleted file mode 100644 index b80da2234..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCancelCommand.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCancelCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class SpigotRegistryEditCancelCommand - : CommonRegistryEditCancelCommand(), CommandExecutor { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommandNode.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommandNode.kt deleted file mode 100644 index 8a8b7313b..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommandNode.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import com.google.inject.Inject -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender - -class SpigotRegistryEditCommandNode @Inject constructor( - registry: Registry, -) : CommonRegistryEditCommandNode(registry) { - - @Inject - private lateinit var registryEditCancelCommand: SpigotRegistryEditCancelCommand - - @Inject - private lateinit var registryEditCommitCommand: SpigotRegistryEditCommitCommand - - @Inject - private lateinit var registryEditKeyCommand: SpigotRegistryEditKeyCommand - - @Inject - private lateinit var registryEditSelectCommand: SpigotRegistryEditSelectCommand - - @Inject - private lateinit var registryEditStartCommand: SpigotRegistryEditStartCommand - - val subCommands: MutableMap, CommandExecutor> = HashMap() - - override fun loadCommands() { - subCommands[CANCEL_ALIAS] = registryEditCancelCommand - subCommands[COMMIT_ALIAS] = registryEditCommitCommand - subCommands[KEY_ALIAS] = registryEditKeyCommand - subCommands[SELECT_ALIAS] = registryEditSelectCommand - subCommands[START_ALIAS] = registryEditStartCommand - subCommands[HELP_ALIAS] = commandService.generateHelpCommand(this) - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommitCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommitCommand.kt deleted file mode 100644 index 7cac09cf6..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditCommitCommand.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommitCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class SpigotRegistryEditCommitCommand - : CommonRegistryEditCommitCommand(), CommandExecutor { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditKeyCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditKeyCommand.kt deleted file mode 100644 index 3d9976adb..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditKeyCommand.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditKeyCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.command.TabCompleter -import org.bukkit.entity.Player - -class SpigotRegistryEditKeyCommand - : CommonRegistryEditKeyCommand(), CommandExecutor, TabCompleter { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } - - override fun onTabComplete(source: CommandSender, command: Command, alias: String, context: Array): List { - return suggest(source, context) - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditRootCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditRootCommand.kt deleted file mode 100644 index 3cf87992c..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditRootCommand.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import com.google.inject.Singleton -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -@Singleton -class SpigotRegistryEditRootCommand - : CommonRegistryEditRootCommand(), CommandExecutor { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditSelectCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditSelectCommand.kt deleted file mode 100644 index b0a5d71f8..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditSelectCommand.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditSelectCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.command.TabCompleter -import org.bukkit.entity.Player - -class SpigotRegistryEditSelectCommand - : CommonRegistryEditSelectCommand(), CommandExecutor, TabCompleter { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } - - override fun onTabComplete(source: CommandSender, command: Command, alias: String, context: Array): List { - return suggest(source, context) - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditStartCommand.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditStartCommand.kt deleted file mode 100644 index d36a6705f..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/command/regedit/SpigotRegistryEditStartCommand.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.command.regedit - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditStartCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender -import org.bukkit.command.TabCompleter -import org.bukkit.entity.Player - -class SpigotRegistryEditStartCommand - : CommonRegistryEditStartCommand(), CommandExecutor, TabCompleter { - override fun onCommand(source: CommandSender, command: Command, alias: String, context: Array): Boolean { - execute(source, context) - return true - } - - override fun onTabComplete(source: CommandSender, command: Command, alias: String, context: Array): List { - return suggest(source, context) - } -} diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/module/SpigotFallbackModule.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/module/SpigotFallbackModule.kt deleted file mode 100644 index 6effc3d2f..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/module/SpigotFallbackModule.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.spigot.module - -import net.md_5.bungee.api.chat.TextComponent -import org.anvilpowered.anvil.common.module.FallbackModule -import org.bukkit.command.CommandSender - -class SpigotFallbackModule : FallbackModule() diff --git a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/server/SpigotLocationService.kt b/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/server/SpigotLocationService.kt deleted file mode 100644 index e4ec04edb..000000000 --- a/anvil-spigot/src/main/kotlin/org/anvilpowered/anvil/spigot/server/SpigotLocationService.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.spigot.server - -import com.flowpowered.math.vector.Vector3d -import com.google.inject.Inject -import org.anvilpowered.anvil.api.util.UserService -import org.anvilpowered.anvil.common.server.CommonLocationService -import org.bukkit.entity.Player -import java.util.Optional -import java.util.UUID -import java.util.concurrent.CompletableFuture - -class SpigotLocationService : CommonLocationService() { - - @Inject - private lateinit var userService: UserService - - override fun teleport(teleportingUserUUID: UUID, targetUserUUID: UUID): CompletableFuture { - val teleporter = userService[teleportingUserUUID] - val target = userService[targetUserUUID] - return CompletableFuture.completedFuture( - if (teleporter.isPresent && target.isPresent) { - teleporter.get().teleport(target.get().location) - } else false - ) - } - - override fun getWorldName(userUUID: UUID): Optional { - return userService[userUUID].map { it.world }.map { it.name } - } - - override fun getWorldName(userName: String): Optional { - return userService[userName].map { it.world }.map { it.name } - } - - private fun extractCoords(player: Player): Vector3d { - val pos = player.location - return Vector3d(pos.x, pos.y, pos.z) - } - - override fun getPosition(userUUID: UUID): Optional { - return userService[userUUID].map(::extractCoords) - } - - override fun getPosition(userName: String): Optional { - return userService[userName].map(::extractCoords) - } -} diff --git a/anvil-spigot/src/main/resources/plugin.yml b/anvil-spigot/src/main/resources/plugin.yml deleted file mode 100644 index d6ec98f08..000000000 --- a/anvil-spigot/src/main/resources/plugin.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Anvil -version: "${version}" -main: org.anvilpowered.anvil.spigot.AnvilSpigot -api-version: 1.15 -description: A cross-platform Minecraft plugin framework -website: https://www.anvilpowered.org -commands: - anvil: - description: Anvil root command - callback: - description: Anvil callback command diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/AnvilSponge.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/AnvilSponge.java deleted file mode 100644 index dd4518bc0..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/AnvilSponge.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge; - -import com.google.inject.Inject; -import com.google.inject.Injector; -import org.anvilpowered.anvil.api.AnvilImpl; -import org.anvilpowered.anvil.api.EnvironmentBuilderImpl; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.sponge.listener.SpongePlayerListener; -import org.anvilpowered.anvil.sponge.module.ApiSpongeModule; -import org.anvilpowered.anvil.sponge.module.SpongeFallbackModule; -import org.anvilpowered.anvil.sponge.module.SpongeModule; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.Order; -import org.spongepowered.api.event.game.state.GameInitializationEvent; -import org.spongepowered.api.plugin.Plugin; - -@Plugin( - id = AnvilPluginInfo.id, - name = AnvilPluginInfo.name, - version = AnvilPluginInfo.version, - description = AnvilPluginInfo.description, - url = AnvilPluginInfo.url, - authors = AnvilPluginInfo.organizationName -) -public class AnvilSponge extends AnvilImpl { - - @Inject - public AnvilSponge(Injector injector) { - super(injector, new SpongeModule()); - } - - @Listener(order = Order.EARLY) - public void onInit(GameInitializationEvent event) { - EnvironmentBuilderImpl.completeInitialization(new ApiSpongeModule(), new SpongeFallbackModule()); - Sponge.getEventManager().registerListeners(this, - environment.getInjector().getInstance(SpongePlayerListener.class)); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilCommandNode.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilCommandNode.java deleted file mode 100644 index b1e0c3e0e..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilCommandNode.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.common.command.CommonAnvilCommandNode; -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.sponge.command.regedit.SpongeRegistryEditCommandNode; -import org.anvilpowered.anvil.sponge.command.regedit.SpongeRegistryEditRootCommand; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.command.CommandCallable; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.args.GenericArguments; -import org.spongepowered.api.command.spec.CommandExecutor; -import org.spongepowered.api.command.spec.CommandSpec; -import org.spongepowered.api.text.Text; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Singleton -public class SpongeAnvilCommandNode - extends CommonAnvilCommandNode { - - @Inject - private SpongeAnvilPluginsCommand anvilPluginsCommand; - - @Inject - private SpongeAnvilReloadCommand anvilReloadCommand; - - @Inject - private SpongeRegistryEditRootCommand registryEditRootCommand; - - @Inject - private SpongeRegistryEditCommandNode registryEditCommandNode; - - @Inject - public SpongeAnvilCommandNode(Registry registry) { - super(registry); - } - - @Override - protected void loadCommands() { - - Map, CommandCallable> subCommands = new HashMap<>(); - - subCommands.put(PLUGINS_ALIAS, CommandSpec.builder() - .description(Text.of(PLUGINS_DESCRIPTION)) - .permission(registry.getOrDefault(Keys.PLUGINS_PERMISSION)) - .executor(anvilPluginsCommand) - .build()); - - subCommands.put(RELOAD_ALIAS, CommandSpec.builder() - .description(Text.of(RELOAD_DESCRIPTION)) - .permission(registry.getOrDefault(Keys.RELOAD_PERMISSION)) - .arguments( - GenericArguments.flags().flag("a", "-all").flag("r", "-regex") - .buildWith(GenericArguments.optional( - GenericArguments.withSuggestions( - GenericArguments.string(Text.of("plugin")), - anvilReloadCommand.suggest() - ) - )) - ) - .executor(anvilReloadCommand) - .build()); - - subCommands.put(REGEDIT_ALIAS, CommandSpec.builder() - .description(Text.of(CommonRegistryEditCommandNode.ROOT_DESCRIPTION)) - .permission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - .executor(registryEditRootCommand) - .children(registryEditCommandNode.getSubCommands()) - .build()); - - subCommands.put(HELP_ALIAS, CommandSpec.builder() - .description(Text.of(HELP_DESCRIPTION)) - .executor(commandService.generateHelpCommand(this)) - .build()); - - subCommands.put(VERSION_ALIAS, CommandSpec.builder() - .description(Text.of(VERSION_DESCRIPTION)) - .executor(commandService.generateVersionCommand(HELP_COMMAND)) - .build()); - - CommandSpec root = CommandSpec.builder() - .description(Text.of(ROOT_DESCRIPTION)) - .executor(commandService.generateRootCommand(HELP_COMMAND)) - .children(subCommands) - .build(); - - Sponge.getCommandManager() - .register(environment.getPlugin(), root, AnvilPluginInfo.id); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilPluginsCommand.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilPluginsCommand.java deleted file mode 100644 index 1a5a66181..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilPluginsCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command; - -import org.anvilpowered.anvil.common.command.CommonAnvilPluginsCommand; -import org.spongepowered.api.command.CommandResult; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.args.CommandContext; -import org.spongepowered.api.command.spec.CommandExecutor; -import org.spongepowered.api.text.Text; - -public class SpongeAnvilPluginsCommand - extends CommonAnvilPluginsCommand - implements CommandExecutor { - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - executeDirect(source); - return CommandResult.success(); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilReloadCommand.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilReloadCommand.java deleted file mode 100644 index 5a5d7d57b..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeAnvilReloadCommand.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command; - -import org.anvilpowered.anvil.common.command.CommonAnvilReloadCommand; -import org.spongepowered.api.command.CommandResult; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.args.CommandContext; -import org.spongepowered.api.command.spec.CommandExecutor; -import org.spongepowered.api.text.Text; - -import java.util.Optional; - -public class SpongeAnvilReloadCommand - extends CommonAnvilReloadCommand - implements CommandExecutor { - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - Optional optionalPlugin = context.getOne("plugin"); - String[] reloadedResult = {""}; - if (context.hasAny("a")) { - reloadedResult[0] = doAll(); - } else if (!checkPresent(source, optionalPlugin.isPresent())) { - return CommandResult.empty(); - } else if (context.hasAny("r")) { - if (!doRegex(source, optionalPlugin.get(), reloadedResult)) { - return CommandResult.empty(); - } - } else if (!doDirect(source, optionalPlugin.get(), reloadedResult)) { - return CommandResult.empty(); - } - sendSuccess(source, reloadedResult); - return CommandResult.success(); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandExecuteService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandExecuteService.java deleted file mode 100644 index 6cbe8c97a..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandExecuteService.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.command.CommandExecuteService; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; -import org.spongepowered.api.scheduler.Task; - -public class SpongeCommandExecuteService implements CommandExecuteService { - - @Inject - private PluginContainer pluginContainer; - - private void executeDirect(String command) { - Sponge.getCommandManager().process(Sponge.getServer().getConsole(), command); - } - - @Override - public void execute(String command) { - if (Sponge.getServer().isMainThread()) { - executeDirect(command); - } else { - Task.builder().execute(() -> executeDirect(command)).submit(pluginContainer); - } - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandService.java deleted file mode 100644 index 423b325de..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/command/SpongeCommandService.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command; - -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.CommonCommandService; -import org.spongepowered.api.command.CommandCallable; -import org.spongepowered.api.command.CommandResult; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.args.CommandContext; -import org.spongepowered.api.command.spec.CommandExecutor; -import org.spongepowered.api.text.Text; - -import java.util.List; -import java.util.function.Predicate; - -public class SpongeCommandService - extends CommonCommandService { - - private static abstract class Command implements CommandExecutor { - - protected final String helpUsage; - protected final Predicate extended; - - public Command(String helpUsage, Predicate extended) { - this.helpUsage = helpUsage; - this.extended = extended; - } - } - - private class RootCommand extends Command { - - public RootCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - sendRoot(source, helpUsage, extended.test(source)); - return CommandResult.success(); - } - } - - private class VersionCommand extends Command { - - public VersionCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - sendVersion(source, helpUsage, extended.test(source)); - return CommandResult.success(); - } - } - - private class HelpCommand implements CommandExecutor { - - private final CommandNode node; - - public HelpCommand(CommandNode node) { - this.node = node; - } - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - sendHelp(source, node); - return CommandResult.success(); - } - } - - private class ReloadCommand implements CommandExecutor { - - @Override - public CommandResult execute(CommandSource source, CommandContext context) { - sendReload(source); - return CommandResult.success(); - } - } - - @Override - protected void runExecutor( - CommandExecutor commandExecutor, - CommandCallable commandCallable, - CommandSource commandSource, - String alias, - String[] context - ) { - throw new UnsupportedOperationException(); - } - - @Override - protected List getSuggestions( - CommandExecutor commandExecutor, - CommandCallable commandCallable, - CommandSource commandSource, - String alias, - String[] context - ) { - throw new UnsupportedOperationException(); - } - - @Override - protected CommandExecutor generateWrapperCommand( - CommandExecutorWrapper command) { - throw new UnsupportedOperationException(); - } - - @Override - public CommandExecutor generateRootCommand( - String helpUsage, Predicate extended) { - return new RootCommand(helpUsage, extended); - } - - @Override - public CommandExecutor generateVersionCommand( - String helpUsage, Predicate extended) { - return new VersionCommand(helpUsage, extended); - } - - @Override - public CommandExecutor generateHelpCommand(CommandNode node) { - return new HelpCommand(node); - } - - @Override - public CommandExecutor generateReloadCommand() { - return new ReloadCommand(); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/entity/SpongeEntityUtils.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/entity/SpongeEntityUtils.java deleted file mode 100644 index 69f48031d..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/entity/SpongeEntityUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.entity; - -import org.anvilpowered.anvil.common.entity.EntityUtils; -import org.spongepowered.api.util.Identifiable; - -import java.util.Optional; -import java.util.UUID; - -public class SpongeEntityUtils implements EntityUtils { - - @Override - public Optional extractUUID(Object entity) { - if (!(entity instanceof Identifiable)) { - return Optional.empty(); - } - return Optional.of(((Identifiable) entity).getUniqueId()); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/listener/SpongePlayerListener.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/listener/SpongePlayerListener.java deleted file mode 100644 index 66e2f4a54..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/listener/SpongePlayerListener.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.listener; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.entity.RestrictionService; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; -import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.event.Cancellable; -import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.action.InteractEvent; -import org.spongepowered.api.event.cause.entity.damage.source.DamageSource; -import org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource; -import org.spongepowered.api.event.command.SendCommandEvent; -import org.spongepowered.api.event.entity.DamageEntityEvent; -import org.spongepowered.api.event.entity.MoveEntityEvent; -import org.spongepowered.api.event.filter.Getter; -import org.spongepowered.api.event.filter.cause.Root; -import org.spongepowered.api.event.item.inventory.TargetInventoryEvent; -import org.spongepowered.api.event.network.ClientConnectionEvent; - -public class SpongePlayerListener { - - @Inject - private CoreMemberManager coreMemberManager; - - @Inject - private Registry registry; - - @Inject - private RestrictionService restrictionService; - - @Listener - public void onPlayerJoin(ClientConnectionEvent.Join event) { - if (registry.getOrDefault(Keys.PROXY_MODE)) { - return; - } - Player player = event.getTargetEntity(); - coreMemberManager.getPrimaryComponent() - .getOneOrGenerateForUser( - player.getUniqueId(), - player.getName(), - player.getConnection().getAddress().getHostString() - ); - } - - @Listener - public void onMovement(MoveEntityEvent event, @Getter("getTargetEntity") Entity entity) { - if (restrictionService.get(entity).movement()) { - event.setCancelled(true); - } - } - - @Listener - public void onInteraction(InteractEvent event, @Root Entity entity) { - if (restrictionService.get(entity).interaction()) { - event.setCancelled(true); - } - } - - @Listener - public void onInventory(TargetInventoryEvent event, @Root Player player) { - if (event instanceof Cancellable - && restrictionService.get(player.getUniqueId()).inventory()) { - ((Cancellable) event).setCancelled(true); - } - } - - @Listener - public void onCommands(SendCommandEvent event, @Root Player player) { - if (restrictionService.get(player.getUniqueId()).commands()) { - event.setCancelled(true); - } - } - - @Listener - public void onDamage(DamageEntityEvent event, @Getter("getTargetEntity") Entity target, @Root DamageSource source) { - if (restrictionService.get(target).damage() || ((source instanceof EntityDamageSource) - && restrictionService.get(((EntityDamageSource) source).getSource()).damage())) { - event.setCancelled(true); - } - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/ApiSpongeModule.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/ApiSpongeModule.java deleted file mode 100644 index d44b36c38..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/ApiSpongeModule.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.module; - -import com.google.inject.TypeLiteral; -import org.anvilpowered.anvil.api.PlatformImpl; -import org.anvilpowered.anvil.api.command.CommandExecuteService; -import org.anvilpowered.anvil.api.command.CommandService; -import org.anvilpowered.anvil.api.server.LocationService; -import org.anvilpowered.anvil.api.util.KickService; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.anvilpowered.anvil.api.util.TextService; -import org.anvilpowered.anvil.api.util.UserService; -import org.anvilpowered.anvil.common.entity.EntityUtils; -import org.anvilpowered.anvil.common.module.PlatformModule; -import org.anvilpowered.anvil.sponge.command.SpongeCommandExecuteService; -import org.anvilpowered.anvil.sponge.command.SpongeCommandService; -import org.anvilpowered.anvil.sponge.entity.SpongeEntityUtils; -import org.anvilpowered.anvil.sponge.server.SpongeLocationService; -import org.anvilpowered.anvil.sponge.util.SpongeKickService; -import org.anvilpowered.anvil.sponge.util.SpongePermissionService; -import org.anvilpowered.anvil.sponge.util.SpongeTextService; -import org.anvilpowered.anvil.sponge.util.SpongeUserService; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.spec.CommandExecutor; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.entity.living.player.User; -import org.spongepowered.api.text.Text; - -public class ApiSpongeModule extends PlatformModule { - - public ApiSpongeModule() { - super(new PlatformImpl(false, "sponge")); - } - - @Override - protected void configure() { - super.configure(); - bind(CommandExecuteService.class).to(SpongeCommandExecuteService.class); - bind(new TypeLiteral>() { - }).to(SpongeCommandService.class); - bind(EntityUtils.class).to(SpongeEntityUtils.class); - bind(KickService.class).to(SpongeKickService.class); - bind(LocationService.class).to(SpongeLocationService.class); - bind(PermissionService.class).to(SpongePermissionService.class); - bind(new TypeLiteral>() { - }).to(SpongeTextService.class); - bind(new TypeLiteral>() { - }).to(SpongeUserService.class); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/SpongeModule.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/SpongeModule.java deleted file mode 100644 index 77a408569..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/module/SpongeModule.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.module; - -import com.google.inject.TypeLiteral; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand; -import org.anvilpowered.anvil.common.module.CommonModule; -import org.anvilpowered.anvil.common.registry.CommonConfigurationService; -import org.anvilpowered.anvil.sponge.command.SpongeAnvilCommandNode; -import org.anvilpowered.anvil.sponge.command.regedit.SpongeRegistryEditRootCommand; -import org.anvilpowered.anvil.sponge.registry.SpongeConfigurationService; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.entity.living.player.User; -import org.spongepowered.api.text.Text; - -public class SpongeModule extends CommonModule { - - @Override - protected void configure() { - super.configure(); - - bind(CommonConfigurationService.class).to(SpongeConfigurationService.class); - bind(new TypeLiteral>() { - }).to(SpongeAnvilCommandNode.class); - bind(new TypeLiteral>() { - }).to(SpongeRegistryEditRootCommand.class); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeKickService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeKickService.java deleted file mode 100644 index ba44cb050..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeKickService.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.util; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.api.util.KickService; -import org.anvilpowered.anvil.api.util.UserService; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.entity.living.player.User; -import org.spongepowered.api.text.Text; - -import java.util.UUID; - -public class SpongeKickService implements KickService { - - @Inject - private UserService userService; - - @Override - public void kick(UUID userUUID, Object reason) { - userService.getPlayer(userUUID).ifPresent(player -> player.kick(Text.of(reason))); - } - - @Override - public void kick(String userName, Object reason) { - userService.getPlayer(userName).ifPresent(player -> player.kick(Text.of(reason))); - } - - @Override - public void kick(UUID userUUID) { - kick(userUUID, "You have been kicked"); - } - - @Override - public void kick(String userName) { - kick(userName, "You have been kicked"); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongePermissionService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongePermissionService.java deleted file mode 100644 index d6f3ac40a..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongePermissionService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.util; - -import org.anvilpowered.anvil.api.util.PermissionService; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.service.permission.Subject; - -public class SpongePermissionService implements PermissionService { - @Override - public boolean hasPermission(@Nullable Object subject, String permission) { - return subject instanceof Subject && ((Subject) subject).hasPermission(permission); - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeTextService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeTextService.java deleted file mode 100644 index 7c9a23d7c..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeTextService.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.util; - -import org.anvilpowered.anvil.common.util.CommonTextService; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.service.pagination.PaginationList; -import org.spongepowered.api.service.pagination.PaginationService; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.TextElement; -import org.spongepowered.api.text.action.ClickAction; -import org.spongepowered.api.text.action.HoverAction; -import org.spongepowered.api.text.action.TextActions; -import org.spongepowered.api.text.format.TextColors; -import org.spongepowered.api.text.format.TextStyles; -import org.spongepowered.api.text.serializer.TextSerializers; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; - -@SuppressWarnings("unchecked") -public class SpongeTextService extends CommonTextService { - - @Override - public Builder builder() { - return new SpongeTextBuilder(); - } - - @Override - public PaginationBuilder paginationBuilder() { - return new SpongePaginationBuilder(); - } - - @Override - public void send(Text text, CommandSource receiver) { - receiver.sendMessage(text); - } - - @Override - public CommandSource getConsole() { - return Sponge.getServer().getConsole(); - } - - @Override - public Text deserialize(String text) { - return TextSerializers.FORMATTING_CODE.deserialize(text); - } - - @Override - public String serialize(Text text) { - return TextSerializers.FORMATTING_CODE.serialize(text); - } - - @Override - public String serializePlain(Text text) { - return text.toPlain(); - } - - protected class SpongeTextBuilder extends CommonTextBuilder { - - private final List elements; - private HoverAction hoverAction; - private ClickAction clickAction; - - protected SpongeTextBuilder() { - elements = new ArrayList<>(); - } - - @Override - public Builder aqua() { - elements.add(TextColors.AQUA); - return this; - } - - @Override - public Builder black() { - elements.add(TextColors.BLACK); - return this; - } - - @Override - public Builder blue() { - elements.add(TextColors.BLUE); - return this; - } - - @Override - public Builder dark_aqua() { - elements.add(TextColors.DARK_AQUA); - return this; - } - - @Override - public Builder dark_blue() { - elements.add(TextColors.DARK_BLUE); - return this; - } - - @Override - public Builder dark_gray() { - elements.add(TextColors.DARK_GRAY); - return this; - } - - @Override - public Builder dark_green() { - elements.add(TextColors.DARK_GREEN); - return this; - } - - @Override - public Builder dark_purple() { - elements.add(TextColors.DARK_PURPLE); - return this; - } - - @Override - public Builder dark_red() { - elements.add(TextColors.DARK_RED); - return this; - } - - @Override - public Builder gold() { - elements.add(TextColors.GOLD); - return this; - } - - @Override - public Builder gray() { - elements.add(TextColors.GRAY); - return this; - } - - @Override - public Builder green() { - elements.add(TextColors.GREEN); - return this; - } - - @Override - public Builder light_purple() { - elements.add(TextColors.LIGHT_PURPLE); - return this; - } - - @Override - public Builder red() { - elements.add(TextColors.RED); - return this; - } - - @Override - public Builder reset() { - elements.add(TextColors.RESET); - return this; - } - - @Override - public Builder white() { - elements.add(TextColors.WHITE); - return this; - } - - @Override - public Builder yellow() { - elements.add(TextColors.YELLOW); - return this; - } - - @Override - public Builder bold() { - elements.add(TextStyles.BOLD); - return this; - } - - @Override - public Builder italic() { - elements.add(TextStyles.ITALIC); - return this; - } - - @Override - public Builder obfuscated() { - elements.add(TextStyles.OBFUSCATED); - return this; - } - - @Override - public Builder strikethrough() { - elements.add(TextStyles.STRIKETHROUGH); - return this; - } - - @Override - public Builder underlined() { - elements.add(TextStyles.UNDERLINE); - return this; - } - - @Override - public Builder append(Object... contents) { - for (Object o : contents) { - if (o instanceof Builder) { - elements.add(((Builder) o).build()); - } else if (o instanceof TextElement) { - elements.add((TextElement) o); - } else { - elements.add(Text.of(o)); - } - } - return this; - } - - @Override - public Builder appendJoining(Object delimiter, Object... contents) { - final int indexOfLast = contents.length - 1; - for (int i = 0; i <= indexOfLast; i++) { - Object o = contents[i]; - if (o instanceof Builder) { - elements.add(((Builder) o).build()); - } else if (o instanceof TextElement) { - elements.add((TextElement) o); - } else { - elements.add(Text.of(o)); - } - if (i != indexOfLast) { - elements.add(Text.of(delimiter)); - } - } - return this; - } - - @Override - public Builder onHoverShowText(Text content) { - hoverAction = TextActions.showText(content); - return this; - } - - @Override - public Builder onClickSuggestCommand(String command) { - clickAction = TextActions.suggestCommand(command); - return this; - } - - @Override - public Builder onClickRunCommand(String command) { - clickAction = TextActions.runCommand(command); - return this; - } - - @Override - public Builder onClickExecuteCallback( - Consumer callback) { - clickAction = TextActions.executeCallback(callback); - return this; - } - - @Override - public Builder onClickOpenUrl(URL url) { - clickAction = TextActions.openUrl(url); - return this; - } - - @Override - public Builder onClickOpenUrl(String url) { - try { - clickAction = TextActions.openUrl(new URL(url)); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - return this; - } - - @Override - public Text build() { - boolean hover = hoverAction != null; - boolean click = clickAction != null; - - if (elements.size() == 1 && !hover && !click) { - TextElement o = elements.get(0); - if (o instanceof Builder) { - return ((Builder) o).build(); - } - return Text.of(o); - } - Text.Builder builder = Text.builder().append(Text.of(elements.toArray())); - if (hover) { - builder.onHover(hoverAction); - } - if (click) { - builder.onClick(clickAction); - } - return builder.build(); - } - } - - protected class SpongePaginationBuilder extends CommonPaginationBuilder { - - private final PaginationList.Builder builder; - - public SpongePaginationBuilder() { - builder = Sponge.getServiceManager() - .provideUnchecked(PaginationService.class).builder(); - } - - @Override - public PaginationBuilder contents( - Text... contents) { - builder.contents(contents); - return this; - } - - @Override - public PaginationBuilder contents( - Iterable contents) { - builder.contents(contents); - return this; - } - - @Override - public PaginationBuilder title( - @Nullable Text title) { - builder.title(title); - return this; - } - - @Override - public PaginationBuilder header( - @Nullable Text header) { - builder.header(header); - return this; - } - - @Override - public PaginationBuilder footer( - @Nullable Text footer) { - builder.footer(footer); - return this; - } - - @Override - public PaginationBuilder padding( - Text padding) { - builder.padding(padding); - return this; - } - - @Override - public PaginationBuilder linesPerPage( - int linesPerPage) { - if (linesPerPage < 1) { - throw new IllegalArgumentException("Lines per page must be at least 1"); - } - builder.linesPerPage(linesPerPage); - return this; - } - - @Override - public Pagination build() { - return new SpongePagination(builder.build()); - } - } - - protected static class SpongePagination implements Pagination { - - private final PaginationList paginationList; - - public SpongePagination(PaginationList paginationList) { - this.paginationList = paginationList; - } - - @Override - public Iterable getContents() { - return paginationList.getContents(); - } - - @Override - public Optional getTitle() { - return paginationList.getTitle(); - } - - @Override - public Optional getHeader() { - return paginationList.getHeader(); - } - - @Override - public Optional getFooter() { - return paginationList.getFooter(); - } - - @Override - public Text getPadding() { - return paginationList.getPadding(); - } - - @Override - public int getLinesPerPage() { - return paginationList.getLinesPerPage(); - } - - @Override - public void sendTo(CommandSource receiver) { - paginationList.sendTo(receiver); - } - - @Override - public void sendToConsole() { - sendTo(Sponge.getServer().getConsole()); - } - } -} diff --git a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeUserService.java b/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeUserService.java deleted file mode 100644 index d82e86cf8..000000000 --- a/anvil-sponge/src/main/java/org/anvilpowered/anvil/sponge/util/SpongeUserService.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.util; - -import com.google.inject.Inject; -import org.anvilpowered.anvil.common.util.CommonUserService; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.entity.living.player.User; -import org.spongepowered.api.profile.GameProfile; -import org.spongepowered.api.service.user.UserStorageService; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -public class SpongeUserService extends CommonUserService { - - @Inject - public SpongeUserService() { - super(User.class); - } - - @Override - public Optional get(String userName) { - return Sponge.getServiceManager().provide(UserStorageService.class).flatMap(u -> u.get(userName)); - } - - @Override - public Optional get(UUID userUUID) { - return Sponge.getServiceManager().provide(UserStorageService.class).flatMap(u -> u.get(userUUID)); - } - - @Override - public Optional getPlayer(String userName) { - return get(userName).flatMap(User::getPlayer); - } - - @Override - public Optional getPlayer(UUID userUUID) { - return get(userUUID).flatMap(User::getPlayer); - } - - @Override - public Optional getPlayer(User user) { - return user.getPlayer(); - } - - @Override - public List matchPlayerNames(String lastKnownName) { - return Sponge.getServiceManager().provideUnchecked(UserStorageService.class).match(lastKnownName).stream() - .map(GameProfile::getName) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - } - - @Override - public Collection getOnlinePlayers() { - return Sponge.getServer().getOnlinePlayers(); - } - - @Override - public CompletableFuture> getUUID(String userName) { - Optional userUUID = getPlayer(userName).map(Player::getUniqueId); - if (userUUID.isPresent()) { - return CompletableFuture.completedFuture(userUUID); - } - return super.getUUID(userName); - } - - @Override - public CompletableFuture> getUserName(UUID userUUID) { - Optional userName = getPlayer(userUUID).map(Player::getName); - if (userName.isPresent()) { - return CompletableFuture.completedFuture(userName); - } - return super.getUserName(userUUID); - } - - @Override - public UUID getUUID(User user) { - return user.getUniqueId(); - } - - @Override - public String getUserName(User user) { - return user.getName(); - } -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCancelCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCancelCommand.kt deleted file mode 100644 index ecef436a9..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCancelCommand.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCancelCommand -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.anvilpowered.anvil.common.command.regedit.alias -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text -import org.spongepowered.api.world.Location -import org.spongepowered.api.world.World -import java.util.Optional - -class SpongeRegistryEditCancelCommand : CommonRegistryEditCancelCommand(), CommandCallable { - - companion object { - val DESCRIPTION: Optional = Optional.of(Text.of(CommonRegistryEditCommandNode.CANCEL_DESCRIPTION)) - val USAGE: Text get() = Text.of("/$alias regedit cancel") - } - - override fun process(source: CommandSource, context: String): CommandResult { - execute(source) - return CommandResult.success() - } - - override fun getSuggestions(source: CommandSource, context: String, targetPosition: Location?): List { - return listOf() - } - - override fun testPermission(source: CommandSource): Boolean { - return source.hasPermission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - override fun getShortDescription(source: CommandSource): Optional = DESCRIPTION - override fun getHelp(source: CommandSource): Optional = DESCRIPTION - override fun getUsage(source: CommandSource): Text = USAGE -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommandNode.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommandNode.kt deleted file mode 100644 index 614599830..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommandNode.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.command.spec.CommandExecutor -import org.spongepowered.api.command.spec.CommandSpec -import java.util.HashMap - -@Singleton -class SpongeRegistryEditCommandNode @Inject constructor( - registry: Registry, -) : CommonRegistryEditCommandNode(registry) { - - @Inject - private lateinit var registryEditCancelCommand: SpongeRegistryEditCancelCommand - - @Inject - private lateinit var registryEditCommitCommand: SpongeRegistryEditCommitCommand - - @Inject - private lateinit var registryEditKeyCommand: SpongeRegistryEditKeyCommand - - @Inject - private lateinit var registryEditSelectCommand: SpongeRegistryEditSelectCommand - - @Inject - private lateinit var registryEditStartCommand: SpongeRegistryEditStartCommand - - val subCommands: MutableMap, CommandCallable> = HashMap() - - override fun loadCommands() { - subCommands[CANCEL_ALIAS] = registryEditCancelCommand - subCommands[COMMIT_ALIAS] = registryEditCommitCommand - subCommands[KEY_ALIAS] = registryEditKeyCommand - subCommands[SELECT_ALIAS] = registryEditSelectCommand - subCommands[START_ALIAS] = registryEditStartCommand - subCommands[HELP_ALIAS] = CommandSpec.builder().executor(commandService.generateHelpCommand(this)).build() - } -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommitCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommitCommand.kt deleted file mode 100644 index 42825daca..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditCommitCommand.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommitCommand -import org.anvilpowered.anvil.common.command.regedit.alias -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text -import org.spongepowered.api.world.Location -import org.spongepowered.api.world.World -import java.util.Optional - -class SpongeRegistryEditCommitCommand : CommonRegistryEditCommitCommand(), CommandCallable { - - companion object { - val DESCRIPTION: Optional = Optional.of(Text.of(CommonRegistryEditCommandNode.COMMIT_DESCRIPTION)) - val USAGE: Text get() = Text.of("/$alias regedit commit") - } - - override fun process(source: CommandSource, context: String): CommandResult { - execute(source) - return CommandResult.success() - } - - override fun getSuggestions(source: CommandSource, context: String, targetPosition: Location?): List { - return listOf() - } - - override fun testPermission(source: CommandSource): Boolean { - return source.hasPermission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - override fun getShortDescription(source: CommandSource): Optional = DESCRIPTION - override fun getHelp(source: CommandSource): Optional = DESCRIPTION - override fun getUsage(source: CommandSource): Text = USAGE -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditKeyCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditKeyCommand.kt deleted file mode 100644 index 7ef5fea90..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditKeyCommand.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditKeyCommand -import org.anvilpowered.anvil.common.command.regedit.alias -import org.anvilpowered.anvil.common.command.regedit.whitespace -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text -import org.spongepowered.api.world.Location -import org.spongepowered.api.world.World -import java.util.Optional - -class SpongeRegistryEditKeyCommand : CommonRegistryEditKeyCommand(), CommandCallable { - - companion object { - val DESCRIPTION: Optional = Optional.of(Text.of(CommonRegistryEditCommandNode.KEY_DESCRIPTION)) - val USAGE: Text get() = Text.of("/$alias regedit key ${CommonRegistryEditCommandNode.KEY_USAGE}") - } - - override fun process(source: CommandSource, context: String): CommandResult { - execute(source, context.split(whitespace).toTypedArray()) - return CommandResult.success() - } - - override fun getSuggestions(source: CommandSource, context: String, targetPosition: Location?): List { - return suggest(source, context.split(whitespace).toTypedArray()) - } - - override fun testPermission(source: CommandSource): Boolean { - return source.hasPermission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - override fun getShortDescription(source: CommandSource): Optional = DESCRIPTION - override fun getHelp(source: CommandSource): Optional = DESCRIPTION - override fun getUsage(source: CommandSource): Text = USAGE -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditRootCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditRootCommand.kt deleted file mode 100644 index 845a9065d..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditRootCommand.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import com.google.inject.Singleton -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.command.args.CommandContext -import org.spongepowered.api.command.spec.CommandExecutor -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text - -@Singleton -class SpongeRegistryEditRootCommand : CommonRegistryEditRootCommand(), CommandExecutor { - override fun execute(source: CommandSource, context: CommandContext): CommandResult { - execute(source) - return CommandResult.success() - } -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditSelectCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditSelectCommand.kt deleted file mode 100644 index 2da523b5d..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditSelectCommand.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditSelectCommand -import org.anvilpowered.anvil.common.command.regedit.alias -import org.anvilpowered.anvil.common.command.regedit.whitespace -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text -import org.spongepowered.api.world.Location -import org.spongepowered.api.world.World -import java.util.Optional - -class SpongeRegistryEditSelectCommand : CommonRegistryEditSelectCommand(), CommandCallable { - - companion object { - val DESCRIPTION: Optional = Optional.of(Text.of(CommonRegistryEditCommandNode.SELECT_DESCRIPTION)) - val USAGE: Text get() = Text.of("/$alias regedit select ${CommonRegistryEditCommandNode.SELECT_USAGE}") - } - - override fun process(source: CommandSource, context: String): CommandResult { - execute(source, context.split(whitespace).toTypedArray()) - return CommandResult.success() - } - - override fun getSuggestions(source: CommandSource, context: String, targetPosition: Location?): List { - return suggest(source, context.split(whitespace).toTypedArray()) - } - - override fun testPermission(source: CommandSource): Boolean { - return source.hasPermission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - override fun getShortDescription(source: CommandSource): Optional = DESCRIPTION - override fun getHelp(source: CommandSource): Optional = DESCRIPTION - override fun getUsage(source: CommandSource): Text = USAGE -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditStartCommand.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditStartCommand.kt deleted file mode 100644 index 61006513c..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/command/regedit/SpongeRegistryEditStartCommand.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.command.regedit - -import org.anvilpowered.anvil.api.registry.Keys -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditStartCommand -import org.anvilpowered.anvil.common.command.regedit.alias -import org.anvilpowered.anvil.common.command.regedit.whitespace -import org.spongepowered.api.command.CommandCallable -import org.spongepowered.api.command.CommandResult -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import org.spongepowered.api.text.Text -import org.spongepowered.api.world.Location -import org.spongepowered.api.world.World -import java.util.Optional - -class SpongeRegistryEditStartCommand : CommonRegistryEditStartCommand(), CommandCallable { - - companion object { - val DESCRIPTION: Optional = Optional.of(Text.of(CommonRegistryEditCommandNode.START_DESCRIPTION)) - val USAGE: Text get() = Text.of("/$alias regedit start ${CommonRegistryEditCommandNode.START_USAGE}") - } - - override fun process(source: CommandSource, context: String): CommandResult { - execute(source, context.split(whitespace).toTypedArray()) - return CommandResult.success() - } - - override fun getSuggestions(source: CommandSource, context: String, targetPosition: Location?): List { - return suggest(source, context.split(whitespace).toTypedArray()) - } - - override fun testPermission(source: CommandSource): Boolean { - return source.hasPermission(registry.getOrDefault(Keys.REGEDIT_PERMISSION)) - } - - override fun getShortDescription(source: CommandSource): Optional = DESCRIPTION - override fun getHelp(source: CommandSource): Optional = DESCRIPTION - override fun getUsage(source: CommandSource): Text = USAGE -} diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/module/SpongeFallbackModule.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/module/SpongeFallbackModule.kt deleted file mode 100644 index d4d0c1b52..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/module/SpongeFallbackModule.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.sponge.module - -import org.anvilpowered.anvil.common.module.FallbackModule -import org.spongepowered.api.command.CommandSource -import org.spongepowered.api.text.Text - -class SpongeFallbackModule : FallbackModule() diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/registry/SpongeConfigurationService.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/registry/SpongeConfigurationService.kt deleted file mode 100644 index 3ef6434ef..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/registry/SpongeConfigurationService.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.sponge.registry - -import com.google.inject.Inject -import com.google.inject.Singleton -import ninja.leaping.configurate.commented.CommentedConfigurationNode -import ninja.leaping.configurate.loader.ConfigurationLoader -import org.anvilpowered.anvil.common.registry.CommonConfigurationService -import org.spongepowered.api.config.DefaultConfig - -@Singleton -class SpongeConfigurationService @Inject constructor( - @DefaultConfig(sharedRoot = false) configLoader: ConfigurationLoader -) : CommonConfigurationService(configLoader) diff --git a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/server/SpongeLocationService.kt b/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/server/SpongeLocationService.kt deleted file mode 100644 index 85c10e4ac..000000000 --- a/anvil-sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/server/SpongeLocationService.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.sponge.server - -import com.flowpowered.math.vector.Vector3d -import com.google.inject.Inject -import org.anvilpowered.anvil.api.util.UserService -import org.anvilpowered.anvil.common.server.CommonLocationService -import org.spongepowered.api.Sponge -import org.spongepowered.api.entity.living.player.Player -import org.spongepowered.api.entity.living.player.User -import java.util.Optional -import java.util.UUID -import java.util.concurrent.CompletableFuture - -class SpongeLocationService : CommonLocationService() { - - @Inject - private lateinit var userService: UserService - - override fun teleport(teleportingUserUUID: UUID, targetUserUUID: UUID): CompletableFuture { - val teleporter = userService[teleportingUserUUID] - val target = userService[targetUserUUID] - return CompletableFuture.completedFuture( - if (teleporter.isPresent && target.isPresent) { - target.get().worldUniqueId - .filter { teleporter.get().setLocation(target.get().position, it) } - .isPresent - } else false - ) - } - - override fun getWorldName(userName: String): Optional { - return userService[userName].flatMap { it.worldUniqueId } - .flatMap { Sponge.getServer().getWorld(it) } - .map { it.name } - } - - override fun getWorldName(userUUID: UUID): Optional { - return userService[userUUID].flatMap { it.worldUniqueId } - .flatMap { Sponge.getServer().getWorld(it) } - .map { it.name } - } - - override fun getPosition(userUUID: UUID): Optional { - return userService[userUUID].map { it.position } - } - - override fun getPosition(userName: String): Optional { - return userService[userName].map { it.position } - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/AnvilVelocity.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/AnvilVelocity.java deleted file mode 100644 index 57ac8b05f..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/AnvilVelocity.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity; - -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.velocitypowered.api.event.PostOrder; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; -import com.velocitypowered.api.plugin.Plugin; -import com.velocitypowered.api.proxy.ProxyServer; -import org.anvilpowered.anvil.api.AnvilImpl; -import org.anvilpowered.anvil.api.EnvironmentBuilderImpl; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.velocity.listener.VelocityPlayerListener; -import org.anvilpowered.anvil.velocity.module.ApiVelocityModule; -import org.anvilpowered.anvil.velocity.module.VelocityFallbackModule; -import org.anvilpowered.anvil.velocity.module.VelocityModule; - -@Plugin( - id = AnvilPluginInfo.id, - name = AnvilPluginInfo.name, - version = AnvilPluginInfo.version, - description = AnvilPluginInfo.description, - url = AnvilPluginInfo.url, - authors = AnvilPluginInfo.organizationName -) -public class AnvilVelocity extends AnvilImpl { - - @Inject - private ProxyServer proxyServer; - - @Inject - public AnvilVelocity(Injector injector) { - super(injector, new VelocityModule()); - } - - @Subscribe(order = PostOrder.EARLY) - public void onInit(ProxyInitializeEvent event) { - EnvironmentBuilderImpl.completeInitialization(new ApiVelocityModule(), new VelocityFallbackModule()); - proxyServer.getEventManager().register(this, - environment.getInjector().getInstance(VelocityPlayerListener.class)); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilCommandNode.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilCommandNode.java deleted file mode 100644 index 07e242b7b..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilCommandNode.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.google.inject.Inject; -import com.velocitypowered.api.command.Command; -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import com.velocitypowered.api.proxy.ProxyServer; -import org.anvilpowered.anvil.api.registry.Registry; -import org.anvilpowered.anvil.common.command.CommonAnvilCommandNode; -import org.anvilpowered.anvil.velocity.command.regedit.VelocityRegistryEditCommandNode; -import org.anvilpowered.anvil.velocity.command.regedit.VelocityRegistryEditRootCommand; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VelocityAnvilCommandNode - extends CommonAnvilCommandNode { - - @Inject - private VelocityAnvilPluginsCommand anvilPluginsCommand; - - @Inject - private VelocityAnvilReloadCommand anvilReloadCommand; - - @Inject - private VelocityCallbackCommand callbackCommand; - - @Inject - private VelocityRegistryEditRootCommand registryEditRootCommand; - - @Inject - private VelocityRegistryEditCommandNode registryEditCommandNode; - - @Inject - private ProxyServer proxyServer; - - private static final String HELP_COMMAND_PROXY = "/anvilv help"; - - @Inject - public VelocityAnvilCommandNode(Registry registry) { - super(registry); - } - - @Override - protected void loadCommands() { - Map, SimpleCommand> subCommands = new HashMap<>(); - - subCommands.put(PLUGINS_ALIAS, anvilPluginsCommand); - subCommands.put(RELOAD_ALIAS, anvilReloadCommand); - subCommands.put(REGEDIT_ALIAS, commandService.generateRoutingCommand( - registryEditRootCommand, registryEditCommandNode.getSubCommands(), false) - ); - subCommands.put(HELP_ALIAS, commandService.generateHelpCommand(this)); - subCommands.put(VERSION_ALIAS, commandService.generateVersionCommand(HELP_COMMAND_PROXY)); - - proxyServer.getCommandManager().register("anvilv", - commandService.generateRoutingCommand( - commandService.generateRootCommand(HELP_COMMAND_PROXY), subCommands, false), - "av", "anvilv:av", "anvilv:anvilv"); - - proxyServer.getCommandManager().register("callback", callbackCommand, "anvilv:callback"); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilPluginsCommand.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilPluginsCommand.java deleted file mode 100644 index 75ce26992..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilPluginsCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.common.command.CommonAnvilPluginsCommand; - -import java.util.List; - -public class VelocityAnvilPluginsCommand - extends CommonAnvilPluginsCommand - implements SimpleCommand { - - @Override - public void execute(Invocation invocation) { - super.execute(invocation.source(), invocation.arguments()); - } - - @Override - public List suggest(Invocation invocation) { - return null; - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilReloadCommand.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilReloadCommand.java deleted file mode 100644 index e45cf62de..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityAnvilReloadCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.common.command.CommonAnvilReloadCommand; - -import java.util.List; - -public class VelocityAnvilReloadCommand - extends CommonAnvilReloadCommand - implements SimpleCommand { - - @Override - public void execute(Invocation invocation) { - super.execute(invocation.source(), invocation.arguments()); - } - - @Override - public List suggest(Invocation invocation) { - return super.suggest(invocation.source(), invocation.arguments()); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCallbackCommand.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCallbackCommand.java deleted file mode 100644 index c4d1cbe5c..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCallbackCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.google.inject.Singleton; -import com.velocitypowered.api.command.Command; -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.common.command.CommonCallbackCommand; - -import java.util.List; - -@Singleton -public class VelocityCallbackCommand - extends CommonCallbackCommand - implements SimpleCommand { - - @Override - public void execute(Invocation invocation) { - super.execute(invocation.source(), invocation.arguments()); - } - - @Override - public List suggest(Invocation invocation) { - return null; - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandExecuteService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandExecuteService.java deleted file mode 100644 index 3c30d43a3..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandExecuteService.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.google.inject.Inject; -import com.velocitypowered.api.proxy.ProxyServer; -import org.anvilpowered.anvil.api.command.CommandExecuteService; - -public class VelocityCommandExecuteService implements CommandExecuteService { - - @Inject - private ProxyServer proxyServer; - - @Override - public void execute(String command) { - proxyServer.getCommandManager().executeAsync(proxyServer.getConsoleCommandSource(), command); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandService.java deleted file mode 100644 index 956aec0fa..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/command/VelocityCommandService.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.command; - -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.CommonCommandService; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.List; -import java.util.function.Predicate; - -public class VelocityCommandService extends CommonCommandService { - - private static class WrapperCommand implements SimpleCommand { - private final CommandExecutorWrapper wrapper; - - public WrapperCommand(CommandExecutorWrapper wrapper) { - this.wrapper = wrapper; - } - - @Override - public void execute(Invocation invocation) { - wrapper.execute(null, invocation.source(), null, invocation.arguments()); - } - - @Override - public List suggest(Invocation invocation) { - return wrapper.suggest(null, invocation.source(), null, invocation.arguments()); - } - } - - private abstract static class VCommand implements SimpleCommand { - - protected final String helpUsage; - protected final Predicate extended; - - protected VCommand(String helpUsage, Predicate extended) { - this.helpUsage = helpUsage; - this.extended = extended; - } - } - - private class RootCommand extends VCommand { - public RootCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public void execute(Invocation invocation) { - sendRoot(invocation.source(), helpUsage, extended.test(invocation.source())); - } - } - - private class VersionCommand extends VCommand { - - public VersionCommand(String helpUsage, Predicate extended) { - super(helpUsage, extended); - } - - @Override - public void execute(Invocation invocation) { - sendVersion(invocation.source(), helpUsage, extended.test(invocation.source())); - } - } - - private class HelpCommand implements SimpleCommand { - - private final CommandNode node; - - private HelpCommand(CommandNode node) { - this.node = node; - } - - @Override - public void execute(Invocation invocation) { - sendHelp(invocation.source(), node); - } - } - - private class ReloadCommand implements SimpleCommand { - - @Override - public void execute(Invocation invocation) { - sendReload(invocation.source()); - } - } - - @Override - protected void runExecutor( - SimpleCommand executor, - SimpleCommand command, - CommandSource source, - String alias, - String[] context) { - executor.execute(new SimpleCommand.Invocation() { - @Override - public String alias() { - return alias; - } - - @Override - public CommandSource source() { - return source; - } - - @Override - public String @NonNull [] arguments() { - return context; - } - }); - } - - @Override - protected List getSuggestions( - SimpleCommand executor, - SimpleCommand command, - CommandSource source, - String alias, - String[] context) { - return executor.suggest(new SimpleCommand.Invocation() { - @Override - public String alias() { - return alias; - } - - @Override - public CommandSource source() { - return source; - } - - @Override - public String @NonNull [] arguments() { - return context; - } - }); - } - - @Override - protected SimpleCommand generateWrapperCommand(CommandExecutorWrapper command) { - return new WrapperCommand(command); - } - - @Override - public SimpleCommand generateRootCommand(String helpUsage, Predicate extended) { - return new RootCommand(helpUsage, extended); - } - - @Override - public SimpleCommand generateVersionCommand(String helpUsage, Predicate extended) { - return new VersionCommand(helpUsage, extended); - } - - @Override - public SimpleCommand generateHelpCommand(CommandNode node) { - return new HelpCommand(node); - } - - @Override - public SimpleCommand generateReloadCommand() { - return new ReloadCommand(); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/listener/VelocityPlayerListener.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/listener/VelocityPlayerListener.java deleted file mode 100644 index ba12511f4..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/listener/VelocityPlayerListener.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.listener; - -import com.google.inject.Inject; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.connection.LoginEvent; -import com.velocitypowered.api.event.player.PlayerChatEvent; -import com.velocitypowered.api.proxy.Player; -import net.kyori.adventure.identity.Identity; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.api.coremember.CoreMemberManager; -import org.anvilpowered.anvil.api.model.coremember.CoreMember; -import org.anvilpowered.anvil.api.plugin.PluginMessages; -import org.anvilpowered.anvil.api.registry.Keys; -import org.anvilpowered.anvil.api.registry.Registry; - -public class VelocityPlayerListener { - - @Inject - private CoreMemberManager coreMemberManager; - - @Inject - private PluginMessages pluginMessages; - - @Inject - private Registry registry; - - @Subscribe - public void onPlayerJoin(LoginEvent event) { - if (registry.getOrDefault(Keys.PROXY_MODE)) { - return; - } - Player player = event.getPlayer(); - coreMemberManager.getPrimaryComponent() - .getOneOrGenerateForUser( - player.getUniqueId(), - player.getUsername(), - player.getRemoteAddress().getHostString() - ).thenAcceptAsync(optionalMember -> { - if (!optionalMember.isPresent()) { - return; - } - CoreMember coreMember = optionalMember.get(); - if (coreMemberManager.getPrimaryComponent().checkBanned(coreMember)) { - player.disconnect( - pluginMessages.getBanMessage(coreMember.getBanReason(), coreMember.getBanEndUtc()) - ); - } - }).join(); - } - - @Subscribe - public void onPlayerChat(PlayerChatEvent event) { - if (registry.getOrDefault(Keys.PROXY_MODE)) { - return; - } - Player player = event.getPlayer(); - coreMemberManager.getPrimaryComponent() - .getOneForUser( - player.getUniqueId() - ).thenAcceptAsync(optionalMember -> { - if (!optionalMember.isPresent()) { - return; - } - CoreMember coreMember = optionalMember.get(); - if (coreMemberManager.getPrimaryComponent().checkMuted(coreMember)) { - event.setResult(PlayerChatEvent.ChatResult.denied()); - player.sendMessage( - Identity.nil(), - pluginMessages.getMuteMessage(coreMember.getMuteReason(), coreMember.getMuteEndUtc()) - ); - } - }).join(); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/ApiVelocityModule.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/ApiVelocityModule.java deleted file mode 100644 index 630dcf45f..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/ApiVelocityModule.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.module; - -import com.google.inject.TypeLiteral; -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import com.velocitypowered.api.proxy.Player; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.api.PlatformImpl; -import org.anvilpowered.anvil.api.command.CommandExecuteService; -import org.anvilpowered.anvil.api.command.CommandService; -import org.anvilpowered.anvil.api.misc.BindingExtensions; -import org.anvilpowered.anvil.api.server.LocationService; -import org.anvilpowered.anvil.api.util.KickService; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.anvilpowered.anvil.api.util.TextService; -import org.anvilpowered.anvil.api.util.UserService; -import org.anvilpowered.anvil.common.command.CommonCallbackCommand; -import org.anvilpowered.anvil.common.module.PlatformModule; -import org.anvilpowered.anvil.velocity.command.VelocityCallbackCommand; -import org.anvilpowered.anvil.velocity.command.VelocityCommandExecuteService; -import org.anvilpowered.anvil.velocity.command.VelocityCommandService; -import org.anvilpowered.anvil.velocity.server.VelocityLocationService; -import org.anvilpowered.anvil.velocity.util.VelocityKickService; -import org.anvilpowered.anvil.velocity.util.VelocityPermissionService; -import org.anvilpowered.anvil.velocity.util.VelocityTextService; -import org.anvilpowered.anvil.velocity.util.VelocityUserService; - -public class ApiVelocityModule extends PlatformModule { - - public ApiVelocityModule() { - super(new PlatformImpl(true, "velocity")); - } - - @Override - protected void configure() { - super.configure(); - bind(new TypeLiteral>() { - }).toProvider(BindingExtensions.asInternalProvider(VelocityCallbackCommand.class)); - bind(CommandExecuteService.class).to(VelocityCommandExecuteService.class); - bind(new TypeLiteral>() { - }).to(VelocityCommandService.class); - bind(KickService.class).to(VelocityKickService.class); - bind(LocationService.class).to(VelocityLocationService.class); - bind(PermissionService.class).to(VelocityPermissionService.class); - bind(new TypeLiteral>() { - }).to(VelocityTextService.class); - bind(new TypeLiteral>() { - }).to(VelocityUserService.class); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/VelocityModule.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/VelocityModule.java deleted file mode 100644 index e3bf60961..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/module/VelocityModule.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.module; - -import com.google.inject.TypeLiteral; -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.proxy.Player; -import net.kyori.adventure.text.TextComponent; -import ninja.leaping.configurate.commented.CommentedConfigurationNode; -import ninja.leaping.configurate.hocon.HoconConfigurationLoader; -import ninja.leaping.configurate.loader.ConfigurationLoader; -import org.anvilpowered.anvil.api.command.CommandNode; -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand; -import org.anvilpowered.anvil.common.module.CommonModule; -import org.anvilpowered.anvil.common.plugin.AnvilPluginInfo; -import org.anvilpowered.anvil.velocity.command.VelocityAnvilCommandNode; -import org.anvilpowered.anvil.velocity.command.regedit.VelocityRegistryEditRootCommand; - -import java.io.File; -import java.nio.file.Paths; - -public class VelocityModule extends CommonModule { - - @Override - protected void configure() { - super.configure(); - File configFilesLocation = Paths.get("plugins/" + AnvilPluginInfo.id).toFile(); - if (!configFilesLocation.exists()) { - if (!configFilesLocation.mkdirs()) { - throw new IllegalStateException("Unable to create config directory"); - } - } - bind(new TypeLiteral>() { - }).toInstance(HoconConfigurationLoader.builder().setPath(Paths.get(configFilesLocation + "/anvil.conf")).build()); - bind(new TypeLiteral>() { - }).to(VelocityAnvilCommandNode.class); - bind(new TypeLiteral>() { - }).to(VelocityRegistryEditRootCommand.class); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityKickService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityKickService.java deleted file mode 100644 index 029ebb776..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityKickService.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.util; - -import com.google.inject.Inject; -import com.velocitypowered.api.proxy.ProxyServer; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import org.anvilpowered.anvil.api.util.KickService; - -import java.util.UUID; - -public class VelocityKickService implements KickService { - - @Inject - private ProxyServer proxyServer; - - private TextComponent getReason(Object reason) { - return reason instanceof TextComponent ? (TextComponent) reason : Component.text(reason.toString()); - } - - @Override - public void kick(UUID userUUID, Object reason) { - proxyServer.getPlayer(userUUID).ifPresent(p -> p.disconnect(getReason(reason))); - } - - @Override - public void kick(String userName, Object reason) { - proxyServer.getPlayer(userName).ifPresent(p -> p.disconnect(getReason(reason))); - } - - @Override - public void kick(UUID userUUID) { - kick(userUUID, "You have been kicked"); - } - - @Override - public void kick(String userName) { - kick(userName, "You have been kicked"); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityPermissionService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityPermissionService.java deleted file mode 100644 index 3983b7173..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityPermissionService.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.util; - -import com.velocitypowered.api.permission.PermissionSubject; -import org.anvilpowered.anvil.api.util.PermissionService; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class VelocityPermissionService implements PermissionService { - - @Override - public boolean hasPermission(@Nullable Object subject, String permission) { - return subject instanceof PermissionSubject - && ((PermissionSubject) subject).hasPermission(permission); - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityTextService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityTextService.java deleted file mode 100644 index eed98b4f4..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityTextService.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.util; - -import com.google.inject.Inject; -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.proxy.ProxyServer; -import net.kyori.adventure.identity.Identified; -import net.kyori.adventure.identity.Identity; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; -import org.anvilpowered.anvil.common.util.CommonTextService; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; - -import java.net.URL; -import java.util.Deque; -import java.util.LinkedList; -import java.util.UUID; - -public class VelocityTextService extends CommonTextService { - - @Inject - private Logger logger; - - @Inject - protected ProxyServer proxyServer; - - @Override - public Builder builder() { - return new VelocityTextBuilder(); - } - - @Override - public void send(TextComponent text, CommandSource receiver) { - receiver.sendMessage(Identity.nil(), text); - } - - @Override - public void send(TextComponent text, CommandSource receiver, UUID sourceUUID) { - receiver.sendMessage(Identity.identity(sourceUUID), text); - } - - @Override - public void send(TextComponent text, CommandSource receiver, Object source) { - if (source instanceof Identified) { - receiver.sendMessage((Identified) source, text); - } else { - send(text, receiver); - } - } - - @Override - public CommandSource getConsole() { - return proxyServer.getConsoleCommandSource(); - } - - @Override - public TextComponent deserialize(String text) { - return LegacyComponentSerializer.legacyAmpersand().deserialize(text); - } - - @Override - public String serialize(TextComponent text) { - return LegacyComponentSerializer.legacyAmpersand().serialize(text); - } - - @Override - public String serializePlain(TextComponent text) { - return PlainComponentSerializer.plain().serialize(text.asComponent()); - } - - protected class VelocityTextBuilder extends CommonTextBuilder { - - private final Deque elements; - @Nullable - private HoverEvent hoverEvent; - @Nullable - private ClickEvent clickEvent; - - protected VelocityTextBuilder() { - elements = new LinkedList<>(); - } - - @Override - public Builder aqua() { - elements.add(NamedTextColor.AQUA); - return this; - } - - @Override - public Builder black() { - elements.add(NamedTextColor.BLACK); - return this; - } - - @Override - public Builder blue() { - elements.add(NamedTextColor.BLUE); - return this; - } - - @Override - public Builder dark_aqua() { - elements.add(NamedTextColor.DARK_AQUA); - return this; - } - - @Override - public Builder dark_blue() { - elements.add(NamedTextColor.DARK_BLUE); - return this; - } - - @Override - public Builder dark_gray() { - elements.add(NamedTextColor.DARK_GRAY); - return this; - } - - @Override - public Builder dark_green() { - elements.add(NamedTextColor.DARK_GREEN); - return this; - } - - @Override - public Builder dark_purple() { - elements.add(NamedTextColor.DARK_PURPLE); - return this; - } - - @Override - public Builder dark_red() { - elements.add(NamedTextColor.DARK_RED); - return this; - } - - @Override - public Builder gold() { - elements.add(NamedTextColor.GOLD); - return this; - } - - @Override - public Builder gray() { - elements.add(NamedTextColor.GRAY); - return this; - } - - @Override - public Builder green() { - elements.add(NamedTextColor.GREEN); - return this; - } - - @Override - public Builder light_purple() { - elements.add(NamedTextColor.LIGHT_PURPLE); - return this; - } - - @Override - public Builder red() { - elements.add(NamedTextColor.RED); - return this; - } - - @Override - public Builder reset() { - elements.add(NamedTextColor.WHITE); - return this; - } - - @Override - public Builder white() { - elements.add(NamedTextColor.WHITE); - return this; - } - - @Override - public Builder yellow() { - elements.add(NamedTextColor.YELLOW); - return this; - } - - @Override - public Builder bold() { - elements.add(TextDecoration.BOLD); - return this; - } - - @Override - public Builder italic() { - elements.add(TextDecoration.ITALIC); - return this; - } - - @Override - public Builder obfuscated() { - elements.add(TextDecoration.OBFUSCATED); - return this; - } - - @Override - public Builder strikethrough() { - elements.add(TextDecoration.STRIKETHROUGH); - return this; - } - - @Override - public Builder underlined() { - elements.add(TextDecoration.UNDERLINED); - return this; - } - - @Override - public Builder append(Object... contents) { - for (Object o : contents) { - if (o instanceof Builder || o instanceof Component || o instanceof TextColor) { - elements.add(o); - } else { - elements.add(Component.text(String.valueOf(o))); - } - } - return this; - } - - @Override - public Builder appendJoining( - Object delimiter, Object... contents) { - if (!(delimiter instanceof Builder || delimiter instanceof Component)) { - delimiter = Component.text(delimiter.toString()); - } - final int indexOfLast = contents.length - 1; - for (int i = 0; i <= indexOfLast; i++) { - Object o = contents[i]; - if (o instanceof Builder || o instanceof Component || o instanceof TextColor) { - elements.add(o); - } else { - elements.add(Component.text(String.valueOf(o))); - } - if (i != indexOfLast) { - elements.add(delimiter); - } - } - return this; - } - - @Override - public Builder onHoverShowText(TextComponent text) { - hoverEvent = HoverEvent.showText(text); - return this; - } - - @Override - public Builder onClickSuggestCommand(String command) { - callback = null; - clickEvent = ClickEvent.suggestCommand(command); - return this; - } - - @Override - public Builder onClickRunCommand(String command) { - callback = null; - clickEvent = ClickEvent.runCommand(command); - return this; - } - - @Override - public Builder onClickOpenUrl(URL url) { - return onClickOpenUrl(url.toString()); - } - - @Override - public Builder onClickOpenUrl(String url) { - callback = null; - clickEvent = ClickEvent.openUrl(url); - return this; - } - - @Override - @SuppressWarnings("unchecked") - public TextComponent build() { - boolean hover = hoverEvent != null; - if (callback != null) { - initializeCallback(); - } - boolean click = clickEvent != null; - - if (elements.isEmpty()) { - return Component.empty(); - } else if (elements.size() == 1 && !hover && !click) { - Object o = elements.getFirst(); - if (o instanceof Builder) { - return ((Builder) o).build(); - } else if (o instanceof TextComponent) { - return (TextComponent) o; - } - } - - // one builder for every color - final Deque components = new LinkedList<>(); - - // create first builder - TextComponent.Builder currentBuilder = Component.text(); - Object firstColor = elements.peekFirst(); - if (firstColor instanceof TextColor) { - currentBuilder.color((TextColor) firstColor); - elements.pollFirst(); // remove color because its already added to builder - } - - for (Object o : elements) { - if (o instanceof Builder) { - currentBuilder.append(((Builder) o).build()); - } else if (o instanceof Component) { - currentBuilder.append((Component) o); - } else if (o instanceof TextColor) { - // build current builder - components.offer(currentBuilder.build()); - // create new builder starting at this point until the next color - currentBuilder = Component.text().color((TextColor) o); - } else { - logger.error("Skipping {} because it does not match any of the correct types.", o); - } - } - - // build last builder - components.offer(currentBuilder.build()); - - // create new builder with all previous components - currentBuilder = Component.text().append(components); - - if (hover) { - currentBuilder.hoverEvent(hoverEvent); - } - if (click) { - currentBuilder.clickEvent(clickEvent); - } - return currentBuilder.build(); - } - } -} diff --git a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityUserService.java b/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityUserService.java deleted file mode 100644 index 75a3af514..000000000 --- a/anvil-velocity/src/main/java/org/anvilpowered/anvil/velocity/util/VelocityUserService.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.util; - -import com.google.inject.Inject; -import com.velocitypowered.api.proxy.Player; -import com.velocitypowered.api.proxy.ProxyServer; -import org.anvilpowered.anvil.common.util.CommonUserService; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -public class VelocityUserService extends CommonUserService { - - @Inject - private ProxyServer proxyServer; - - @Inject - public VelocityUserService() { - super(Player.class); - } - - @Override - public Optional get(String userName) { - return proxyServer.getPlayer(userName); - } - - @Override - public Optional get(UUID userUUID) { - return proxyServer.getPlayer(userUUID); - } - - @Override - public Optional getPlayer(String userName) { - return get(userName); - } - - @Override - public Optional getPlayer(UUID userUUID) { - return get(userUUID); - } - - @Override - public Optional getPlayer(Player player) { - return Optional.of(player); - } - - @Override - public List matchPlayerNames(String startsWith) { - String startsWithLowerCase = startsWith.toLowerCase(); - return getOnlinePlayers().stream() - .map(Player::getUsername) - .filter(name -> name.toLowerCase().startsWith(startsWithLowerCase)) - .collect(Collectors.toList()); - } - - @Override - public Collection getOnlinePlayers() { - return proxyServer.getAllPlayers(); - } - - @Override - public CompletableFuture> getUUID(String userName) { - Optional userUUID = getPlayer(userName).map(Player::getUniqueId); - if (userUUID.isPresent()) { - return CompletableFuture.completedFuture(userUUID); - } - return super.getUUID(userName); - } - - @Override - public CompletableFuture> getUserName(UUID userUUID) { - Optional userName = getPlayer(userUUID).map(Player::getUsername); - if (userName.isPresent()) { - return CompletableFuture.completedFuture(userName); - } - return super.getUserName(userUUID); - } - - @Override - public UUID getUUID(Player player) { - return player.getUniqueId(); - } - - @Override - public String getUserName(Player player) { - return player.getUsername(); - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCancelCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCancelCommand.kt deleted file mode 100644 index faf84b5c1..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCancelCommand.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCancelCommand - -class VelocityRegistryEditCancelCommand - : CommonRegistryEditCancelCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) { - super.execute(invocation.source(), invocation.arguments()) - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommandNode.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommandNode.kt deleted file mode 100644 index 8c707cec4..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommandNode.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.google.inject.Inject -import com.google.inject.Singleton -import com.velocitypowered.api.command.Command -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import org.anvilpowered.anvil.api.registry.Registry -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommandNode -import java.util.HashMap - -@Singleton -class VelocityRegistryEditCommandNode @Inject constructor( - registry: Registry, -) : CommonRegistryEditCommandNode(registry) { - - @Inject - private lateinit var registryEditCancelCommand: VelocityRegistryEditCancelCommand - - @Inject - private lateinit var registryEditCommitCommand: VelocityRegistryEditCommitCommand - - @Inject - private lateinit var registryEditKeyCommand: VelocityRegistryEditKeyCommand - - @Inject - private lateinit var registryEditSelectCommand: VelocityRegistryEditSelectCommand - - @Inject - private lateinit var registryEditStartCommand: VelocityRegistryEditStartCommand - - val subCommands: MutableMap, SimpleCommand> = HashMap() - - override fun loadCommands() { - subCommands[CANCEL_ALIAS] = registryEditCancelCommand - subCommands[COMMIT_ALIAS] = registryEditCommitCommand - subCommands[KEY_ALIAS] = registryEditKeyCommand - subCommands[SELECT_ALIAS] = registryEditSelectCommand - subCommands[START_ALIAS] = registryEditStartCommand - subCommands[HELP_ALIAS] = commandService.generateHelpCommand(this) - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommitCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommitCommand.kt deleted file mode 100644 index 2da7752b5..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditCommitCommand.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditCommitCommand - -class VelocityRegistryEditCommitCommand - : CommonRegistryEditCommitCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) { - super.execute(invocation.source(), invocation.arguments()) - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditKeyCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditKeyCommand.kt deleted file mode 100644 index 548e618d4..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditKeyCommand.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditKeyCommand - -class VelocityRegistryEditKeyCommand - : CommonRegistryEditKeyCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) = - super.execute(invocation.source(), invocation.arguments()) - - override fun suggest(invocation: SimpleCommand.Invocation): List = - super.suggest(invocation.source(), invocation.arguments()) -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditRootCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditRootCommand.kt deleted file mode 100644 index c9e0b8f02..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditRootCommand.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.google.inject.Singleton -import com.velocitypowered.api.command.Command -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditRootCommand - -@Singleton -class VelocityRegistryEditRootCommand - : CommonRegistryEditRootCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) { - super.execute(invocation.source(), invocation.arguments()) - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditSelectCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditSelectCommand.kt deleted file mode 100644 index 6f103034b..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditSelectCommand.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditSelectCommand - -class VelocityRegistryEditSelectCommand - : CommonRegistryEditSelectCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) = - super.execute(invocation.source(), invocation.arguments()) - - override fun suggest(invocation: SimpleCommand.Invocation): List = - super.suggest(invocation.source(), invocation.arguments()) -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditStartCommand.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditStartCommand.kt deleted file mode 100644 index 538853aff..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/regedit/VelocityRegistryEditStartCommand.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.anvilpowered.anvil.velocity.command.regedit - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import com.velocitypowered.api.proxy.Player -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.command.regedit.CommonRegistryEditStartCommand - -class VelocityRegistryEditStartCommand - : CommonRegistryEditStartCommand(), SimpleCommand { - override fun execute(invocation: SimpleCommand.Invocation) = - super.execute(invocation.source(), invocation.arguments()) - - override fun suggest(invocation: SimpleCommand.Invocation): List = - super.suggest(invocation.source(), invocation.arguments()) -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityBackendServer.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityBackendServer.kt deleted file mode 100644 index dfc3d5bb6..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityBackendServer.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.server - -import com.velocitypowered.api.proxy.Player -import com.velocitypowered.api.proxy.server.RegisteredServer -import org.anvilpowered.anvil.api.util.UserService -import org.anvilpowered.anvil.common.server.CommonBackendServer -import java.util.Optional -import java.util.UUID -import java.util.concurrent.CompletableFuture -import kotlin.streams.toList - -class VelocityBackendServer( - private val server: RegisteredServer, - userService: UserService, -) : CommonBackendServer(userService) { - override fun getName(): String = server.serverInfo.name - override fun getVersion(): CompletableFuture { - return server.ping().thenApply { VelocityVersion(it.version) } - } - override fun Optional.connect(): CompletableFuture { - return map { it.createConnectionRequest(server).connect().thenApply { c -> c.isSuccessful } } - .orElse(CompletableFuture.completedFuture(false)) - } - - override fun connect(player: Any?): CompletableFuture = Optional.ofNullable(player as? Player).connect() - override fun getPlayerUUIDs(): List = server.playersConnected.stream().map { it.uniqueId }.toList() -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityLocationService.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityLocationService.kt deleted file mode 100644 index 37c7accf8..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityLocationService.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.server - -import com.google.inject.Inject -import com.velocitypowered.api.proxy.Player -import com.velocitypowered.api.proxy.ProxyServer -import org.anvilpowered.anvil.api.util.UserService -import org.anvilpowered.anvil.common.server.CommonLocationService -import java.util.Optional -import java.util.UUID -import kotlin.streams.toList - -class VelocityLocationService : CommonLocationService() { - - @Inject - private lateinit var proxyServer: ProxyServer - - @Inject - private lateinit var userService: UserService - - private fun Optional.getServer(): Optional { - return flatMap { it.currentServer }.map { VelocityBackendServer(it.server, userService) } - } - - override fun getServer(userUUID: UUID): Optional = userService.getPlayer(userUUID).getServer() - override fun getServer(userName: String): Optional = userService.getPlayer(userName).getServer() - override fun getServerForName(serverName: String): Optional { - return proxyServer.getServer(serverName).map { VelocityBackendServer(it, userService) } - } - - override fun getServers(): List { - return proxyServer.allServers.stream().map { VelocityBackendServer(it, userService) }.toList() - } -} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityVersion.kt b/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityVersion.kt deleted file mode 100644 index 6d33d1f32..000000000 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/server/VelocityVersion.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package org.anvilpowered.anvil.velocity.server - -import com.velocitypowered.api.proxy.server.ServerPing -import org.anvilpowered.anvil.api.server.Version - -class VelocityVersion( - val version: ServerPing.Version -) : Version { - override fun getName(): String = version.name - override fun getProtocol(): Int = version.protocol -} diff --git a/api/build.gradle.kts b/api/build.gradle.kts deleted file mode 100644 index c2fce59a5..000000000 --- a/api/build.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -@Suppress("DSL_SCOPE_VIOLATION") -plugins { - `java-library` - alias(libs.plugins.kotlin.jvm) -} - -val apiVersion: String by rootProject -version = apiVersion - -dependencies { - api(libs.coroutines) - api(libs.bson) - api(libs.configurate.core) - api(libs.flow.math) - api(libs.guice) - api(libs.jetbrains.annotations) - api(libs.mongo.driver.sync) - api(libs.morphia) - api(libs.reflections) - api(libs.xodus.entity.store) -} - -java { - withSourcesJar() - withJavadocJar() -} diff --git a/app/plugin/build.gradle.kts b/app/plugin/build.gradle.kts new file mode 100644 index 000000000..13f9e2439 --- /dev/null +++ b/app/plugin/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + alias(libs.plugins.shadow) +} + +dependencies { + implementation(project(":anvil-app-plugin-paper")) + implementation(project(":anvil-app-plugin-sponge")) + implementation(project(":anvil-app-plugin-velocity")) +} + +tasks { + shadowJar { + archiveFileName = "anvil-agent-${project.version}.jar" + } +} diff --git a/app/plugin/core/build.gradle.kts b/app/plugin/core/build.gradle.kts new file mode 100644 index 000000000..d6d13c134 --- /dev/null +++ b/app/plugin/core/build.gradle.kts @@ -0,0 +1,7 @@ +dependencies { + api(project(":anvil-core")) + api(platform(libs.adventure.bom)) + compileOnlyApi("net.kyori:adventure-api") +// compileOnlyApi(libs.logging.api) + api(libs.kbrig.brigadier) +} diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPlugin.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPlugin.kt new file mode 100644 index 000000000..22615d1dc --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPlugin.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.plugin.command.AnvilCommandFactory +import org.anvilpowered.kbrig.tree.LiteralCommandNode +import org.apache.logging.log4j.Logger + +abstract class AnvilPlugin( + private val logger: Logger, + private val anvilCommandFactory: AnvilCommandFactory, +) { + fun registerCommands(registrationCallback: (LiteralCommandNode) -> Unit) { + logger.info("Building command tree...") + val command = anvilCommandFactory.create() + logger.info("Registering commands...") + registrationCallback(command) + logger.info("Finished registering commands.") + } +} diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/PluginMessages.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/PluginMessages.kt new file mode 100644 index 000000000..0b2272c45 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/PluginMessages.kt @@ -0,0 +1,28 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor + +object PluginMessages { + val pluginPrefix = Component.text("[Anvil Agent] ").color(NamedTextColor.GOLD) + val notEnoughArgs = Component.text("Not enough arguments!").color(NamedTextColor.RED) + val noPermission = Component.text("Insufficient Permissions!").color(NamedTextColor.RED) +} diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/AnvilCommandFactory.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/AnvilCommandFactory.kt new file mode 100644 index 000000000..5cf8845c0 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/AnvilCommandFactory.kt @@ -0,0 +1,40 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command + +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.plugin.command.common.addHelp +import org.anvilpowered.anvil.plugin.command.plugin.PluginCommandFactory +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +private val children = mapOf( + "help" to Component.text("Shows this help message"), + "plugin" to Component.text("Plugin management"), + "version" to Component.text("Shows the Anvil Agent version"), +) + +class AnvilCommandFactory(private val pluginCommandFactory: PluginCommandFactory) { + fun create(): LiteralCommandNode = + ArgumentBuilder.literal("anvil") + .addHelp("anvil", children) + .then(pluginCommandFactory.create()) + .build() +} diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/common/Help.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/common/Help.kt new file mode 100644 index 000000000..e6781b5ce --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/common/Help.kt @@ -0,0 +1,80 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.common + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.JoinConfiguration +import net.kyori.adventure.text.format.NamedTextColor +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.plugin.PluginMessages +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.builder.executesSingleSuccess + +// TODO: Idea: Automatically detect usage from command node tree + +fun > B.executesUsage(usage: String): B = + executes { + it.source.audience.sendMessage( + Component.text() + .append(PluginMessages.pluginPrefix) + .append(Component.text("Command usage: ", NamedTextColor.GOLD)) + .append(Component.text("/$usage", NamedTextColor.AQUA)), + ) + 0 + } + +fun > B.addHelp(baseName: String, children: Map): B = + executes { context -> + context.source.audience.sendMessage( + Component.text() + .append(PluginMessages.pluginPrefix) + .append(Component.text("Command usage: ", NamedTextColor.GOLD)) + .append(Component.text("/$baseName", NamedTextColor.GREEN)) + .append(Component.space()) + .append(Component.text("${children.keys.joinToString("|")} ...", NamedTextColor.GREEN)) + .append(Component.newline()) + .append(Component.text("For more information see ", NamedTextColor.AQUA)) + .append(Component.text("/$baseName help", NamedTextColor.GREEN)), + ) + 0 + }.then( + ArgumentBuilder.literal("help").executesSingleSuccess { context -> + context.source.audience.sendMessage( + Component.text() + .append(PluginMessages.pluginPrefix) + .append(Component.text("Command usage: ", NamedTextColor.GOLD)) + .append(Component.text("/$baseName", NamedTextColor.GREEN)) + .append(Component.newline()) + .append(Component.text("Subcommands:", NamedTextColor.AQUA)) + .append(Component.newline()) + .append( + Component.join( + JoinConfiguration.newlines(), + children.map { (command, description) -> + Component.text() + .append(Component.text(" /$baseName ", NamedTextColor.DARK_GRAY)) + .append(Component.text(command, NamedTextColor.GREEN)) + .append(Component.space()) + .append(description.color(NamedTextColor.GRAY)) + }, + ), + ), + ) + }, + ) diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/GameUserCommand.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/GameUserCommand.kt new file mode 100644 index 000000000..dc0ae8c07 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/GameUserCommand.kt @@ -0,0 +1,41 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.gameuser + +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.user.requiresPermission +import org.anvilpowered.anvil.plugin.command.common.addHelp +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +private val children = mapOf( + "help" to Component.text("Shows this help message"), + "info" to Component.text("Shows information about a game user"), +) + +object GameUserCommand { + context(AnvilApi) + fun create(): LiteralCommandNode = + ArgumentBuilder.literal("gameuser") + .addHelp("anvil gameuser", children) + .requiresPermission("anvil.agent.gameuser") + .build() +} diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/Info.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/Info.kt new file mode 100644 index 000000000..5352e2dad --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/gameuser/Info.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.gameuser + +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.plugin.command.common.executesUsage +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +private val children = mapOf( + "help" to Component.text("Shows this help message"), + "info" to Component.text("Shows information about a game user"), +) + +context(AnvilApi) +fun GameUserCommand.createInfo(): LiteralCommandNode = + ArgumentBuilder.literal("info") + .executesUsage("anvil gameuser info ") + .build() diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/Info.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/Info.kt new file mode 100644 index 000000000..bf24c7393 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/Info.kt @@ -0,0 +1,56 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.plugin + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.plugin.command.common.executesUsage +import org.anvilpowered.kbrig.Command +import org.anvilpowered.kbrig.argument.StringArgumentType +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.context.get +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +fun PluginCommandFactory.createInfo(): LiteralCommandNode = + ArgumentBuilder.literal("info") + .executesUsage("anvil plugin info ") + .then( + ArgumentBuilder.required("name", StringArgumentType.SingleWord) + .executes { context -> + val name = context.get("name") + val plugin = pluginManager.plugins.find { it.name == name } + if (plugin == null) { + context.source.audience.sendMessage( + Component.text() + .append(Component.text("Plugin not found: ").color(NamedTextColor.RED)) + .append(Component.text(name).color(NamedTextColor.WHITE)), + ) + 0 + } else { + context.source.audience.sendMessage( + Component.text() + .append(Component.text("Plugin: ").color(NamedTextColor.AQUA)) + .append(Component.text(plugin.name).color(NamedTextColor.WHITE)), + ) + Command.SINGLE_SUCCESS + } + } + .build(), + ).build() diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/List.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/List.kt new file mode 100644 index 000000000..8faa88d29 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/List.kt @@ -0,0 +1,35 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.plugin + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.builder.executesSingleSuccess +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +fun PluginCommandFactory.createList(): LiteralCommandNode = + ArgumentBuilder.literal("list") + .executesSingleSuccess { context -> + val pluginNamesString = pluginManager.plugins.joinToString(", ") { it.name } + context.source.audience.sendMessage( + Component.text("Plugins: $pluginNamesString").color(NamedTextColor.AQUA), + ) + }.build() diff --git a/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/PluginCommandFactory.kt b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/PluginCommandFactory.kt new file mode 100644 index 000000000..c2f128b27 --- /dev/null +++ b/app/plugin/core/src/main/kotlin/org/anvilpowered/anvil/plugin/command/plugin/PluginCommandFactory.kt @@ -0,0 +1,43 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin.command.plugin + +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.platform.PluginManager +import org.anvilpowered.anvil.core.user.requiresPermission +import org.anvilpowered.anvil.plugin.command.common.addHelp +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.tree.LiteralCommandNode + +private val children = mapOf( + "help" to Component.text("Shows this help message"), + "list" to Component.text("Lists all plugins"), + "info " to Component.text("Shows information about a plugin"), +) + +class PluginCommandFactory(val pluginManager: PluginManager) { + fun create(): LiteralCommandNode = + ArgumentBuilder.literal("plugin") + .addHelp("anvil plugin", children) + .requiresPermission("anvil.agent.plugin") + .then(createList()) + .then(createInfo()) + .build() +} diff --git a/app/plugin/paper/build.gradle.kts b/app/plugin/paper/build.gradle.kts new file mode 100644 index 000000000..410816522 --- /dev/null +++ b/app/plugin/paper/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.shadow) + alias(libs.plugins.pluginyml) +} + +dependencies { + implementation(project(":anvil-app-plugin-core")) + implementation(project(":anvil-paper")) + compileOnly(libs.brigadier) + compileOnly(libs.paper) +} + +paper { + name = "anvil-agent" + main = "org.anvilpowered.anvil.plugin.AnvilPaperPluginBootstrap" + foliaSupported = true + apiVersion = "1.19" + authors = rootProject.file("authors").readLines().map { it.substringBefore(',') } +} diff --git a/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPlugin.kt b/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPlugin.kt new file mode 100644 index 000000000..709ca5eea --- /dev/null +++ b/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPlugin.kt @@ -0,0 +1,33 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +@file:Suppress("UnstableApiUsage") + +package org.anvilpowered.anvil.plugin + +import io.papermc.paper.event.server.ServerResourcesLoadEvent +import org.anvilpowered.anvil.paper.command.toPaper +import org.bukkit.plugin.Plugin + +class AnvilPaperPlugin(private val plugin: AnvilPlugin) { + fun registerCommands(bootstrap: Plugin, event: ServerResourcesLoadEvent) { + plugin.registerCommands { command -> + event.commands.register(bootstrap.pluginMeta, command.toPaper()) + } + } +} diff --git a/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPluginBootstrap.kt b/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPluginBootstrap.kt new file mode 100644 index 000000000..b0309d107 --- /dev/null +++ b/app/plugin/paper/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilPaperPluginBootstrap.kt @@ -0,0 +1,53 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +@file:Suppress("UnstableApiUsage") + +package org.anvilpowered.anvil.plugin + +import io.papermc.paper.event.server.ServerResourcesLoadEvent +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.paper.createPaper +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.plugin.java.JavaPlugin +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.koinApplication +import org.koin.dsl.module + +class AnvilPaperPluginBootstrap : JavaPlugin(), Listener { + + private lateinit var plugin: AnvilPaperPlugin + + override fun onEnable() { + logger.info { "Registering events" } + server.pluginManager.registerEvents(this, this) + plugin = koinApplication { + modules( + AnvilApi.createPaper().module, + module { singleOf(::AnvilPaperPlugin) }, + ) + }.koin.get() + } + + @EventHandler + fun load(event: ServerResourcesLoadEvent) { + logger.info { "Load event" } + plugin.registerCommands(this, event) + } +} diff --git a/app/plugin/sponge/build.gradle.kts b/app/plugin/sponge/build.gradle.kts new file mode 100644 index 000000000..ff047b646 --- /dev/null +++ b/app/plugin/sponge/build.gradle.kts @@ -0,0 +1,36 @@ +import org.spongepowered.gradle.plugin.config.PluginLoaders + +plugins { + alias(libs.plugins.sponge) + alias(libs.plugins.shadow) +} + +// TODO: Should not be necessary, but it seems sponge is nuking the repositories define in settings +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + implementation(project(":anvil-app-plugin-core")) + implementation(project(":anvil-sponge")) + compileOnly(libs.brigadier) +} + +sponge { + apiVersion("8.1.0-SNAPSHOT") + license("AGPL-3.0") + loader { + name(PluginLoaders.JAVA_PLAIN) + version("1.0") + } + plugin("anvil-agent") { + displayName("Anvil Agent") + version.set(project.version.toString()) + entrypoint("org.anvilpowered.anvil.agent.AnvilSpongePlugin") + description("Agent plugin for the Anvil system") +// dependency("spongeapi") { +// loadOrder(LoadOrder.AFTER) +// } + } +} diff --git a/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePlugin.kt b/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePlugin.kt new file mode 100644 index 000000000..a7bac6560 --- /dev/null +++ b/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePlugin.kt @@ -0,0 +1,27 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import com.mojang.brigadier.tree.LiteralCommandNode +import org.spongepowered.api.event.lifecycle.RegisterCommandEvent + +class AnvilSpongePlugin(private val plugin: AnvilPlugin) { + fun registerCommands(event: RegisterCommandEvent>) { + } +} diff --git a/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePluginBootstrap.kt b/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePluginBootstrap.kt new file mode 100644 index 000000000..96f07fe9f --- /dev/null +++ b/app/plugin/sponge/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilSpongePluginBootstrap.kt @@ -0,0 +1,36 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import com.google.inject.Inject +import org.apache.logging.log4j.Logger +import org.spongepowered.api.event.Listener +import org.spongepowered.api.event.lifecycle.ConstructPluginEvent +import org.spongepowered.plugin.builtin.jvm.Plugin + +@Plugin("anvil-agent") +class AnvilSpongePluginBootstrap @Inject constructor( + private val logger: Logger, +) { + + @Listener + fun onServerStart(event: ConstructPluginEvent) { + logger.warn("Hello, world! ${event.plugin()}") + } +} diff --git a/app/plugin/velocity/build.gradle.kts b/app/plugin/velocity/build.gradle.kts new file mode 100644 index 000000000..ff0c12f5e --- /dev/null +++ b/app/plugin/velocity/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + kotlin("kapt") +} + +dependencies { + implementation(project(":anvil-app-plugin-core")) + implementation(project(":anvil-velocity")) + compileOnly(libs.velocity) + kapt(libs.velocity) + implementation(libs.kbrig.brigadier) +} diff --git a/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPlugin.kt b/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPlugin.kt new file mode 100644 index 000000000..4ea01f456 --- /dev/null +++ b/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPlugin.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import com.velocitypowered.api.command.BrigadierCommand +import com.velocitypowered.api.proxy.ProxyServer +import org.anvilpowered.anvil.velocity.AnvilVelocityApi +import org.anvilpowered.anvil.velocity.command.toVelocity + +context(AnvilVelocityApi) +class AnvilVelocityPlugin( + private val proxyServer: ProxyServer, + private val plugin: AnvilPlugin, +) { + + fun registerCommands() { + plugin.registerCommands { command -> + proxyServer.commandManager.register(BrigadierCommand(command.toVelocity())) + } + } +} diff --git a/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPluginBootstrap.kt b/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPluginBootstrap.kt new file mode 100644 index 000000000..1333bc05e --- /dev/null +++ b/app/plugin/velocity/src/main/kotlin/org/anvilpowered/anvil/plugin/AnvilVelocityPluginBootstrap.kt @@ -0,0 +1,57 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.plugin + +import com.google.inject.Inject +import com.google.inject.Injector +import com.velocitypowered.api.event.Subscribe +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent +import com.velocitypowered.api.plugin.Plugin +import com.velocitypowered.api.proxy.ProxyServer +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.velocity.createVelocity +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.koinApplication +import org.koin.dsl.module + +@Plugin( + id = "anvil-agent", + name = "Anvil Agent", + version = "0.4.0-SNAPSHOT", + authors = ["AnvilPowered"], +) +class AnvilVelocityPluginBootstrap @Inject constructor( + private val proxyServer: ProxyServer, + private val injector: Injector, +) { + + private lateinit var plugin: AnvilVelocityPlugin + + @Subscribe + fun onProxyInit(event: ProxyInitializeEvent) { + plugin = koinApplication { + modules( + AnvilApi.createVelocity(injector).module, + module { singleOf(::AnvilVelocityPlugin) }, + ) + }.koin.get() + plugin.registerCommands() + proxyServer.eventManager.register(this, plugin) + } +} diff --git a/authors b/authors new file mode 100644 index 000000000..6f52bd28f --- /dev/null +++ b/authors @@ -0,0 +1 @@ +alexstaeding,Alexander Städing diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts new file mode 100644 index 000000000..b51d43bb2 --- /dev/null +++ b/build-logic/build.gradle.kts @@ -0,0 +1,20 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") +} + +tasks { + withType { + kotlinOptions.jvmTarget = "17" + } + withType { + options.encoding = "UTF-8" + sourceCompatibility = "17" + targetCompatibility = "17" + } +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 000000000..1d2545453 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,15 @@ +@file:Suppress("UnstableApiUsage") + +dependencyResolutionManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } + versionCatalogs { + register("libs") { + from(files("../gradle/libs.versions.toml")) // include from parent project + } + } +} + +rootProject.name = "build-logic" diff --git a/build-logic/src/main/kotlin/anvil-publish.gradle.kts b/build-logic/src/main/kotlin/anvil-publish.gradle.kts new file mode 100644 index 000000000..21cf6fa47 --- /dev/null +++ b/build-logic/src/main/kotlin/anvil-publish.gradle.kts @@ -0,0 +1,49 @@ +import java.net.URI + +plugins { + `maven-publish` +} + +extensions.configure { + withJavadocJar() + withSourcesJar() +} + +extensions.configure { + repositories { + maven { + credentials { + username = project.findProperty("sonatypeUsername") as? String + password = project.findProperty("sonatypePassword") as? String + } + val releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" + val snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots" + url = URI(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl) + } + } + publications.register("maven") { + from(components["java"]) + pom { + name.set("anvil") + url.set("https://www.anvilpowered.org") + scm { + url.set("https://github.com/anvilpowered/anvil") + connection.set("scm:git:https://github.com/anvilpowered/anvil.git") + developerConnection.set("scm:git:https://github.com/anvilpowered/anvil.git") + } + licenses { + license { + name.set("GNU AFFERO GENERAL PUBLIC LICENSE Version 3") + url.set("https://www.gnu.org/licenses/agpl-3.0.html") + distribution.set("repo") + } + } + developers { + rootProject.file("authors").readLines() + .asSequence() + .map { it.split(",") } + .forEach { (_id, _name) -> developer { id.set(_id); name.set(_name) } } + } + } + } +} diff --git a/build.gradle.kts b/build.gradle.kts index ae2ee5a9b..ccbe5071a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,50 +1,38 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -@Suppress("DSL_SCOPE_VIOLATION") plugins { - `java-library` alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.ktlint) } val projectVersion = file("version").readLines().first() -project.extra["apiVersion"] = projectVersion.replace(".[0-9]+(?=($|-SNAPSHOT))".toRegex(), "") allprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "org.jlleitschuh.gradle.ktlint") + apply(plugin = "java-library") group = "org.anvilpowered" version = projectVersion project.findProperty("buildNumber") ?.takeIf { version.toString().contains("SNAPSHOT") } ?.also { version = version.toString().replace("SNAPSHOT", "RC$it") } + kotlin { + compilerOptions { + freeCompilerArgs = listOf( + "-opt-in=kotlin.RequiresOptIn", + "-Xcontext-receivers", + ) + } + } + tasks { withType { kotlinOptions.jvmTarget = "17" - kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" } withType { options.encoding = "UTF-8" - targetCompatibility = "17" sourceCompatibility = "17" - } - } -} - -// include legacy java code during migration to kotlin -subprojects { - apply(plugin = "java") - apply(plugin = "org.jetbrains.kotlin.jvm") - val legacyName = when (this@subprojects.name) { - "anvil-core" -> "anvil-common" - "anvil-paper" -> "anvil-spigot" - else -> this@subprojects.name - } - java { - sourceSets.main.configure { - java.srcDir("../$legacyName/src/main/java") - } - } - kotlin { - sourceSets.main.configure { - kotlin.srcDir("../$legacyName/src/main/kotlin") + targetCompatibility = "17" } } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 57439e3f1..870440ad1 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,11 +1,20 @@ -@Suppress("DSL_SCOPE_VIOLATION") plugins { - alias(libs.plugins.kotlin.jvm) + id("anvil-publish") + `java-library` } dependencies { - api(project(":anvil-api")) - api(libs.kotlin.reflect) - api(libs.configurate.hocon) - implementation(libs.reflections) + api(platform(libs.exposed.bom)) + api(libs.bundles.exposed) + api(libs.kbrig.brigadier) + api(libs.logging.api) + api(libs.configurate.core) + api(libs.annotations) + api(libs.kotlinx.coroutines) + api(libs.guava) + api(libs.koin) + + compileOnlyApi(platform(libs.adventure.bom)) + compileOnlyApi("net.kyori:adventure-api") + compileOnlyApi("net.kyori:adventure-text-minimessage") } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/AnvilApi.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/AnvilApi.kt new file mode 100644 index 000000000..9147b6b46 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/AnvilApi.kt @@ -0,0 +1,43 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core + +import org.koin.core.module.Module + +/** + * To create an instance of this interface, use the `AnvilApi.create` function. + * This is available for each platform in the corresponding `anvil-` module. + * + * Generally, the method will look something like this: + * ```kt + * AnvilApi.create<<>>("my-plugin", ....) + * ``` + * + * For example, for Velocity: + * + * ```kt + * AnvilApi.createVelocity("my-plugin", ....) + * ``` + */ +interface AnvilApi { + + val module: Module + + companion object +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/ModuleExtensions.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/ModuleExtensions.kt deleted file mode 100644 index 8a5ad845c..000000000 --- a/core/src/main/kotlin/org/anvilpowered/anvil/core/ModuleExtensions.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.anvilpowered.anvil.core - -import com.google.inject.Binder -import com.google.inject.binder.AnnotatedBindingBuilder -import com.google.inject.binder.LinkedBindingBuilder -import com.google.inject.binder.ScopedBindingBuilder - -inline fun Binder.bind(): AnnotatedBindingBuilder = bind(T::class.java) - -inline fun LinkedBindingBuilder.to(): ScopedBindingBuilder = to(T::class.java) diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginInfo.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/PlatformType.kt similarity index 58% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginInfo.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/PlatformType.kt index 7b38af15d..adff97806 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginInfo.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/PlatformType.kt @@ -1,24 +1,24 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.plugin; +package org.anvilpowered.anvil.core -public interface PluginInfo extends BasicPluginInfo { +interface PlatformType { - TString getPrefix(); + val platformDelegate: Any } diff --git a/anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/EntityUtils.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandExecutor.kt similarity index 53% rename from anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/EntityUtils.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandExecutor.kt index f0e7caedc..b9e474c51 100644 --- a/anvil-common/src/main/java/org/anvilpowered/anvil/common/entity/EntityUtils.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandExecutor.kt @@ -1,27 +1,26 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.common.entity; +package org.anvilpowered.anvil.core.command -import java.util.Optional; -import java.util.UUID; +interface CommandExecutor { -public interface EntityUtils { + suspend fun execute(source: CommandSource, command: String): Boolean - Optional extractUUID(Object entity); + suspend fun executeAsConsole(command: String): Boolean } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandSource.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandSource.kt new file mode 100644 index 000000000..fe5997dd1 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/CommandSource.kt @@ -0,0 +1,36 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.command + +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.PlatformType +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject + +interface CommandSource : PlatformType { + + val audience: Audience + + val subject: Subject + + /** + * The [Player] associated with the executed command, if any. + */ + val player: Player? +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/command/LoggingExecutor.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/LoggingExecutor.kt new file mode 100644 index 000000000..912720e16 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/LoggingExecutor.kt @@ -0,0 +1,43 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.command + +import org.apache.logging.log4j.Logger + +fun CommandExecutor.withLogging(logger: Logger, prefix: String = "command"): CommandExecutor = object : CommandExecutor { + private fun log(success: Boolean, prefix: String, command: String) { + if (success) { + logger.info("$prefix: $command") + } else { + logger.error("Failed to execute $prefix: $command") + } + } + + override suspend fun execute(source: CommandSource, command: String): Boolean { + val success = this@withLogging.execute(source, command) + log(success, prefix, command) + return success + } + + override suspend fun executeAsConsole(command: String): Boolean { + val success = this@withLogging.executeAsConsole(command) + log(success, "console via $prefix", command) + return success + } +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/command/PlayerCommandScope.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/PlayerCommandScope.kt new file mode 100644 index 000000000..37adbe207 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/command/PlayerCommandScope.kt @@ -0,0 +1,32 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.command + +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.builder.RequiredArgumentBuilder +import org.anvilpowered.kbrig.context.CommandContext + +interface PlayerCommandScope { + + fun ArgumentBuilder.Companion.player( + argumentName: String = "player", + command: (context: CommandContext, player: Player) -> Int, + ): RequiredArgumentBuilder +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/AbstractKeyBuilder.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/AbstractKeyBuilder.kt new file mode 100644 index 000000000..245af8790 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/AbstractKeyBuilder.kt @@ -0,0 +1,48 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +abstract class AbstractKeyBuilder< + T : Any, K : Key, B : Key.FacetedBuilder, + AF : Key.BuilderFacet, NF : Key.NamedBuilderFacet, + >(val type: TypeToken) : Key.FacetedBuilder { + + var name: String? = null + var fallback: T? = null + var description: String? = null + + protected abstract fun self(): B + + override fun name(name: String): B { + this.name = name + return self() + } + + override fun fallback(fallback: T?): B { + this.fallback = fallback + return self() + } + + override fun description(description: String?): B { + this.description = description + return self() + } +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/DefaultSerialization.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/DefaultSerialization.kt new file mode 100644 index 000000000..40a5c1d35 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/DefaultSerialization.kt @@ -0,0 +1,34 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +internal fun Key.Companion.getDefaultDeserializer(type: TypeToken): (String) -> T { + @Suppress("UNCHECKED_CAST") + return when (type.type) { + String::class.java -> { it -> it } + Int::class.java -> { it: String -> it.toIntOrNull() } + Long::class.java -> { it: String -> it.toLongOrNull() } + Float::class.java -> { it: String -> it.toFloatOrNull() } + Double::class.java -> { it: String -> it.toDoubleOrNull() } + Boolean::class.java -> { it: String -> it.toBooleanStrictOrNull() } + else -> throw IllegalArgumentException("There is no default parser for ${type.type}") + } as (String) -> T +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/EnvironmentRegistry.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/EnvironmentRegistry.kt new file mode 100644 index 000000000..aa24b8eb8 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/EnvironmentRegistry.kt @@ -0,0 +1,83 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +/** + * A [Registry] implementation that checks environment variables. + */ +class EnvironmentRegistry(private val prefix: String, private val delegate: Registry? = null) : Registry { + + private val Key<*>.environmentName: String + get() = prefix + "_" + name + + override fun getDefault(key: Key): T { + return delegate?.getDefault(key) ?: key.fallback + } + + override fun getStrict(key: SimpleKey): T? { + val value = System.getenv(key.environmentName) ?: return delegate?.getStrict(key) + return key.deserialize(value) + } + + override fun getStrict(key: ListKey): List? { + val value = System.getenv(key.environmentName) ?: return delegate?.getStrict(key) + val tokens = value.split(",") + return tokens.map { key.deserializeElement(it) } + } + + override fun getStrict(key: ListKey, index: Int): E? { + val value = System.getenv(key.environmentName) ?: return delegate?.getStrict(key, index) + val tokens = value.split(",") + return key.deserializeElement(tokens[index]) + } + + override fun getDefault(key: ListKey, index: Int): E { + return delegate?.getDefault(key, index) + ?: key.fallback.getOrNull(index) + ?: throw NoSuchElementException("No default value for key ${key.name} at index $index") + } + + override fun getStrict(key: MapKey): Map? { + val value = System.getenv(key.environmentName) ?: return delegate?.getStrict(key) + val tokens = value.split(",") + return tokens.associate { token -> + val (k, v) = token.split("=") + val mapKey = requireNotNull(key.deserializeKey(k)) { "Could not deserialize mapKey $k for key $key" } + val mapValue = requireNotNull(key.deserializeValue(v)) { "Could not deserialize mapValue $v for mapKey $k for key $key" } + mapKey to mapValue + } + } + + override fun getStrict(key: MapKey, mapKey: K): V? { + val value = System.getenv(key.environmentName) ?: return delegate?.getStrict(key, mapKey) + return value.split(",").asSequence() + .map { it.split("=").zipWithNext().single() } + .firstOrNull { (k, _) -> + mapKey == requireNotNull(key.deserializeKey(k)) { "Could not deserialize mapKey $k for key $key" } + }?.let { (k, v) -> + requireNotNull(key.deserializeValue(v)) { "Could not deserialize mapValue $v for mapKey $k for key $key" } + } + } + + override fun getDefault(key: MapKey, mapKey: K): V { + return delegate?.getDefault(key, mapKey) + ?: key.fallback[mapKey] + ?: throw NoSuchElementException("No default value for key ${key.name} with mapKey $mapKey") + } +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Key.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Key.kt new file mode 100644 index 000000000..c9ef9a2e8 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Key.kt @@ -0,0 +1,188 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken +import kotlin.properties.PropertyDelegateProvider +import kotlin.properties.ReadOnlyProperty + +interface Key : Comparable> { + + val type: TypeToken + + val name: String + + val fallback: T + + val description: String? + + /** + * Serializes the given value in a simple [String] representation. + */ + fun serialize(value: T): String + + /** + * Deserializes the given value from a simple [String] representation. + */ + fun deserialize(value: String): T? + + @KeyBuilderDsl + interface BuilderFacet, B : BuilderFacet> { + /** + * Sets the fallback value of the generated [Key] + * + * @param fallback The fallback value to set + * @return `this` + */ + @KeyBuilderDsl + fun fallback(fallback: T?): B + + /** + * Sets the description of the generated [Key]. + * + * @param description The description to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun description(description: String?): B + } + + @KeyBuilderDsl + interface NamedBuilderFacet, B : BuilderFacet> : BuilderFacet { + /** + * Sets the name of the generated [Key] + * + * @param name The name to set + * @return `this` + */ + @KeyBuilderDsl + fun name(name: String): B + } + + interface Builder, B : Builder> : NamedBuilderFacet { + /** + * Generates a [Key] based on this builder. + * + * @return The generated [Key] + */ + context(KeyNamespace) + @KeyBuilderDsl + fun build(): K + } + + @KeyBuilderDsl + interface FacetedBuilder< + T : Any, K : Key, B : FacetedBuilder, + AF : BuilderFacet, NF : NamedBuilderFacet, + > : Builder { + + /** + * @return This builder as an (anonymous) [BuilderFacet] + */ + fun asAnonymousFacet(): AF + + /** + * @return This builder as a [NamedBuilderFacet] + */ + fun asNamedFacet(): NF + } + + companion object { + + val comparator: Comparator> = Comparator.comparing, String> { it.name } + .thenComparing(Comparator.comparing { it.type.type.typeName }) + + fun equals(a: Key<*>?, b: Key<*>?): Boolean { + if (a === b) return true + if (a == null || b == null) return false + return a.name == b.name && a.type.type.typeName == b.type.type.typeName + } + + fun hashCode(key: Key<*>): Int { + var result = key.type.hashCode() + result = 31 * result + key.name.hashCode() + return result + } + + context(KeyNamespace) + inline fun buildSimple(type: TypeToken, block: SimpleKey.NamedBuilderFacet.() -> Unit): SimpleKey { + val builder = SimpleKeyBuilder(type) + builder.asNamedFacet().block() + return builder.build() + } + + context(KeyNamespace) + inline fun buildingSimple( + type: TypeToken, + crossinline block: SimpleKey.AnonymousBuilderFacet.() -> Unit, + ): PropertyDelegateProvider>> = PropertyDelegateProvider { _, property -> + val builder = SimpleKeyBuilder(type) + builder.name(property.name) + builder.asAnonymousFacet().block() + val key = builder.build() + ReadOnlyProperty { _, _ -> key } + } + + context(KeyNamespace) + inline fun buildList( + elementType: TypeToken, + block: ListKey.NamedBuilderFacet.() -> Unit, + ): ListKey { + val builder = ListKeyBuilder(elementType) + builder.asNamedFacet().block() + return builder.build() + } + + context(KeyNamespace) + inline fun buildingList( + elementType: TypeToken, + crossinline block: ListKey.AnonymousBuilderFacet.() -> Unit, + ): PropertyDelegateProvider>> = PropertyDelegateProvider { _, property -> + val builder = ListKeyBuilder(elementType) + builder.name(property.name) + builder.asAnonymousFacet().block() + val key = builder.build() + ReadOnlyProperty { _, _ -> key } + } + + context(KeyNamespace) + inline fun buildMap( + keyType: TypeToken, + valueType: TypeToken, + block: MapKey.NamedBuilderFacet.() -> Unit, + ): MapKey { + val builder = MapKeyBuilder(keyType, valueType) + builder.asNamedFacet().block() + return builder.build() + } + + context(KeyNamespace) + inline fun buildingMap( + keyType: TypeToken, + valueType: TypeToken, + crossinline block: MapKey.AnonymousBuilderFacet.() -> Unit, + ): PropertyDelegateProvider>> = PropertyDelegateProvider { _, property -> + val builder = MapKeyBuilder(keyType, valueType) + builder.name(property.name) + builder.asAnonymousFacet().block() + val key = builder.build() + ReadOnlyProperty { _, _ -> key } + } + } +} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/Version.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyBuilderDsl.kt similarity index 57% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/server/Version.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyBuilderDsl.kt index b1e1c8b3f..da06d4dde 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/server/Version.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyBuilderDsl.kt @@ -1,26 +1,22 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.server; +package org.anvilpowered.anvil.core.config -import org.anvilpowered.anvil.api.misc.Named; - -public interface Version extends Named { - - int getProtocol(); -} +@DslMarker +annotation class KeyBuilderDsl diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyNamespace.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyNamespace.kt new file mode 100644 index 000000000..8e5156b99 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/KeyNamespace.kt @@ -0,0 +1,56 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken +import org.jetbrains.annotations.ApiStatus + +interface KeyNamespace { + val name: String + + operator fun get(keyName: String, type: TypeToken): Key? + + @ApiStatus.Internal + fun add(key: Key) + + companion object { + fun create(name: String): KeyNamespace { + return KeyNamespaceImpl(name) + } + } +} + +internal class KeyNamespaceImpl(override val name: String) : KeyNamespace { + private val keys: MutableMap> = mutableMapOf() + + override fun get(keyName: String, type: TypeToken): Key? { + val key = keys[keyName] ?: return null + if (key.type != type) { + throw TypeCastException("Key $name has type ${key.type} which does not match provided type $type") + } + @Suppress("UNCHECKED_CAST") + return key as Key + } + + override fun add(key: Key) { + keys[key.name] = key + } +} + +inline operator fun KeyNamespace.get(keyName: String): Key? = get(keyName, TypeToken.get(T::class.java)) diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKey.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKey.kt new file mode 100644 index 000000000..09169b865 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKey.kt @@ -0,0 +1,98 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +context(KeyNamespace) +class ListKey internal constructor( + override val type: TypeToken>, + override val name: String, + override val fallback: List, + override val description: String?, + private val elementType: TypeToken, + private val elementSerializer: ((E) -> String)?, + private val elementDeserializer: (String) -> E, +) : Key> { + private val namespace: KeyNamespace = this@KeyNamespace + + init { + namespace.add(this) + } + + fun serializeElement(element: E): String = elementSerializer?.invoke(element) ?: element.toString() + fun deserializeElement(element: String): E = elementDeserializer(element) + + override fun serialize(value: List): String { + return value.joinToString(",") { serializeElement(it) } + } + + override fun deserialize(value: String): List? { + return value.splitToSequence(",") + .map { deserializeElement(it) } + .toList() + } + + override fun compareTo(other: Key>): Int = Key.comparator.compare(this, other) + override fun equals(other: Any?): Boolean = (other as Key<*>?)?.let { Key.equals(this, it) } ?: false + override fun hashCode(): Int = Key.hashCode(this) + override fun toString(): String = "ListKey<$elementType>(name='$name')" + + @KeyBuilderDsl + interface BuilderFacet> : Key.BuilderFacet, ListKey, B> { + + /** + * Sets the element serializer of the generated [Key]. + * + * @param serializer The element serializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun elementSerializer(serializer: ((E) -> String)?): B + + /** + * Sets the element deserializer of the generated [Key]. + * + * @param deserializer The element deserializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun elementDeserializer(deserializer: ((String) -> E)?): B + } + + @KeyBuilderDsl + interface AnonymousBuilderFacet : + BuilderFacet>, + Key.BuilderFacet, ListKey, AnonymousBuilderFacet> + + @KeyBuilderDsl + interface NamedBuilderFacet : + BuilderFacet>, + Key.NamedBuilderFacet, ListKey, NamedBuilderFacet> + + @KeyBuilderDsl + interface Builder : + BuilderFacet>, + Key.Builder, ListKey, Builder> + + @KeyBuilderDsl + interface FacetedBuilder : + BuilderFacet>, + Key.FacetedBuilder, ListKey, FacetedBuilder, AnonymousBuilderFacet, NamedBuilderFacet> +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKeyBuilder.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKeyBuilder.kt new file mode 100644 index 000000000..486c6a11c --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/ListKeyBuilder.kt @@ -0,0 +1,113 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeFactory +import io.leangen.geantyref.TypeToken + +class ListKeyBuilder( + private val elementType: TypeToken, +) : AbstractKeyBuilder, ListKey, ListKey.FacetedBuilder, ListKey.AnonymousBuilderFacet, ListKey.NamedBuilderFacet>( + createListTypeToken(elementType), +), + ListKey.FacetedBuilder { + + private var elementSerializer: ((E) -> String)? = null + private var elementDeserializer: ((String) -> E)? = null + + override fun self(): ListKey.FacetedBuilder = this + + override fun elementSerializer(serializer: ((E) -> String)?): ListKey.FacetedBuilder { + this.elementSerializer = serializer + return this + } + + override fun elementDeserializer(deserializer: ((String) -> E)?): ListKey.FacetedBuilder { + this.elementDeserializer = deserializer + return this + } + + context(KeyNamespace) + override fun build(): ListKey = ListKey( + type, + requireNotNull(name) { "Name is null" }, + requireNotNull(fallback) { "Fallback is null" }, + description, + elementType, + elementSerializer, + elementDeserializer ?: Key.getDefaultDeserializer(elementType), + ) + + override fun asAnonymousFacet(): ListKey.AnonymousBuilderFacet { + return object : ListKey.AnonymousBuilderFacet { + override fun fallback(fallback: List?): ListKey.AnonymousBuilderFacet { + this@ListKeyBuilder.fallback(fallback) + return this + } + + override fun description(description: String?): ListKey.AnonymousBuilderFacet { + this@ListKeyBuilder.description(description) + return this + } + + override fun elementSerializer(serializer: ((E) -> String)?): ListKey.AnonymousBuilderFacet { + this@ListKeyBuilder.elementSerializer(serializer) + return this + } + + override fun elementDeserializer(deserializer: ((String) -> E)?): ListKey.AnonymousBuilderFacet { + this@ListKeyBuilder.elementDeserializer(deserializer) + return this + } + } + } + + override fun asNamedFacet(): ListKey.NamedBuilderFacet { + return object : ListKey.NamedBuilderFacet { + override fun fallback(fallback: List?): ListKey.NamedBuilderFacet { + this@ListKeyBuilder.fallback(fallback) + return this + } + + override fun description(description: String?): ListKey.NamedBuilderFacet { + this@ListKeyBuilder.description(description) + return this + } + + override fun name(name: String): ListKey.NamedBuilderFacet { + this@ListKeyBuilder.name(name) + return this + } + + override fun elementSerializer(serializer: ((E) -> String)?): ListKey.NamedBuilderFacet { + this@ListKeyBuilder.elementSerializer(serializer) + return this + } + + override fun elementDeserializer(deserializer: ((String) -> E)?): ListKey.NamedBuilderFacet { + this@ListKeyBuilder.elementDeserializer(deserializer) + return this + } + } + } +} + +@Suppress("UNCHECKED_CAST") +private fun createListTypeToken(elementType: TypeToken): TypeToken> = + TypeToken.get(TypeFactory.parameterizedClass(List::class.java, elementType.type)) as TypeToken> diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKey.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKey.kt new file mode 100644 index 000000000..5410ccba0 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKey.kt @@ -0,0 +1,124 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +context(KeyNamespace) +class MapKey internal constructor( + override val type: TypeToken>, + override val name: String, + override val fallback: Map, + override val description: String?, + private val keyType: TypeToken, + private val keySerializer: ((K) -> String)?, + private val keyDeserializer: (String) -> K, + private val valueType: TypeToken, + private val valueSerializer: ((V) -> String)?, + private val valueDeserializer: (String) -> V, +) : Key> { + private val namespace: KeyNamespace = this@KeyNamespace + + init { + namespace.add(this) + } + + fun serializeKey(mapKey: K): String = keySerializer?.invoke(mapKey) ?: mapKey.toString() + fun deserializeKey(mapKey: String): K = keyDeserializer(mapKey) + fun serializeValue(mapValue: V): String = valueSerializer?.invoke(mapValue) ?: mapValue.toString() + fun deserializeValue(mapValue: String): V = valueDeserializer(mapValue) + + override fun serialize(value: Map): String { + return value.entries.joinToString(",") { (key, value) -> + "${serializeKey(key)}=${serializeValue(value)}" + } + } + + override fun deserialize(value: String): Map { + return value.splitToSequence(",") + .map { it.split("=", limit = 2) } + .map { (key, value) -> deserializeKey(key) to deserializeValue(value) } + .toMap() + } + + override fun compareTo(other: Key>): Int = Key.comparator.compare(this, other) + override fun equals(other: Any?): Boolean = (other as Key<*>?)?.let { Key.equals(this, it) } ?: false + override fun hashCode(): Int = Key.hashCode(this) + override fun toString(): String = "MapKey<$keyType, $valueType>(name='$name')" + + @KeyBuilderDsl + interface BuilderFacet> : Key.BuilderFacet, MapKey, B> { + + /** + * Sets the key serializer of the generated [Key]. + * + * @param serializer The key serializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun keySerializer(serializer: ((K) -> String)?): B + + /** + * Sets the key deserializer of the generated [Key]. + * + * @param deserializer The key deserializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun keyDeserializer(deserializer: ((String) -> K)?): B + + /** + * Sets the value serializer of the generated [Key]. + * + * @param serializer The value serializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun valueSerializer(serializer: ((V) -> String)?): B + + /** + * Sets the value deserializer of the generated [Key]. + * + * @param deserializer The value deserializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun valueDeserializer(deserializer: ((String) -> V)?): B + } + + @KeyBuilderDsl + interface AnonymousBuilderFacet : + BuilderFacet>, + Key.BuilderFacet, MapKey, AnonymousBuilderFacet> + + @KeyBuilderDsl + interface NamedBuilderFacet : + BuilderFacet>, + Key.NamedBuilderFacet, MapKey, NamedBuilderFacet> + + @KeyBuilderDsl + interface Builder : + BuilderFacet>, + Key.Builder, MapKey, Builder> + + @KeyBuilderDsl + interface FacetedBuilder : + BuilderFacet>, + Key.FacetedBuilder, MapKey, FacetedBuilder, AnonymousBuilderFacet, NamedBuilderFacet> +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKeyBuilder.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKeyBuilder.kt new file mode 100644 index 000000000..8d5a44908 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/MapKeyBuilder.kt @@ -0,0 +1,150 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeFactory +import io.leangen.geantyref.TypeToken + +class MapKeyBuilder( + private val mapKeyType: TypeToken, + private val mapValueType: TypeToken, +) : AbstractKeyBuilder< + Map, MapKey, MapKey.FacetedBuilder, MapKey.AnonymousBuilderFacet, + MapKey.NamedBuilderFacet, + >(createMapTypeToken(mapKeyType, mapValueType)), + MapKey.FacetedBuilder { + + private var keySerializer: ((K) -> String)? = null + private var keyDeserializer: ((String) -> K)? = null + private var valueSerializer: ((V) -> String)? = null + private var valueDeserializer: ((String) -> V)? = null + + override fun self(): MapKey.FacetedBuilder = this + + override fun keySerializer(serializer: ((K) -> String)?): MapKey.FacetedBuilder { + this.keySerializer = serializer + return this + } + + override fun keyDeserializer(deserializer: ((String) -> K)?): MapKey.FacetedBuilder { + this.keyDeserializer = deserializer + return this + } + + override fun valueSerializer(serializer: ((V) -> String)?): MapKey.FacetedBuilder { + this.valueSerializer = serializer + return this + } + + override fun valueDeserializer(deserializer: ((String) -> V)?): MapKey.FacetedBuilder { + this.valueDeserializer = deserializer + return this + } + + context(KeyNamespace) + override fun build(): MapKey = MapKey( + type, + requireNotNull(name) { "Name is null" }, + requireNotNull(fallback) { "Fallback is null" }, + description, + mapKeyType, + keySerializer, + keyDeserializer ?: Key.getDefaultDeserializer(mapKeyType), + mapValueType, + valueSerializer, + valueDeserializer ?: Key.getDefaultDeserializer(mapValueType), + ) + + override fun asAnonymousFacet(): MapKey.AnonymousBuilderFacet { + return object : MapKey.AnonymousBuilderFacet { + override fun fallback(fallback: Map?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.fallback(fallback) + return this + } + + override fun description(description: String?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.description(description) + return this + } + + override fun keySerializer(serializer: ((K) -> String)?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.keySerializer(serializer) + return this + } + + override fun keyDeserializer(deserializer: ((String) -> K)?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.keyDeserializer(deserializer) + return this + } + + override fun valueSerializer(serializer: ((V) -> String)?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.valueSerializer(serializer) + return this + } + + override fun valueDeserializer(deserializer: ((String) -> V)?): MapKey.AnonymousBuilderFacet { + this@MapKeyBuilder.valueDeserializer(deserializer) + return this + } + } + } + + override fun asNamedFacet(): MapKey.NamedBuilderFacet { + return object : MapKey.NamedBuilderFacet { + override fun name(name: String): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.name(name) + return this + } + + override fun fallback(fallback: Map?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.fallback(fallback) + return this + } + + override fun description(description: String?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.description(description) + return this + } + + override fun keySerializer(serializer: ((K) -> String)?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.keySerializer(serializer) + return this + } + + override fun keyDeserializer(deserializer: ((String) -> K)?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.keyDeserializer(deserializer) + return this + } + + override fun valueSerializer(serializer: ((V) -> String)?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.valueSerializer(serializer) + return this + } + + override fun valueDeserializer(deserializer: ((String) -> V)?): MapKey.NamedBuilderFacet { + this@MapKeyBuilder.valueDeserializer(deserializer) + return this + } + } + } +} + +@Suppress("UNCHECKED_CAST") +private fun createMapTypeToken(mapKeyType: TypeToken, mapValueType: TypeToken): TypeToken> = + TypeToken.get(TypeFactory.parameterizedClass(Map::class.java, mapKeyType.type, mapValueType.type)) as TypeToken> diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Registry.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Registry.kt new file mode 100644 index 000000000..57813f155 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/Registry.kt @@ -0,0 +1,40 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +interface Registry { + fun getDefault(key: Key): T + + fun getStrict(key: SimpleKey): T? + operator fun get(key: SimpleKey): T = getStrict(key) ?: getDefault(key) + + fun getStrict(key: ListKey): List? + operator fun get(key: ListKey): List = getStrict(key) ?: getDefault(key) + + fun getStrict(key: ListKey, index: Int): E? + fun getDefault(key: ListKey, index: Int): E + operator fun get(key: ListKey, index: Int): E = getStrict(key, index) ?: getDefault(key, index) + + fun getStrict(key: MapKey): Map? + operator fun get(key: MapKey): Map = getStrict(key) ?: getDefault(key) + + fun getStrict(key: MapKey, mapKey: K): V? + fun getDefault(key: MapKey, mapKey: K): V + operator fun get(key: MapKey, mapKey: K): V = getStrict(key, mapKey) ?: getDefault(key, mapKey) +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKey.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKey.kt new file mode 100644 index 000000000..d000a32e8 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKey.kt @@ -0,0 +1,87 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +context(KeyNamespace) +class SimpleKey internal constructor( + override val type: TypeToken, + override val name: String, + override val fallback: T, + override val description: String?, + private val serializer: ((T) -> String)?, + private val deserializer: (String) -> T, +) : Key { + private val namespace: KeyNamespace = this@KeyNamespace + + init { + namespace.add(this) + } + + override fun serialize(value: T): String = serializer?.invoke(value) ?: value.toString() + override fun deserialize(value: String): T = deserializer(value) + + override fun compareTo(other: Key): Int = Key.comparator.compare(this, other) + override fun equals(other: Any?): Boolean = (other as Key<*>?)?.let { Key.equals(this, it) } ?: false + override fun hashCode(): Int = Key.hashCode(this) + override fun toString(): String = "SimpleKey(type=$type, name='$name')" + + @KeyBuilderDsl + interface BuilderFacet> : Key.BuilderFacet, B> { + + /** + * Sets the serializer of the generated [Key]. + * + * @param serializer The serializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun serializer(serializer: ((T) -> String)?): B + + /** + * Sets the deserializer of the generated [Key]. + * + * @param deserializer The deserializer to set or `null` to remove it + * @return `this` + */ + @KeyBuilderDsl + fun deserializer(deserializer: ((String) -> T)?): B + } + + @KeyBuilderDsl + interface AnonymousBuilderFacet : + BuilderFacet>, + Key.BuilderFacet, AnonymousBuilderFacet> + + @KeyBuilderDsl + interface NamedBuilderFacet : + BuilderFacet>, + Key.NamedBuilderFacet, NamedBuilderFacet> + + @KeyBuilderDsl + interface Builder : + BuilderFacet>, + Key.Builder, Builder> + + @KeyBuilderDsl + interface FacetedBuilder : + BuilderFacet>, + Key.FacetedBuilder, FacetedBuilder, AnonymousBuilderFacet, NamedBuilderFacet> +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKeyBuilder.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKeyBuilder.kt new file mode 100644 index 000000000..dbd6aa2e5 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/SimpleKeyBuilder.kt @@ -0,0 +1,107 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken + +class SimpleKeyBuilder( + type: TypeToken, +) : AbstractKeyBuilder, SimpleKey.FacetedBuilder, SimpleKey.AnonymousBuilderFacet, SimpleKey.NamedBuilderFacet>( + type, +), + SimpleKey.FacetedBuilder { + + private var serializer: ((T) -> String)? = null + private var deserializer: ((String) -> T)? = null + + override fun self(): SimpleKey.FacetedBuilder = this + + override fun serializer(serializer: ((T) -> String)?): SimpleKey.FacetedBuilder { + this.serializer = serializer + return self() + } + + override fun deserializer(deserializer: ((String) -> T)?): SimpleKey.FacetedBuilder { + this.deserializer = deserializer + return self() + } + + context(KeyNamespace) + override fun build(): SimpleKey = SimpleKey( + type, + requireNotNull(name) { "Name is null" }, + requireNotNull(fallback) { "Fallback is null" }, + description, + serializer, + deserializer ?: Key.getDefaultDeserializer(type), + ) + + override fun asAnonymousFacet(): SimpleKey.AnonymousBuilderFacet { + return object : SimpleKey.AnonymousBuilderFacet { + override fun fallback(fallback: T?): SimpleKey.AnonymousBuilderFacet { + this@SimpleKeyBuilder.fallback(fallback).let { this } + return this + } + + override fun description(description: String?): SimpleKey.AnonymousBuilderFacet { + this@SimpleKeyBuilder.description(description) + return this + } + + override fun serializer(serializer: ((T) -> String)?): SimpleKey.AnonymousBuilderFacet { + this@SimpleKeyBuilder.serializer(serializer) + return this + } + + override fun deserializer(deserializer: ((String) -> T)?): SimpleKey.AnonymousBuilderFacet { + this@SimpleKeyBuilder.deserializer(deserializer) + return this + } + } + } + + override fun asNamedFacet(): SimpleKey.NamedBuilderFacet { + return object : SimpleKey.NamedBuilderFacet { + override fun name(name: String): SimpleKey.NamedBuilderFacet { + this@SimpleKeyBuilder.name(name) + return this + } + + override fun fallback(fallback: T?): SimpleKey.NamedBuilderFacet { + this@SimpleKeyBuilder.fallback(fallback) + return this + } + + override fun description(description: String?): SimpleKey.NamedBuilderFacet { + this@SimpleKeyBuilder.description(description) + return this + } + + override fun serializer(serializer: ((T) -> String)?): SimpleKey.NamedBuilderFacet { + this@SimpleKeyBuilder.serializer(serializer) + return this + } + + override fun deserializer(deserializer: ((String) -> T)?): SimpleKey.NamedBuilderFacet { + this@SimpleKeyBuilder.deserializer(deserializer) + return this + } + } + } +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/config/TypeTokens.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/TypeTokens.kt new file mode 100644 index 000000000..55c1c6c9b --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/config/TypeTokens.kt @@ -0,0 +1,34 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.config + +import io.leangen.geantyref.TypeToken +import net.kyori.adventure.text.Component +import java.time.ZoneId + +@Suppress("PropertyName") +open class TypeTokens { + val BOOLEAN: TypeToken = TypeToken.get(Boolean::class.java) + val INTEGER: TypeToken = TypeToken.get(Int::class.java) + val STRING: TypeToken = TypeToken.get(String::class.java) + val COMPONENT: TypeToken = TypeToken.get(Component::class.java) + val ZONE_ID: TypeToken = TypeToken.get(ZoneId::class.java) + + companion object : TypeTokens() +} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginMessages.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/DomainEntity.kt similarity index 51% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginMessages.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/db/DomainEntity.kt index 695bec40e..88dc49102 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/plugin/PluginMessages.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/DomainEntity.kt @@ -1,30 +1,32 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.plugin; +package org.anvilpowered.anvil.core.db -import java.time.Instant; +import java.util.UUID -public interface PluginMessages { - - TString getBanMessage(String reason, Instant endUtc); - - TString getMuteMessage(String reason, Instant endUtc); +interface DomainEntity { + val id: UUID + // TODO: createdUtc, updatedUtc +} - TString getNoPermission(); +interface DomainFacet { + suspend fun getOriginal(): E } + +interface Creates diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/db/MutableRepository.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/MutableRepository.kt new file mode 100644 index 000000000..4596dcacb --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/MutableRepository.kt @@ -0,0 +1,29 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.db + +interface MutableRepository> : Repository { + suspend fun create(item: C): E + suspend fun put(item: C): PutResult + + data class PutResult( + val entity: E, + val created: Boolean, + ) +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/db/Pagination.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/Pagination.kt new file mode 100644 index 000000000..08e59e9eb --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/Pagination.kt @@ -0,0 +1,32 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.db + +import kotlin.reflect.KProperty1 + +interface Pagination> { + fun limit(n: Int, offset: Long = 0): Pagination + fun sortBy(field: KProperty1>, direction: SortDirection = SortDirection.ASCENDING): Pagination + fun build(): List +} + +enum class SortDirection { + ASCENDING, + DESCENDING, +} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandExecuteService.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/Repository.kt similarity index 50% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandExecuteService.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/db/Repository.kt index 9856f07fb..7a2923e6d 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/command/CommandExecuteService.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/db/Repository.kt @@ -1,29 +1,28 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.command; +package org.anvilpowered.anvil.core.db -public interface CommandExecuteService { +import java.util.UUID - /** - * Executes the provided command as the console. - * - * @param command The command to execute - */ - void execute(String command); +interface Repository { + suspend fun getById(id: UUID): E? + suspend fun exists(id: UUID): Boolean + suspend fun countAll(): Long + suspend fun deleteById(id: UUID): Boolean } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/entity/AnvilTable.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/entity/AnvilTable.kt new file mode 100644 index 000000000..f630fffe4 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/entity/AnvilTable.kt @@ -0,0 +1,26 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.entity + +import org.jetbrains.exposed.dao.id.UUIDTable + +abstract class AnvilTable(name: String) : UUIDTable(name) { +// val createdUtc = timestamp("created_utc") +// val updatedUtc = timestamp("updated_utc") // TODO: Make sure postgres updates this field +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Platform.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Platform.kt new file mode 100644 index 000000000..d991d3bc0 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Platform.kt @@ -0,0 +1,27 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.platform + +interface Platform { + val name: String + val version: String + + val isProxy: Boolean + val plugins: List +} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/Named.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Plugin.kt similarity index 60% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/Named.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Plugin.kt index fcfc975e4..acbba67b5 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/misc/Named.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Plugin.kt @@ -1,24 +1,23 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.misc; +package org.anvilpowered.anvil.core.platform -public interface Named { - - String getName(); +interface Plugin { + val name: String } diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/Result.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/PluginManager.kt similarity index 57% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/util/Result.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/platform/PluginManager.kt index 5014531ee..1a71d5d4a 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/Result.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/PluginManager.kt @@ -1,26 +1,23 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.util; +package org.anvilpowered.anvil.core.platform -public interface Result { - - TResult success(TData data); - - TResult fail(TData data); +interface PluginManager { + val plugins: List } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Server.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Server.kt new file mode 100644 index 000000000..8218f9354 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/platform/Server.kt @@ -0,0 +1,30 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.platform + +import net.kyori.adventure.audience.Audience + +interface Server { + + val platform: Platform + + val broadcastAudience: Audience + + val systemSubject: Audience +} diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/user/ArgumentExtensions.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/ArgumentExtensions.kt new file mode 100644 index 000000000..daa4c2712 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/ArgumentExtensions.kt @@ -0,0 +1,25 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.user + +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.kbrig.builder.ArgumentBuilder + +fun > B.requiresPermission(permission: String): B = + requires { it.subject.hasPermissionSet(permission) } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Player.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Player.kt new file mode 100644 index 000000000..a0dece50a --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Player.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.user + +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.text.Component +import java.util.UUID + +/** + * An online player. + */ +interface Player : Subject, Audience { + + val id: UUID + + val username: String + + val displayname: Component + + val latencyMs: Int +} diff --git a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/KickService.java b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/PlayerService.kt similarity index 52% rename from anvil-api/src/main/java/org/anvilpowered/anvil/api/util/KickService.java rename to core/src/main/kotlin/org/anvilpowered/anvil/core/user/PlayerService.kt index bc2edca40..70ad3578e 100644 --- a/anvil-api/src/main/java/org/anvilpowered/anvil/api/util/KickService.java +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/PlayerService.kt @@ -1,32 +1,30 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.api.util; +package org.anvilpowered.anvil.core.user -import java.util.UUID; +import java.util.UUID -public interface KickService { +interface PlayerService { - void kick(UUID userUUID, Object reason); + operator fun get(username: String): Player? - void kick(String userName, Object reason); + operator fun get(id: UUID): Player? - void kick(UUID userUUID); - - void kick(String userName); + fun getAll(startsWith: String = ""): Sequence } diff --git a/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Subject.kt b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Subject.kt new file mode 100644 index 000000000..5b8222a34 --- /dev/null +++ b/core/src/main/kotlin/org/anvilpowered/anvil/core/user/Subject.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.core.user + +import org.anvilpowered.anvil.core.PlatformType + +interface Subject : PlatformType { + + /** + * Checks if the subject has the specified permission. + * + * - A value of `true` indicates that the subject has the permission explicitly set. + * - A value of `false` indicates that the subject has the permission explicitly set to false. + * - A value of `null` indicates that the subject does not have the permission explicitly set. + */ + fun hasPermission(permission: String): Boolean? +} + +fun Subject.hasPermissionSet(permission: String): Boolean = hasPermission(permission) == true +fun Subject.hasPermissionUnset(permission: String): Boolean = hasPermission(permission) == null +fun Subject.hasPermissionNotSet(permission: String): Boolean = hasPermission(permission) == false diff --git a/core/src/main/resources/application.conf b/core/src/main/resources/application.conf new file mode 100644 index 000000000..05697b0ee --- /dev/null +++ b/core/src/main/resources/application.conf @@ -0,0 +1,9 @@ +ktor { + development = false + deployment { + port = 8080 + } + application { + modules = [ org.anvilpowered.anvil.cockpit.MainKt.main ] + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..bfac9db08 --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +systemProp.org.gradle.unsafe.kotlin.assignment=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f9f7668d0..2ba5048b7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,40 +1,55 @@ [versions] -configurate = "3.7.2" -kotlin = "1.7.0" -blossom = "1.3.0" -mongo = "3.12.11" +configurate = "4.1.2" +kotlin = "1.9.21" +ktor = "2.3.0" +log4j = "2.20.0" [libraries] -aopalliance = "aopalliance:aopalliance:1.0" -apache-commons = "org.apache.commons:commons-pool2:2.11.1" -bson = { module = "org.mongodb:bson", version.ref = "mongo" } -bungee = "net.md-5:bungeecord-api:1.15-SNAPSHOT" +adventure-bom = "net.kyori:adventure-bom:4.14.0" +annotations = "org.jetbrains:annotations:24.0.0" +brigadier = "com.mojang:brigadier:1.0.18" configurate-core = { module = "org.spongepowered:configurate-core", version.ref = "configurate" } configurate-hocon = { module = "org.spongepowered:configurate-hocon", version.ref = "configurate" } -coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2" -flow-math = "com.flowpowered:flow-math:1.0.3" -guava = "com.google.guava:guava:28.1-jre" -guice = "com.google.inject:guice:4.1.0" -javasisst = "org.javassist:javassist:3.26.0-GA" -javax = "javax.inject:javax.inject:1" -jetbrains_annotations = "org.jetbrains:annotations:23.0.0" -kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } -kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } -kotlin-stdlib8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } -mongo-java-driver = { module = "org.mongodb:mongodb-java-driver", version.ref = "mongo" } -mongo-driver-sync = { module = "org.mongodb:mongodb-driver-sync", version.ref = "mongo" } -morphia = "dev.morphia.morphia:core:1.6.1" -microutils_logging = "io.github.microutils:kotlin-logging:1.5.4" -paper = "io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT" -reflections = "org.reflections:reflections:0.9.10" -serialization = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3" -sponge = "org.spongepowered:spongeapi:7.4.0" -typesafe_config = "com.typesafe:config:1.4.0" -velocity = "com.velocitypowered:velocity-api:3.1.1" -xodus-entity-store = "org.jetbrains.xodus:xodus-entity-store:2.0.1" +exposed-bom = "org.jetbrains.exposed:exposed-bom:0.41.1" +exposed-core = { module = "org.jetbrains.exposed:exposed-core" } +exposed-dao = { module = "org.jetbrains.exposed:exposed-dao" } +exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc" } +exposed-java-time = { module = "org.jetbrains.exposed:exposed-java-time" } +guava = "com.google.guava:guava:32.1.3-jre" +kbrig-brigadier = "org.anvilpowered:kbrig-brigadier:0.1.0-SNAPSHOT" +koin = "io.insert-koin:koin-core:3.5.2-RC1" +kotest = "io.kotest:kotest-runner-junit5-jvm:5.5.4" +kotlinx-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0" +kotlinx-datetime = "org.jetbrains.kotlinx:kotlinx-datetime:0.4.0" +kotlinx-serialization = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1" +ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } +ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } +ktor-serialization = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +ktor-server-auth = { module = "io.ktor:ktor-server-auth", version.ref = "ktor" } +ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" } +ktor-server-cors = { module = "io.ktor:ktor-server-cors", version.ref = "ktor" } +ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } +ktor-server-resources = { module = "io.ktor:ktor-server-resources", version.ref = "ktor" } +ktor-server-sessions = { module = "io.ktor:ktor-server-sessions", version.ref = "ktor" } +ktor-server-status-pages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor" } +logging-api = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j" } +logging-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" } +paper = "io.papermc.paper:paper-api:1.20.2-brigadier-SNAPSHOT" +redux = "org.reduxkotlin:redux-kotlin-threadsafe:0.6.1" +sponge = "org.spongepowered:spongeapi:8.1.0" +velocity = "com.velocitypowered:velocity-api:3.2.0-SNAPSHOT" + +[bundles] +exposed = ["exposed-core", "exposed-dao", "exposed-jdbc", "exposed-java-time"] +ktor-client = ["ktor-client-cio", "ktor-serialization"] +ktor-server = ["ktor-server-auth", "ktor-server-content-negotiation", "ktor-server-cors", "ktor-server-netty", "ktor-server-resources", "ktor-server-sessions", "ktor-server-status-pages"] [plugins] -kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } -shadow = { id = "com.github.johnrengelman.shadow", version = "7.1.2" } +ktlint = "org.jlleitschuh.gradle.ktlint:11.3.1" +pluginyml = "net.minecrell.plugin-yml.paper:0.6.0" +shadow = "com.github.johnrengelman.shadow:8.1.0" +sponge = "org.spongepowered.gradle.plugin:2.1.1" +ktor = { id = "io.ktor.plugin", version.ref = "ktor" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa..c1962a79e 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..309b4e18d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68d6..aeb74cbb4 100755 --- a/gradlew +++ b/gradlew @@ -85,9 +85,6 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +141,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +149,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index 2bfb25080..b7f6c5c75 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -1,10 +1,9 @@ -@Suppress("DSL_SCOPE_VIOLATION") plugins { - alias(libs.plugins.kotlin.jvm) - alias(libs.plugins.shadow) + id("anvil-publish") } dependencies { - implementation(project(":anvil-md5")) + implementation(project(":anvil-core")) + implementation(libs.kbrig.brigadier) compileOnly(libs.paper) } diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/AnvilPaperApi.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/AnvilPaperApi.kt new file mode 100644 index 000000000..3b8acacd8 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/AnvilPaperApi.kt @@ -0,0 +1,49 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +@file:Suppress("UnstableApiUsage") + +package org.anvilpowered.anvil.paper + +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.core.platform.PluginManager +import org.anvilpowered.anvil.core.platform.Server +import org.anvilpowered.anvil.core.user.PlayerService +import org.anvilpowered.anvil.paper.platform.PaperPluginManager +import org.anvilpowered.anvil.paper.platform.PaperServer +import org.anvilpowered.anvil.paper.user.PaperPlayerService +import org.apache.logging.log4j.LogManager +import org.apache.logging.log4j.Logger +import org.bukkit.plugin.java.JavaPlugin +import org.koin.core.module.Module +import org.koin.dsl.module + +interface AnvilPaperApi : AnvilApi + +context(JavaPlugin) +fun AnvilApi.Companion.createPaper(): AnvilPaperApi { + val paperModule = module { + single { LogManager.getLogger(pluginMeta.name) } + single { PaperServer } + single { PaperPluginManager } + single { PaperPlayerService } + } + return object : AnvilPaperApi { + override val module: Module = paperModule + } +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/AnvilPaperCommandSource.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/AnvilPaperCommandSource.kt new file mode 100644 index 000000000..cf26c51aa --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/AnvilPaperCommandSource.kt @@ -0,0 +1,42 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.command + +import io.papermc.paper.command.brigadier.CommandSourceStack +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import org.anvilpowered.anvil.paper.user.toAnvilPlayer +import org.anvilpowered.anvil.paper.user.toAnvilSubject +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player as PaperPlayer + +fun CommandSender.toAnvilCommandSource(): CommandSource = AnvilPaperCommandSource(this) + +@Suppress("UnstableApiUsage") +fun CommandSourceStack.toAnvilCommandSource(): CommandSource = AnvilPaperCommandSource(sender) + +private class AnvilPaperCommandSource( + override val platformDelegate: CommandSender, +) : CommandSource { + override val audience: Audience = platformDelegate + override val subject: Subject = platformDelegate.toAnvilSubject() + override val player: Player? = (platformDelegate as? PaperPlayer)?.toAnvilPlayer() +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCommandExecutor.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCommandExecutor.kt new file mode 100644 index 000000000..f2d5346b2 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCommandExecutor.kt @@ -0,0 +1,34 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.command + +import org.anvilpowered.anvil.core.command.CommandExecutor +import org.anvilpowered.anvil.core.command.CommandSource +import org.bukkit.Bukkit +import org.bukkit.command.CommandSender + +class PaperCommandExecutor : CommandExecutor { + override suspend fun execute(source: CommandSource, command: String): Boolean { + return Bukkit.dispatchCommand(source.platformDelegate as CommandSender, command) + } + + override suspend fun executeAsConsole(command: String): Boolean { + return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command) + } +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCustomCommand.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCustomCommand.kt new file mode 100644 index 000000000..0ca69e529 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperCustomCommand.kt @@ -0,0 +1,59 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.command + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.command.PlayerCommandScope +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.paper.user.toAnvilPlayer +import org.anvilpowered.kbrig.argument.StringArgumentType +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.builder.RequiredArgumentBuilder +import org.anvilpowered.kbrig.context.CommandContext +import org.anvilpowered.kbrig.context.get +import org.bukkit.Bukkit + +class PaperCustomCommand : PlayerCommandScope { + + override fun ArgumentBuilder.Companion.player( + argumentName: String, + command: (context: CommandContext, player: Player) -> Int, + ): RequiredArgumentBuilder = + required(argumentName, StringArgumentType.SingleWord) + .suggests { _, builder -> + Bukkit.getOnlinePlayers().forEach { player -> builder.suggest(player.name) } + builder.build() + } + .executes { context -> + val username = context.get(argumentName) + Bukkit.getPlayer(username)?.let { paperPlayer -> + command(context, paperPlayer.toAnvilPlayer()) + } ?: run { + context.source.audience.sendMessage( + Component.text() + .append(Component.text("Player with name ", NamedTextColor.RED)) + .append(Component.text(username, NamedTextColor.GOLD)) + .append(Component.text(" not found!", NamedTextColor.RED)), + ) + 0 + } + } +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperSourceConverter.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperSourceConverter.kt new file mode 100644 index 000000000..9c4dd0c61 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/command/PaperSourceConverter.kt @@ -0,0 +1,43 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +@file:JvmName("PaperSourceConverter") +@file:Suppress("UnstableApiUsage") + +package org.anvilpowered.anvil.paper.command + +import io.papermc.paper.command.brigadier.CommandSourceStack +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.kbrig.brigadier.toBrigadier +import org.anvilpowered.kbrig.tree.ArgumentCommandNode +import org.anvilpowered.kbrig.tree.LiteralCommandNode +import org.anvilpowered.kbrig.tree.mapSource +import com.mojang.brigadier.tree.ArgumentCommandNode as BrigadierArgumentCommandNode +import com.mojang.brigadier.tree.LiteralCommandNode as BrigadierLiteralCommandNode1 + +/** + * Converts a kbrig argument command node to a paper brigadier argument command node. + */ +fun ArgumentCommandNode.toPaper(): BrigadierArgumentCommandNode = + mapSource { it.toAnvilCommandSource() }.toBrigadier() + +/** + * Converts a kbrig literal command node to a paper brigadier literal command node. + */ +fun LiteralCommandNode.toPaper(): BrigadierLiteralCommandNode1 = + mapSource { it.toAnvilCommandSource() }.toBrigadier() diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlatform.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlatform.kt new file mode 100644 index 000000000..43cd2ac04 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlatform.kt @@ -0,0 +1,33 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.platform + +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Plugin +import org.bukkit.Bukkit + +internal object PaperPlatform : Platform { + override val isProxy: Boolean = false + override val plugins: List + get() = Bukkit.getPluginManager().plugins.map { it.toAnvilPlugin() } + override val name: String + get() = "paper" + override val version: String + get() = Bukkit.getBukkitVersion() +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlugin.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlugin.kt new file mode 100644 index 000000000..5602fda17 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPlugin.kt @@ -0,0 +1,29 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.platform + +import org.anvilpowered.anvil.core.platform.Plugin +import org.bukkit.plugin.Plugin as BukkitPlugin + +internal fun BukkitPlugin.toAnvilPlugin() = PaperPlugin(this) + +class PaperPlugin(private val delegate: BukkitPlugin) : Plugin { + override val name: String + get() = delegate.name +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPluginManager.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPluginManager.kt new file mode 100644 index 000000000..4692ca4db --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperPluginManager.kt @@ -0,0 +1,28 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.platform + +import org.anvilpowered.anvil.core.platform.Plugin +import org.anvilpowered.anvil.core.platform.PluginManager +import org.bukkit.Bukkit + +internal object PaperPluginManager : PluginManager { + override val plugins: List + get() = Bukkit.getPluginManager().plugins.map { it.toAnvilPlugin() } +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperServer.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperServer.kt new file mode 100644 index 000000000..b539d775d --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/platform/PaperServer.kt @@ -0,0 +1,33 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.platform + +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Server +import org.bukkit.Bukkit + +object PaperServer : Server { + override val platform: Platform + get() = PaperPlatform + override val broadcastAudience: Audience + get() = Bukkit.getServer() + override val systemSubject: Audience + get() = Bukkit.getConsoleSender() +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperPlayer.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperPlayer.kt new file mode 100644 index 000000000..cb4acc7df --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperPlayer.kt @@ -0,0 +1,40 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.user + +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import java.util.UUID +import org.bukkit.entity.Player as PaperPlayer + +fun PaperPlayer.toAnvilPlayer(): Player = AnvilPaperPlayer(this) + +private class AnvilPaperPlayer( + override val platformDelegate: PaperPlayer, +) : Player, + Audience by platformDelegate, + Subject by platformDelegate.toAnvilSubject() { + override val id: UUID = platformDelegate.uniqueId + override val username: String = platformDelegate.name + override val displayname: Component = platformDelegate.displayName() + override val latencyMs: Int + get() = platformDelegate.ping +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperSubject.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperSubject.kt new file mode 100644 index 000000000..5aeff22e7 --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/AnvilPaperSubject.kt @@ -0,0 +1,38 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.user + +import org.anvilpowered.anvil.core.user.Subject +import org.bukkit.permissions.Permissible + +fun Permissible.toAnvilSubject(): Subject = AnvilPaperSubject(this) + +private class AnvilPaperSubject( + override val platformDelegate: Permissible, +) : Subject { + override fun hasPermission(permission: String): Boolean? { + return if (platformDelegate.hasPermission(permission)) { + true + } else if (platformDelegate.isPermissionSet(permission)) { + false + } else { + null + } + } +} diff --git a/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/PaperPlayerService.kt b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/PaperPlayerService.kt new file mode 100644 index 000000000..77679adfb --- /dev/null +++ b/paper/src/main/kotlin/org/anvilpowered/anvil/paper/user/PaperPlayerService.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.paper.user + +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.PlayerService +import org.bukkit.Bukkit +import java.util.UUID + +object PaperPlayerService : PlayerService { + override fun get(username: String): Player? = + Bukkit.getPlayerExact(username)?.toAnvilPlayer() + + override fun get(id: UUID): Player? = + Bukkit.getPlayer(id)?.toAnvilPlayer() + + override fun getAll(startsWith: String): Sequence = when (startsWith) { + "" -> Bukkit.getOnlinePlayers().asSequence().map { it.toAnvilPlayer() } + else -> Bukkit.matchPlayer(startsWith).asSequence().map { it.toAnvilPlayer() } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 91c7c9739..92380f763 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,25 +1,39 @@ +@file:Suppress("UnstableApiUsage") + dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) +// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { + maven("https://nexus.anvilpowered.org/repository/maven-public/") mavenCentral() + maven("https://oss.sonatype.org/content/repositories/snapshots/") + maven("https://libraries.minecraft.net") + maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.spongepowered.org/repository/maven-public/") - maven("https://papermc.io/repo/repository/maven-public/") - maven("https://libraries.minecraft.net/") } } -rootProject.name = "anvil" +pluginManagement { + includeBuild("build-logic") + repositories { + mavenCentral() + gradlePluginPortal() + } +} -include("anvil-md5") +rootProject.name = "anvil" sequenceOf( - "api", + "app-plugin", + "app-plugin-core", + "app-plugin-paper", + "app-plugin-sponge", + "app-plugin-velocity", "core", "paper", "sponge", - "velocity" + "velocity", ).forEach { val project = ":anvil-$it" include(project) - project(project).projectDir = file(it) + project(project).projectDir = file(it.replace('-', '/')) } diff --git a/sponge/build.gradle.kts b/sponge/build.gradle.kts index dccb88603..79ed5f5da 100644 --- a/sponge/build.gradle.kts +++ b/sponge/build.gradle.kts @@ -1,10 +1,9 @@ -@Suppress("DSL_SCOPE_VIOLATION") plugins { - alias(libs.plugins.kotlin.jvm) - alias(libs.plugins.shadow) + id("anvil-publish") } dependencies { + implementation(libs.kotlinx.coroutines) implementation(project(":anvil-core")) - compileOnly(libs.sponge) + implementation(libs.sponge) } diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/AnvilSpongeApi.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/AnvilSpongeApi.kt new file mode 100644 index 000000000..075c4e5e6 --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/AnvilSpongeApi.kt @@ -0,0 +1,82 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge + +import com.google.inject.Injector +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.core.platform.PluginManager +import org.anvilpowered.anvil.core.platform.Server +import org.anvilpowered.anvil.core.user.PlayerService +import org.anvilpowered.anvil.sponge.platform.SpongePluginManager +import org.anvilpowered.anvil.sponge.platform.SpongeServer +import org.anvilpowered.anvil.sponge.user.SpongePlayerService +import org.apache.logging.log4j.Logger +import org.koin.dsl.module + +interface AnvilSpongeApi : AnvilApi { + + companion object +} + +/** + * Creates an Anvil API instance for Sponge. + * + * The returned API instance can be used to access the Anvil API. + * It is intended to be used as a context receiver. + * + * For example, you can access it in a class like this: + * ```kt + * context(AnvilSpongeApi) // or AnvilApi if in common code + * class MyPlugin { + * fun foo() { + * logger.info { "Hello, world!" } // logger property of [AnvilApi] is accessed through context receiver + * } + * } + * ``` + * + * In order to invoke this constructor, you must have an instance of [AnvilSpongeApi] in the calling context. + * To bring an instance of [AnvilSpongeApi] into the calling context, you can use the [with] function: + * + * ```kt + * private val plugin = with(AnvilApi.createSponge(logger, proxyServer)) { + * AnvilSpongePlugin() + * } + * ``` + * + * Context receivers may also be used on individual functions. + * This is particularly useful for top-level functions: + * + * ```kt + * context(AnvilSpongeApi) // or AnvilApi if in common code + * fun foo() { + * logger.info { "Hello, world!" } // logger property of [AnvilApi] is accessed through context receiver + * } + * ``` + */ +fun AnvilApi.Companion.createSponge(injector: Injector): AnvilSpongeApi { + val spongeModule = module { + single { injector.getInstance(Logger::class.java) } + single { SpongeServer } + single { SpongePluginManager } + single { SpongePlayerService } + } + return object : AnvilSpongeApi { + override val module = spongeModule + } +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlatform.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlatform.kt new file mode 100644 index 000000000..344b32365 --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlatform.kt @@ -0,0 +1,34 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.platform + +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Plugin +import org.spongepowered.api.Sponge +import org.spongepowered.api.Platform as SPlatform + +internal object SpongePlatform : Platform { + override val isProxy: Boolean = false + override val plugins: List + get() = Sponge.pluginManager().plugins().map { it.toAnvilPlugin() } + override val name: String + get() = "sponge" + override val version: String + get() = Sponge.platform().container(SPlatform.Component.IMPLEMENTATION).metadata().version().qualifier +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlugin.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlugin.kt new file mode 100644 index 000000000..a356845ee --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePlugin.kt @@ -0,0 +1,29 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.platform + +import org.anvilpowered.anvil.core.platform.Plugin +import org.spongepowered.plugin.PluginContainer + +internal fun PluginContainer.toAnvilPlugin() = SpongePlugin(this) + +internal class SpongePlugin(private val container: PluginContainer) : Plugin { + override val name: String + get() = container.metadata().id() +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePluginManager.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePluginManager.kt new file mode 100644 index 000000000..db39ee2ed --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongePluginManager.kt @@ -0,0 +1,28 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.platform + +import org.anvilpowered.anvil.core.platform.Plugin +import org.anvilpowered.anvil.core.platform.PluginManager +import org.spongepowered.api.Sponge + +internal object SpongePluginManager : PluginManager { + override val plugins: List + get() = Sponge.pluginManager().plugins().map { it.toAnvilPlugin() } +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongeServer.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongeServer.kt new file mode 100644 index 000000000..c8508f259 --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/platform/SpongeServer.kt @@ -0,0 +1,33 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.platform + +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Server +import org.spongepowered.api.Sponge + +object SpongeServer : Server { + override val platform: Platform + get() = SpongePlatform + override val broadcastAudience: Audience + get() = Sponge.server().broadcastAudience() + override val systemSubject: Audience + get() = Sponge.game().systemSubject() +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeCommandSource.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeCommandSource.kt new file mode 100644 index 000000000..f63e14b9b --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeCommandSource.kt @@ -0,0 +1,36 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.user + +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import org.spongepowered.api.command.parameter.CommandContext +import org.spongepowered.api.entity.living.player.server.ServerPlayer + +fun CommandContext.toAnvilCommandSource(): CommandSource = AnvilSpongeCommandSource(this) + +class AnvilSpongeCommandSource( + override val platformDelegate: CommandContext, +) : CommandSource { + override val audience: Audience = platformDelegate.cause().audience() + override val subject: Subject = platformDelegate.cause().subject().toAnvilSubject() + override val player: Player? = platformDelegate.cause().first(ServerPlayer::class.java).orElse(null)?.toAnvilPlayer() +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongePlayer.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongePlayer.kt new file mode 100644 index 000000000..f7b95ca20 --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongePlayer.kt @@ -0,0 +1,38 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.user + +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import org.spongepowered.api.entity.living.player.server.ServerPlayer +import java.util.UUID + +fun ServerPlayer.toAnvilPlayer(): Player = AnvilSpongePlayer(this) + +private class AnvilSpongePlayer( + override val platformDelegate: ServerPlayer, +) : Player, + Subject by platformDelegate.toAnvilSubject() { + override val id: UUID = platformDelegate.uniqueId() + override val username: String = platformDelegate.name() + override val displayname: Component = platformDelegate.displayName().get() + override val latencyMs: Int + get() = platformDelegate.connection().latency() +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeSubject.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeSubject.kt new file mode 100644 index 000000000..54c0d6c9a --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/AnvilSpongeSubject.kt @@ -0,0 +1,38 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.user + +import org.anvilpowered.anvil.core.user.Subject +import org.spongepowered.api.util.Tristate +import org.spongepowered.api.service.permission.Subject as SpongeSubject + +fun SpongeSubject.toAnvilSubject(): Subject = AnvilSpongeSubject(this) + +private class AnvilSpongeSubject( + override val platformDelegate: SpongeSubject, +) : Subject { + override fun hasPermission(permission: String): Boolean? = + platformDelegate.permissionValue(permission).toBoolean() +} + +private fun Tristate.toBoolean(): Boolean? = when (this) { + Tristate.TRUE -> true + Tristate.FALSE -> false + Tristate.UNDEFINED -> null +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongeCommandExecutor.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongeCommandExecutor.kt new file mode 100644 index 000000000..1e950366e --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongeCommandExecutor.kt @@ -0,0 +1,41 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.user + +import org.anvilpowered.anvil.core.command.CommandExecutor +import org.anvilpowered.anvil.core.command.CommandSource +import org.spongepowered.api.Sponge +import org.spongepowered.api.service.permission.Subject + +class SpongeCommandExecutor : CommandExecutor { + override suspend fun execute(source: CommandSource, command: String): Boolean { + return Sponge.server().commandManager().process( + source.subject.platformDelegate as Subject, + source.audience, + command, + ).isSuccess + } + + override suspend fun executeAsConsole(command: String): Boolean { + return Sponge.server().commandManager().process( + Sponge.systemSubject(), + command, + ).isSuccess + } +} diff --git a/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongePlayerService.kt b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongePlayerService.kt new file mode 100644 index 000000000..689e884b3 --- /dev/null +++ b/sponge/src/main/kotlin/org/anvilpowered/anvil/sponge/user/SpongePlayerService.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.sponge.user + +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.PlayerService +import org.spongepowered.api.Sponge +import java.util.UUID + +object SpongePlayerService : PlayerService { + override fun get(username: String): Player? = + Sponge.server().player(username).orElse(null)?.toAnvilPlayer() + + override fun get(id: UUID): Player? = + Sponge.server().player(id).orElse(null)?.toAnvilPlayer() + + override fun getAll(startsWith: String): Sequence = when (startsWith) { + "" -> Sponge.server().onlinePlayers().asSequence().map { it.toAnvilPlayer() } + else -> Sponge.server().onlinePlayers().asSequence().filter { it.name().startsWith(startsWith) }.map { it.toAnvilPlayer() } + } +} diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts index 409f6644d..e5db47a84 100644 --- a/velocity/build.gradle.kts +++ b/velocity/build.gradle.kts @@ -1,14 +1,8 @@ -@Suppress("DSL_SCOPE_VIOLATION") plugins { - alias(libs.plugins.kotlin.jvm) - id("org.jetbrains.kotlin.kapt") - alias(libs.plugins.shadow) + id("anvil-publish") } -val velocityVersion: String by project - dependencies { implementation(project(":anvil-core")) - compileOnly(libs.velocity) - kapt(libs.velocity) + compileOnlyApi(libs.velocity) } diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/AnvilVelocityApi.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/AnvilVelocityApi.kt new file mode 100644 index 000000000..0c17808c0 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/AnvilVelocityApi.kt @@ -0,0 +1,121 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity + +import com.google.inject.Injector +import com.velocitypowered.api.plugin.PluginContainer +import com.velocitypowered.api.plugin.PluginDescription +import com.velocitypowered.api.proxy.ProxyServer +import org.anvilpowered.anvil.core.AnvilApi +import org.anvilpowered.anvil.core.command.CommandExecutor +import org.anvilpowered.anvil.core.platform.PluginManager +import org.anvilpowered.anvil.core.platform.Server +import org.anvilpowered.anvil.core.user.PlayerService +import org.anvilpowered.anvil.velocity.command.VelocityCommandExecutor +import org.anvilpowered.anvil.velocity.platform.VelocityPluginManager +import org.anvilpowered.anvil.velocity.platform.VelocityServer +import org.anvilpowered.anvil.velocity.user.VelocityPlayerService +import org.apache.logging.log4j.LogManager +import org.apache.logging.log4j.Logger +import org.koin.core.module.Module +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +/** + * A subtype of [AnvilApi] that also provides access to Velocity-specific APIs such as [ProxyServer]. + * + * To create an instance of this interface, use [AnvilApi.Companion.createVelocity]. + * + * If you are using Java, the method [AnvilVelocityApi.doNotUse] is provided as an alternative. + */ +interface AnvilVelocityApi : AnvilApi { + + companion object { + /** + * Creates an Anvil API instance for Velocity. + * + * This method is meant as an alternative to [AnvilApi.Companion.createVelocity] for Java users. + * + * In Kotlin, you should use [AnvilApi.Companion.createVelocity] instead. + */ + @JvmStatic + @JvmName("create") + fun doNotUse(injector: Injector): AnvilVelocityApi = + AnvilApi.createVelocity(injector) + } +} + +/** + * Creates an Anvil API instance for Velocity. + * + * The returned API instance can be used to access the Anvil API. + * It is intended to be used as a context receiver. + * + * For example, you can access it in a class like this: + * ```kt + * context(AnvilVelocityApi) // or AnvilApi if in common code + * class MyPlugin { + * fun foo() { + * logger.info { "Hello, world!" } // logger property of [AnvilApi] is accessed through context receiver + * } + * } + * ``` + * + * In order to invoke this constructor, you must have an instance of [AnvilVelocityApi] in the calling context. + * To bring an instance of [AnvilVelocityApi] into the calling context, you can use the [with] function: + * + * ```kt + * private val plugin = with(AnvilApi.createVelocity(logger, proxyServer)) { + * AnvilVelocityPlugin() + * } + * ``` + * + * Context receivers may also be used on individual functions. + * This is particularly useful for top-level functions: + * + * ```kt + * context(AnvilVelocityApi) // or AnvilApi if in common code + * fun foo() { + * logger.info { "Hello, world!" } // logger property of [AnvilApi] is accessed through context receiver + * } + * ``` + */ +fun AnvilApi.Companion.createVelocity(injector: Injector): AnvilVelocityApi { + val proxyServer = injector.getInstance(ProxyServer::class.java) + val pluginDescription = injector.getInstance(PluginDescription::class.java) + val velocityModule = module { + single { LogManager.getLogger(pluginDescription.id) } + single { VelocityServer(proxyServer) } + single { VelocityPluginManager(proxyServer.pluginManager) } + single { proxyServer } + single { pluginDescription } + single { injector.getInstance(PluginContainer::class.java) } + singleOf(::VelocityPlayerService) { + bind() + } + singleOf(::VelocityCommandExecutor) { + bind() + } + } + + return object : AnvilVelocityApi { + override val module: Module = velocityModule + } +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/AnvilVelocityCommandSource.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/AnvilVelocityCommandSource.kt new file mode 100644 index 000000000..2895f80d4 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/AnvilVelocityCommandSource.kt @@ -0,0 +1,38 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.command + +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import org.anvilpowered.anvil.velocity.user.toAnvilPlayer +import org.anvilpowered.anvil.velocity.user.toAnvilSubject +import com.velocitypowered.api.command.CommandSource as VelocityCommandSource +import com.velocitypowered.api.proxy.Player as VelocityPlayer + +fun VelocityCommandSource.toAnvilCommandSource(): CommandSource = AnvilVelocityCommandSource(this) + +private class AnvilVelocityCommandSource( + override val platformDelegate: VelocityCommandSource, +) : CommandSource { + override val audience: Audience = platformDelegate + override val subject: Subject = platformDelegate.toAnvilSubject() + override val player: Player? = (platformDelegate as? VelocityPlayer)?.toAnvilPlayer() +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCommandExecutor.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCommandExecutor.kt new file mode 100644 index 000000000..8e42a2a3b --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCommandExecutor.kt @@ -0,0 +1,43 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.command + +import com.velocitypowered.api.proxy.ProxyServer +import kotlinx.coroutines.future.await +import org.anvilpowered.anvil.core.command.CommandExecutor +import org.anvilpowered.anvil.core.command.CommandSource +import com.velocitypowered.api.command.CommandSource as VelocityCommandSource + +class VelocityCommandExecutor( + private val proxyServer: ProxyServer, +) : CommandExecutor { + override suspend fun execute(source: CommandSource, command: String): Boolean { + return proxyServer.commandManager.executeAsync( + source.platformDelegate as VelocityCommandSource, + command, + ).await() + } + + override suspend fun executeAsConsole(command: String): Boolean { + return proxyServer.commandManager.executeAsync( + proxyServer.consoleCommandSource, + command, + ).await() + } +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCustomCommand.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCustomCommand.kt new file mode 100644 index 000000000..edb51127f --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocityCustomCommand.kt @@ -0,0 +1,60 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.command + +import com.velocitypowered.api.proxy.ProxyServer +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.anvil.core.command.PlayerCommandScope +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.velocity.user.toAnvilPlayer +import org.anvilpowered.kbrig.argument.StringArgumentType +import org.anvilpowered.kbrig.builder.ArgumentBuilder +import org.anvilpowered.kbrig.builder.RequiredArgumentBuilder +import org.anvilpowered.kbrig.context.CommandContext +import org.anvilpowered.kbrig.context.get +import kotlin.jvm.optionals.getOrNull + +class VelocityCustomCommand(private val proxyServer: ProxyServer) : PlayerCommandScope { + + override fun ArgumentBuilder.Companion.player( + argumentName: String, + command: (context: CommandContext, player: Player) -> Int, + ): RequiredArgumentBuilder = + required(argumentName, StringArgumentType.SingleWord) + .suggests { _, builder -> + proxyServer.allPlayers.forEach { player -> builder.suggest(player.username) } + builder.build() + } + .executes { context -> + val playerName = context.get(argumentName) + proxyServer.getPlayer(playerName).getOrNull()?.let { velocityPlayer -> + command(context, velocityPlayer.toAnvilPlayer()) + } ?: run { + context.source.audience.sendMessage( + Component.text() + .append(Component.text("Player with name ", NamedTextColor.RED)) + .append(Component.text(playerName, NamedTextColor.GOLD)) + .append(Component.text(" not found!", NamedTextColor.RED)), + ) + 0 + } + } +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocitySourceConverter.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocitySourceConverter.kt new file mode 100644 index 000000000..288ffcd79 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/command/VelocitySourceConverter.kt @@ -0,0 +1,42 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +@file:JvmName("VelocitySourceConverter") + +package org.anvilpowered.anvil.velocity.command + +import org.anvilpowered.anvil.core.command.CommandSource +import org.anvilpowered.kbrig.brigadier.toBrigadier +import org.anvilpowered.kbrig.tree.ArgumentCommandNode +import org.anvilpowered.kbrig.tree.LiteralCommandNode +import org.anvilpowered.kbrig.tree.mapSource +import com.mojang.brigadier.tree.ArgumentCommandNode as BrigadierArgumentCommandNode +import com.mojang.brigadier.tree.LiteralCommandNode as BrigadierLiteralCommandNode1 +import com.velocitypowered.api.command.CommandSource as VelocityCommandSource + +/** + * Converts a kbrig argument command node to a velocity brigadier argument command node. + */ +fun ArgumentCommandNode.toVelocity(): BrigadierArgumentCommandNode = + mapSource { it.toAnvilCommandSource() }.toBrigadier() + +/** + * Converts a kbrig literal command node to a velocity brigadier literal command node. + */ +fun LiteralCommandNode.toVelocity(): BrigadierLiteralCommandNode1 = + mapSource { it.toAnvilCommandSource() }.toBrigadier() diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlatform.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlatform.kt new file mode 100644 index 000000000..cb3ac6188 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlatform.kt @@ -0,0 +1,31 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.platform + +import com.velocitypowered.api.proxy.ProxyServer +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Plugin + +internal class VelocityPlatform(private val proxyServer: ProxyServer) : Platform { + override val isProxy: Boolean = true + override val plugins: List + get() = proxyServer.pluginManager.plugins.map { it.toAnvilPlugin() } + override val name: String = "velocity" + override val version: String = proxyServer.version.version +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlugin.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlugin.kt new file mode 100644 index 000000000..01b518049 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPlugin.kt @@ -0,0 +1,29 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.platform + +import com.velocitypowered.api.plugin.PluginContainer +import org.anvilpowered.anvil.core.platform.Plugin + +internal fun PluginContainer.toAnvilPlugin() = VelocityPlugin(this) + +internal class VelocityPlugin(private val container: PluginContainer) : Plugin { + override val name: String + get() = container.description.id +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPluginManager.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPluginManager.kt new file mode 100644 index 000000000..78e509873 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityPluginManager.kt @@ -0,0 +1,28 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.platform + +import org.anvilpowered.anvil.core.platform.Plugin +import org.anvilpowered.anvil.core.platform.PluginManager +import com.velocitypowered.api.plugin.PluginManager as BackingPluginManager + +internal class VelocityPluginManager(private val backing: BackingPluginManager) : PluginManager { + override val plugins: List + get() = backing.plugins.map { VelocityPlugin(it) } +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityServer.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityServer.kt new file mode 100644 index 000000000..4d0a6b04f --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/platform/VelocityServer.kt @@ -0,0 +1,30 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.platform + +import com.velocitypowered.api.proxy.ProxyServer +import net.kyori.adventure.audience.Audience +import org.anvilpowered.anvil.core.platform.Platform +import org.anvilpowered.anvil.core.platform.Server + +class VelocityServer(proxyServer: ProxyServer) : Server { + override val platform: Platform = VelocityPlatform(proxyServer) + override val broadcastAudience: Audience = proxyServer + override val systemSubject: Audience = proxyServer.consoleCommandSource +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocityPlayer.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocityPlayer.kt new file mode 100644 index 000000000..7156aeb58 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocityPlayer.kt @@ -0,0 +1,40 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.user + +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.text.Component +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.Subject +import java.util.UUID +import com.velocitypowered.api.proxy.Player as VelocityPlayer + +fun VelocityPlayer.toAnvilPlayer(): Player = AnvilVelocityPlayer(this) + +private class AnvilVelocityPlayer( + val velocityPlayer: VelocityPlayer, +) : Player, + Audience by velocityPlayer, + Subject by velocityPlayer.toAnvilSubject() { + override val id: UUID = velocityPlayer.uniqueId + override val username: String = velocityPlayer.username + override val displayname: Component = Component.text(velocityPlayer.username) + override val latencyMs: Int + get() = velocityPlayer.ping.toInt() +} diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocitySubject.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocitySubject.kt new file mode 100644 index 000000000..f3766a51f --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/AnvilVelocitySubject.kt @@ -0,0 +1,38 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.user + +import com.velocitypowered.api.permission.Tristate +import org.anvilpowered.anvil.core.user.Subject +import com.velocitypowered.api.permission.PermissionSubject as VelocitySubject + +fun VelocitySubject.toAnvilSubject(): Subject = AnvilVelocitySubject(this) + +private class AnvilVelocitySubject( + override val platformDelegate: VelocitySubject, +) : Subject { + override fun hasPermission(permission: String): Boolean? = + platformDelegate.getPermissionValue(permission).toBoolean() +} + +private fun Tristate.toBoolean(): Boolean? = when (this) { + Tristate.TRUE -> true + Tristate.FALSE -> false + Tristate.UNDEFINED -> null +} diff --git a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/module/VelocityFallbackModule.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/ArgumentExtensions.kt similarity index 54% rename from anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/module/VelocityFallbackModule.kt rename to velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/ArgumentExtensions.kt index 4edcac8ca..4ed22b5b7 100644 --- a/anvil-velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/module/VelocityFallbackModule.kt +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/ArgumentExtensions.kt @@ -1,25 +1,25 @@ /* - * Anvil - AnvilPowered - * Copyright (C) 2020-2021 + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by + * 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. * * 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 Lesser General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.anvilpowered.anvil.velocity.module +package org.anvilpowered.anvil.velocity.user import com.velocitypowered.api.command.CommandSource -import net.kyori.adventure.text.TextComponent -import org.anvilpowered.anvil.common.module.FallbackModule +import org.anvilpowered.kbrig.builder.ArgumentBuilder -class VelocityFallbackModule : FallbackModule() +fun > B.requiresPermission(permission: String): B = + requires { it.hasPermission(permission) } diff --git a/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/VelocityPlayerService.kt b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/VelocityPlayerService.kt new file mode 100644 index 000000000..6900fc9f7 --- /dev/null +++ b/velocity/src/main/kotlin/org/anvilpowered/anvil/velocity/user/VelocityPlayerService.kt @@ -0,0 +1,37 @@ +/* + * Anvil - AnvilPowered.org + * Copyright (C) 2019-2024 Contributors + * + * This program 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. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.anvilpowered.anvil.velocity.user + +import com.velocitypowered.api.proxy.ProxyServer +import org.anvilpowered.anvil.core.user.Player +import org.anvilpowered.anvil.core.user.PlayerService +import java.util.UUID + +class VelocityPlayerService(private val proxyServer: ProxyServer) : PlayerService { + override fun get(username: String): Player? = + proxyServer.getPlayer(username).orElse(null)?.toAnvilPlayer() + + override fun get(id: UUID): Player? = + proxyServer.getPlayer(id).orElse(null)?.toAnvilPlayer() + + override fun getAll(startsWith: String): Sequence = when (startsWith) { + "" -> proxyServer.allPlayers.asSequence().map { it.toAnvilPlayer() } + else -> proxyServer.matchPlayer(startsWith).asSequence().map { it.toAnvilPlayer() } + } +}