Merge branch 'main' into ban-sync

This commit is contained in:
Vankka 2024-04-13 17:10:35 +03:00
commit 53e216ea2a
No known key found for this signature in database
GPG Key ID: 6E50CB7A29B96AD0
19 changed files with 4 additions and 1229 deletions

View File

@ -1,6 +1,8 @@
# Temporary repository for DiscordSRV3 [Testing builds available on our Discord server] # Ascension
# DiscordSRV This is a temporary repository for developing the next major version of DiscordSRV,
if you are interested in more details, contributing or testing builds join our [Discord server](https://discord.discordsrv.com),
opt-in to the `Tester` role in `#notifications` and check out the `#ascension-testing` forum.
### License ### License

View File

@ -17,7 +17,6 @@ dependencies {
// Depend on all platforms for configs // Depend on all platforms for configs
implementation(project(':bukkit')) { transitive = false } implementation(project(':bukkit')) { transitive = false }
implementation(project(':bungee')) { transitive = false } implementation(project(':bungee')) { transitive = false }
implementation(project(':sponge')) { transitive = false }
implementation(project(':velocity')) { transitive = false } implementation(project(':velocity')) { transitive = false }
api(libs.configurate.yaml) api(libs.configurate.yaml)

View File

@ -29,11 +29,6 @@ dependencyResolutionManagement {
// Bungee // Bungee
library('bungee', 'net.md-5', 'bungeecord-api').version('1.17-R0.1-SNAPSHOT') library('bungee', 'net.md-5', 'bungeecord-api').version('1.17-R0.1-SNAPSHOT')
// Sponge
version('sponge', '8.0.0')
library('spongeapi', 'org.spongepowered', 'spongeapi').versionRef('sponge')
plugin('spongeplugin', 'org.spongepowered.gradle.plugin').version('2.0.0')
// Velocity // Velocity
library('velocity', 'com.velocitypowered', 'velocity-api').version('3.0.0') library('velocity', 'com.velocitypowered', 'velocity-api').version('3.0.0')
@ -154,7 +149,6 @@ rootProject.name = 'DiscordSRV-Ascension'
'api', 'api',
'bukkit', 'bukkit:loader', 'bukkit:folia', 'bukkit:spigot', 'bukkit:paper', 'bukkit:bukkit1_12', 'bukkit', 'bukkit:loader', 'bukkit:folia', 'bukkit:spigot', 'bukkit:paper', 'bukkit:bukkit1_12',
'bungee', 'bungee:loader', 'bungee', 'bungee:loader',
'sponge', 'sponge:loader',
'velocity' 'velocity'
].each { ].each {
include it include it

View File

@ -1,38 +0,0 @@
apply from: rootProject.file('buildscript/runtime.gradle')
shadowJar {
archiveFileName = 'sponge.jarinjar'
// Relocations in buildscript/relocations.gradle
}
allprojects {
repositories {
// exclusiveContent {
// forRepository {
maven { url 'https://repo.spongepowered.org/maven/' }
// }
// filter {
// includeGroup 'org.spongepowered'
// }
// }
}
dependencies {
// Platform
annotationProcessor(libs.spongeapi)
compileOnly(libs.spongeapi)
}
}
dependencies {
// API
annotationProcessor project(':api')
// Common
implementation project(':common')
// Dependency Download
implementation(libs.dependencydownload.jarinjar.bootstrap)
compileOnlyApi project(':sponge:sponge-loader')
}

View File

@ -1,53 +0,0 @@
import org.spongepowered.gradle.plugin.config.PluginLoaders
import org.spongepowered.plugin.metadata.model.PluginDependency
plugins {
alias(libs.plugins.spongeplugin)
}
apply from: rootProject.file('buildscript/loader.gradle')
dependencies {
// API
implementation project(':common:common-api')
// DependencyDownload
implementation(libs.dependencydownload.jarinjar.loader)
}
shadowJar {
archiveBaseName = 'DiscordSRV-Sponge'
}
// buildscript/loader.gradle includes the jarinjar in the jar
sponge {
apiVersion(libs.versions.sponge.get())
license('GPLv3')
loader {
name(PluginLoaders.JAVA_PLAIN)
version('1.0')
}
plugin('discordsrv') {
displayName('DiscordSRV')
version(project.version)
entrypoint('com.discordsrv.sponge.loader.DiscordSRVSpongeLoader')
description('')
links {
homepage('https://discordsrv.com')
source('https://github.com/DiscordSRV/DiscordSRV')
issues('https://github.com/DiscordSRV/DiscordSRV/issues')
}
contributor('Scarsz') {
description('Developer')
}
contributor('Vankka') {
description('Developer')
}
dependency('spongeapi') {
loadOrder(PluginDependency.LoadOrder.AFTER)
version('[8.0.0,)')
optional(false)
}
}
}

View File

@ -1,27 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.bootstrap;
public interface ISpongeBootstrap {
default void onConstruct() {}
default void onRefresh() {}
default void onStarted() {}
default void onStopping() {}
}

View File

@ -1,135 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.loader;
import com.discordsrv.sponge.bootstrap.ISpongeBootstrap;
import com.google.inject.Inject;
import dev.vankka.dependencydownload.jarinjar.classloader.JarInJarClassLoader;
import dev.vankka.dependencydownload.jarinjar.loader.ILoader;
import dev.vankka.dependencydownload.jarinjar.loader.exception.LoadingException;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.Game;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.ConstructPluginEvent;
import org.spongepowered.api.event.lifecycle.RefreshGameEvent;
import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
import org.spongepowered.api.event.lifecycle.StoppingEngineEvent;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.builtin.jvm.Plugin;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.nio.file.Path;
import java.util.Optional;
@Plugin("discordsrv")
public class DiscordSRVSpongeLoader implements ILoader {
private final PluginContainer pluginContainer;
private final Game game;
private final Path dataDirectory;
private final JarInJarClassLoader classLoader;
private ISpongeBootstrap bootstrap;
@Inject
public DiscordSRVSpongeLoader(PluginContainer pluginContainer, Game game, @ConfigDir(sharedRoot = false) Path dataDirectory) {
this.pluginContainer = pluginContainer;
this.game = game;
this.dataDirectory = dataDirectory;
if (!game.platform().type().isServer()) {
Logger logger = pluginContainer.logger();
logger.error("+---------------------------------------------+");
logger.error("| DiscordSRV does not run on clients |");
logger.error("| DiscordSRV can only be installed on servers |");
logger.error("+---------------------------------------------+");
this.classLoader = null;
return;
}
this.classLoader = initialize();
}
private Optional<ISpongeBootstrap> bootstrap() {
return Optional.ofNullable(bootstrap);
}
@Override
public @NotNull String getBootstrapClassName() {
return "com.discordsrv.sponge.DiscordSRVSpongeBootstrap";
}
@Override
public void initiateBootstrap(Class<?> bootstrapClass, @NotNull JarInJarClassLoader classLoader) throws ReflectiveOperationException {
Constructor<?> constructor = bootstrapClass.getConstructor(PluginContainer.class, Game.class, JarInJarClassLoader.class, Path.class);
bootstrap = (ISpongeBootstrap) constructor.newInstance(pluginContainer, game, classLoader, dataDirectory);
}
@Override
public void handleLoadingException(LoadingException exception) {
pluginContainer.logger().error(exception.getMessage(), exception.getCause());
}
@Override
public @NotNull String getName() {
return "DiscordSRV";
}
@Override
public @NotNull ClassLoader getParentClassLoader() {
return getClass().getClassLoader();
}
@Override
public @NotNull URL getJarInJarResource() {
URL resource = getParentClassLoader().getResource("sponge.jarinjar");
if (resource == null) {
throw new IllegalStateException("Jar does not contain jarinjar");
}
return resource;
}
@Listener
public void onConstructPlugin(ConstructPluginEvent event) {
bootstrap().ifPresent(ISpongeBootstrap::onConstruct);
}
@Listener
public void onRefreshGame(RefreshGameEvent event) {
bootstrap().ifPresent(ISpongeBootstrap::onRefresh);
}
@Listener
public void onStartedEngine(StartedEngineEvent<?> event) {
bootstrap().ifPresent(ISpongeBootstrap::onStarted);
}
@Listener
public void onStoppingEngine(StoppingEngineEvent<?> event) {
bootstrap().ifPresent(ISpongeBootstrap::onStopping);
try {
classLoader.close();
} catch (IOException e) {
pluginContainer.logger().error("Failed to close JarInJarClassLoader", e);
}
}
}

View File

@ -1,127 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge;
import com.discordsrv.common.bootstrap.IBootstrap;
import com.discordsrv.common.bootstrap.LifecycleManager;
import com.discordsrv.common.logging.Logger;
import com.discordsrv.common.logging.backend.impl.Log4JLoggerImpl;
import com.discordsrv.sponge.bootstrap.ISpongeBootstrap;
import com.discordsrv.sponge.command.game.handler.SpongeCommandHandler;
import dev.vankka.dependencydownload.classpath.ClasspathAppender;
import dev.vankka.dependencydownload.jarinjar.bootstrap.AbstractBootstrap;
import dev.vankka.dependencydownload.jarinjar.bootstrap.classpath.JarInJarClasspathAppender;
import dev.vankka.dependencydownload.jarinjar.classloader.JarInJarClassLoader;
import org.spongepowered.api.Game;
import org.spongepowered.plugin.PluginContainer;
import java.io.IOException;
import java.nio.file.Path;
@SuppressWarnings("unused") // Reflection
public class DiscordSRVSpongeBootstrap extends AbstractBootstrap implements ISpongeBootstrap, IBootstrap {
private final Logger logger;
private final ClasspathAppender classpathAppender;
private final LifecycleManager lifecycleManager;
private SpongeDiscordSRV discordSRV;
private SpongeCommandHandler commandHandler;
private final PluginContainer pluginContainer;
private final Game game;
private final Path dataDirectory;
public DiscordSRVSpongeBootstrap(PluginContainer pluginContainer, Game game, JarInJarClassLoader classLoader, Path dataDirectory) throws IOException {
// Don't change these parameters
super(classLoader);
this.logger = new Log4JLoggerImpl(pluginContainer.logger());
this.classpathAppender = new JarInJarClasspathAppender(classLoader);
this.lifecycleManager = new LifecycleManager(
logger,
dataDirectory,
new String[] {"dependencies/runtimeDownload-sponge.txt"},
classpathAppender
);
this.pluginContainer = pluginContainer;
this.game = game;
this.dataDirectory = dataDirectory;
}
@Override
public void onConstruct() {
lifecycleManager.loadAndEnable(() -> this.discordSRV = new SpongeDiscordSRV(this));
this.commandHandler = new SpongeCommandHandler(() -> discordSRV, pluginContainer);
game.eventManager().registerListeners(pluginContainer, commandHandler);
}
@Override
public void onStarted() {
if (discordSRV != null) {
discordSRV.invokeServerStarted();
}
}
@Override
public void onRefresh() {
lifecycleManager.reload(discordSRV);
}
@Override
public void onStopping() {
lifecycleManager.disable(discordSRV);
}
@Override
public Logger logger() {
return logger;
}
@Override
public ClasspathAppender classpathAppender() {
return classpathAppender;
}
@Override
public ClassLoader classLoader() {
return getClassLoader();
}
@Override
public LifecycleManager lifecycleManager() {
return lifecycleManager;
}
@Override
public Path dataDirectory() {
return dataDirectory;
}
public PluginContainer pluginContainer() {
return pluginContainer;
}
public Game game() {
return game;
}
public SpongeCommandHandler commandHandler() {
return commandHandler;
}
}

View File

@ -1,128 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge;
import com.discordsrv.api.DiscordSRVApi;
import com.discordsrv.common.ServerDiscordSRV;
import com.discordsrv.common.command.game.handler.ICommandHandler;
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
import com.discordsrv.common.config.connection.ConnectionConfig;
import com.discordsrv.common.config.main.MainConfig;
import com.discordsrv.common.config.messages.MessagesConfig;
import com.discordsrv.common.debug.data.OnlineMode;
import com.discordsrv.common.plugin.PluginManager;
import com.discordsrv.sponge.console.SpongeConsole;
import com.discordsrv.sponge.player.SpongePlayerProvider;
import com.discordsrv.sponge.plugin.SpongePluginManager;
import com.discordsrv.sponge.scheduler.SpongeScheduler;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.Game;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.ProvideServiceEvent;
import org.spongepowered.plugin.PluginContainer;
public class SpongeDiscordSRV extends ServerDiscordSRV<DiscordSRVSpongeBootstrap, MainConfig, ConnectionConfig, MessagesConfig> {
private final SpongeScheduler scheduler;
private final SpongeConsole console;
private final SpongePlayerProvider playerProvider;
private final SpongePluginManager pluginManager;
public SpongeDiscordSRV(DiscordSRVSpongeBootstrap bootstrap) {
super(bootstrap);
this.scheduler = new SpongeScheduler(this);
this.console = new SpongeConsole(this);
this.playerProvider = new SpongePlayerProvider(this);
this.pluginManager = new SpongePluginManager(this);
load();
}
public PluginContainer container() {
return bootstrap.pluginContainer();
}
public Game game() {
return bootstrap.game();
}
@Override
public SpongeScheduler scheduler() {
return scheduler;
}
@Override
public SpongeConsole console() {
return console;
}
@Override
public @NotNull SpongePlayerProvider playerProvider() {
return playerProvider;
}
@Override
public PluginManager pluginManager() {
return pluginManager;
}
@Override
public OnlineMode onlineMode() {
// TODO: velocity / bungee
return OnlineMode.of(game().server().isOnlineModeEnabled());
}
@Override
public ICommandHandler commandHandler() {
return bootstrap.commandHandler();
}
@Override
public ConnectionConfigManager<ConnectionConfig> connectionConfigManager() {
return null;
}
@Override
public MainConfigManager<MainConfig> configManager() {
return null;
}
@Override
public MessagesConfigManager<MessagesConfig> messagesConfigManager() {
return null;
}
@Override
protected void enable() throws Throwable {
// Service provider
game().eventManager().registerListeners(container(), this);
super.enable();
}
@Listener
public void onServiceProvide(ProvideServiceEvent<DiscordSRVApi> event) {
// Service provider
event.suggest(() -> this);
}
}

View File

@ -1,146 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.command.game.handler;
import com.discordsrv.common.command.game.abstraction.GameCommand;
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
import com.discordsrv.common.command.game.handler.ICommandHandler;
import com.discordsrv.common.command.game.sender.ICommandSender;
import com.discordsrv.sponge.SpongeDiscordSRV;
import com.discordsrv.sponge.command.game.sender.SpongeCommandSender;
import net.kyori.adventure.audience.Audience;
import org.spongepowered.api.SystemSubject;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.parameter.CommandContext;
import org.spongepowered.api.command.parameter.Parameter;
import org.spongepowered.api.command.parameter.managed.Flag;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.plugin.PluginContainer;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Supplier;
/**
* Sponge has its own api for interacting with Brigadier...
*/
public class SpongeCommandHandler implements ICommandHandler {
private final Map<String, Command.Parameterized> commands = new LinkedHashMap<>();
private final Supplier<SpongeDiscordSRV> discordSRV;
private final PluginContainer container;
public SpongeCommandHandler(Supplier<SpongeDiscordSRV> discordSRV, PluginContainer container) {
this.discordSRV = discordSRV;
this.container = container;
}
@Override
public void registerCommand(GameCommand command) {
commands.put(command.getLabel(), remap(command));
}
private ICommandSender getSender(Subject subject, Audience audience) {
SpongeDiscordSRV discordSRV = this.discordSRV.get();
if (discordSRV != null) {
if (subject instanceof ServerPlayer) {
return discordSRV.playerProvider().player((ServerPlayer) subject);
} else if (subject instanceof SystemSubject) {
return discordSRV.console();
}
}
return new SpongeCommandSender(discordSRV, () -> subject, () -> audience);
}
private ICommandSender getSender(CommandContext context) {
return getSender(context.subject(), context.cause().audience());
}
private Command.Parameterized remap(GameCommand command) {
GameCommand redirection = command.getRedirection();
if (redirection != null) {
command = redirection;
}
//GameCommandSuggester suggester = command.getSuggester();
GameCommandExecutor executor = command.getExecutor();
String permission = command.getRequiredPermission();
Command.Builder builder = Command.builder();
builder.addFlag(Flag.builder().alias(command.getLabel()).build());
if (permission != null) {
builder.permission(permission);
}
for (GameCommand child : command.getChildren()) {
builder.addChild(remap(child));
}
if (executor != null) {
String label = command.getLabel();
builder.executor(context -> {
executor.execute(getSender(context), new GameCommandArguments() {
@Override
public <T> T get(String label, Class<T> type) {
return context.one(new Parameter.Key<T>() {
@Override
public String key() {
return label;
}
@Override
public Type type() {
return type;
}
@Override
public boolean isInstance(Object value) {
return type.isInstance(value);
}
@SuppressWarnings("unchecked")
@Override
public T cast(Object value) {
return (T) value;
}
}).orElse(null);
}
}, label);
return CommandResult.success();
});
}
return builder.build();
}
@Listener
public void onRegister(RegisterCommandEvent<Command.Parameterized> event) {
for (Map.Entry<String, Command.Parameterized> entry : commands.entrySet()) {
event.register(container, entry.getValue(), entry.getKey());
}
}
}

View File

@ -1,59 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.command.game.sender;
import com.discordsrv.common.command.game.sender.ICommandSender;
import com.discordsrv.sponge.SpongeDiscordSRV;
import net.kyori.adventure.audience.Audience;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.command.exception.CommandException;
import org.spongepowered.api.service.permission.Subject;
import java.util.function.Supplier;
public class SpongeCommandSender implements ICommandSender {
protected final SpongeDiscordSRV discordSRV;
protected final Supplier<Subject> subjectSupplier;
protected final Supplier<Audience> audienceSupplier;
public SpongeCommandSender(SpongeDiscordSRV discordSRV, Supplier<Subject> subjectSupplier, Supplier<Audience> audienceSupplier) {
this.discordSRV = discordSRV;
this.subjectSupplier = subjectSupplier;
this.audienceSupplier = audienceSupplier;
}
@Override
public boolean hasPermission(String permission) {
return subjectSupplier.get().hasPermission(permission);
}
@Override
public void runCommand(String command) {
try {
Subject subject = subjectSupplier.get();
discordSRV.game().server().commandManager().process((Subject & Audience) subject, command);
} catch (CommandException ignored) {}
}
@Override
public @NotNull Audience audience() {
return audienceSupplier.get();
}
}

View File

@ -1,49 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.console;
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
import com.discordsrv.common.console.Console;
import com.discordsrv.common.logging.backend.LoggingBackend;
import com.discordsrv.common.logging.backend.impl.Log4JLoggerImpl;
import com.discordsrv.sponge.SpongeDiscordSRV;
import com.discordsrv.sponge.command.game.sender.SpongeCommandSender;
import com.discordsrv.sponge.console.executor.SpongeCommandExecutorProvider;
public class SpongeConsole extends SpongeCommandSender implements Console {
private final LoggingBackend loggingBackend;
private final SpongeCommandExecutorProvider executorProvider;
public SpongeConsole(SpongeDiscordSRV discordSRV) {
super(discordSRV, () -> discordSRV.game().systemSubject(), () -> discordSRV.game().systemSubject());
this.loggingBackend = Log4JLoggerImpl.getRoot();
this.executorProvider = new SpongeCommandExecutorProvider(discordSRV);
}
@Override
public LoggingBackend loggingBackend() {
return loggingBackend;
}
@Override
public CommandExecutorProvider commandExecutorProvider() {
return executorProvider;
}
}

View File

@ -1,58 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.console.executor;
import com.discordsrv.common.command.game.executor.AdventureCommandExecutorProxy;
import com.discordsrv.common.command.game.executor.CommandExecutor;
import com.discordsrv.sponge.SpongeDiscordSRV;
import net.kyori.adventure.text.Component;
import org.spongepowered.api.SystemSubject;
import org.spongepowered.api.command.exception.CommandException;
import java.util.function.Consumer;
public class SpongeCommandExecutor implements CommandExecutor {
private final SpongeDiscordSRV discordSRV;
private final SystemSubject subject;
public SpongeCommandExecutor(SpongeDiscordSRV discordSRV, Consumer<Component> componentConsumer) {
this.discordSRV = discordSRV;
this.subject = (SystemSubject) new AdventureCommandExecutorProxy(
discordSRV.game().systemSubject(),
componentConsumer
).getProxy();
}
@Override
public void runCommand(String command) {
discordSRV.scheduler().runOnMainThread(() -> runOnMain(command));
}
private void runOnMain(String command) {
try {
discordSRV.game().server().commandManager().process(subject, command);
} catch (CommandException e) {
Component message = e.componentMessage();
if (message != null) {
subject.sendMessage(message);
}
}
}
}

View File

@ -1,40 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.console.executor;
import com.discordsrv.common.command.game.executor.CommandExecutor;
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
import com.discordsrv.sponge.SpongeDiscordSRV;
import net.kyori.adventure.text.Component;
import java.util.function.Consumer;
public class SpongeCommandExecutorProvider implements CommandExecutorProvider {
private final SpongeDiscordSRV discordSRV;
public SpongeCommandExecutorProvider(SpongeDiscordSRV discordSRV) {
this.discordSRV = discordSRV;
}
@Override
public CommandExecutor getConsoleExecutor(Consumer<Component> componentConsumer) {
return new SpongeCommandExecutor(discordSRV, componentConsumer);
}
}

View File

@ -1,69 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.player;
import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.player.IOfflinePlayer;
import com.discordsrv.common.player.provider.model.SkinInfo;
import com.discordsrv.common.player.provider.model.Textures;
import com.discordsrv.sponge.SpongeDiscordSRV;
import net.kyori.adventure.identity.Identity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.profile.property.ProfileProperty;
public class SpongeOfflinePlayer implements IOfflinePlayer {
protected final SpongeDiscordSRV discordSRV;
private final User user;
public SpongeOfflinePlayer(SpongeDiscordSRV discordSRV, User user) {
this.discordSRV = discordSRV;
this.user = user;
}
@Override
public DiscordSRV discordSRV() {
return discordSRV;
}
@Override
public @NotNull String username() {
return user.name();
}
@Override
public @Nullable SkinInfo skinInfo() {
for (ProfileProperty property : user.profile().properties()) {
if (!Textures.KEY.equals(property.name())) {
continue;
}
Textures textures = Textures.getFromBase64(discordSRV, property.value());
return textures.getSkinInfo();
}
return null;
}
@Override
public @NotNull Identity identity() {
return user.profile();
}
}

View File

@ -1,77 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.player;
import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.player.IPlayer;
import com.discordsrv.common.player.provider.model.SkinInfo;
import com.discordsrv.common.player.provider.model.Textures;
import com.discordsrv.sponge.SpongeDiscordSRV;
import com.discordsrv.sponge.command.game.sender.SpongeCommandSender;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import java.util.Locale;
public class SpongePlayer extends SpongeCommandSender implements IPlayer {
private final ServerPlayer player;
private final Identity identity;
public SpongePlayer(SpongeDiscordSRV discordSRV, ServerPlayer player) {
super(discordSRV, () -> player, () -> player);
this.player = player;
this.identity = Identity.identity(player.uniqueId());
}
@Override
public DiscordSRV discordSRV() {
return discordSRV;
}
@Override
public @NotNull String username() {
return player.name();
}
@Override
public @Nullable SkinInfo skinInfo() {
String texturesRaw = player.skinProfile().get().value();
Textures textures = Textures.getFromBase64(discordSRV, texturesRaw);
return textures.getSkinInfo();
}
@Override
public @Nullable Locale locale() {
return player.locale();
}
@Override
public @NotNull Component displayName() {
return player.displayName().get();
}
@Override
public @NotNull Identity identity() {
return identity;
}
}

View File

@ -1,107 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.player;
import com.discordsrv.common.player.IOfflinePlayer;
import com.discordsrv.common.player.IPlayer;
import com.discordsrv.common.player.provider.ServerPlayerProvider;
import com.discordsrv.sponge.SpongeDiscordSRV;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class SpongePlayerProvider extends ServerPlayerProvider<SpongePlayer, SpongeDiscordSRV> {
public SpongePlayerProvider(SpongeDiscordSRV discordSRV) {
super(discordSRV);
}
// IPlayer
@Override
public void subscribe() {
discordSRV.game().eventManager().registerListeners(discordSRV.container(), this);
// Add players that are already connected
for (ServerPlayer player : discordSRV.game().server().onlinePlayers()) {
addPlayer(player, true);
}
}
@Listener(order = Order.PRE)
public void onPlayerJoin(ServerSideConnectionEvent.Join event) {
addPlayer(event.player(), false);
}
private void addPlayer(ServerPlayer player, boolean initial) {
addPlayer(player.uniqueId(), new SpongePlayer(discordSRV, player), initial);
}
@Listener(order = Order.POST)
public void onPlayerDisconnect(ServerSideConnectionEvent.Disconnect event) {
removePlayer(event.player().uniqueId());
}
public SpongePlayer player(ServerPlayer player) {
SpongePlayer srvPlayer = player(player.uniqueId());
if (srvPlayer == null) {
throw new IllegalStateException("Player not available");
}
return srvPlayer;
}
// IOfflinePlayer
private IOfflinePlayer convert(User user) {
return new SpongeOfflinePlayer(discordSRV, user);
}
@Override
public CompletableFuture<IOfflinePlayer> lookupOfflinePlayer(UUID uuid) {
IPlayer player = player(uuid);
if (player != null) {
return CompletableFuture.completedFuture(player);
}
return discordSRV.game().server().userManager()
.load(uuid)
.thenApply(optional -> optional.map(this::convert).orElse(null));
}
@Override
public CompletableFuture<IOfflinePlayer> lookupOfflinePlayer(String username) {
IPlayer player = player(username);
if (player != null) {
return CompletableFuture.completedFuture(player);
}
return discordSRV.game().server().userManager()
.load(username)
.thenApply(optional -> optional.map(this::convert).orElse(null));
}
public IOfflinePlayer offlinePlayer(User user) {
return convert(user);
}
}

View File

@ -1,56 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.plugin;
import com.discordsrv.common.plugin.Plugin;
import com.discordsrv.common.plugin.PluginManager;
import com.discordsrv.sponge.SpongeDiscordSRV;
import org.spongepowered.plugin.metadata.PluginMetadata;
import org.spongepowered.plugin.metadata.model.PluginContributor;
import java.util.List;
import java.util.stream.Collectors;
public class SpongePluginManager implements PluginManager {
private final SpongeDiscordSRV discordSRV;
public SpongePluginManager(SpongeDiscordSRV discordSRV) {
this.discordSRV = discordSRV;
}
@Override
public boolean isPluginEnabled(String pluginName) {
return discordSRV.game().pluginManager().plugin(pluginName).isPresent();
}
@Override
public List<Plugin> getPlugins() {
return discordSRV.game().pluginManager().plugins().stream()
.map(container -> {
PluginMetadata metadata = container.metadata();
String id = metadata.id();
List<String> authors = metadata.contributors().stream()
.map(PluginContributor::name)
.collect(Collectors.toList());
return new Plugin(id, metadata.name().orElse(id), metadata.version().toString(), authors);
})
.collect(Collectors.toList());
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.discordsrv.sponge.scheduler;
import com.discordsrv.common.scheduler.ServerScheduler;
import com.discordsrv.common.scheduler.StandardScheduler;
import com.discordsrv.sponge.SpongeDiscordSRV;
import org.spongepowered.api.scheduler.TaskExecutorService;
import java.util.concurrent.TimeUnit;
public class SpongeScheduler extends StandardScheduler implements ServerScheduler {
private final TaskExecutorService service;
public SpongeScheduler(SpongeDiscordSRV discordSRV) {
super(discordSRV);
this.service = discordSRV.game().server().scheduler().executor(discordSRV.container());
}
@Override
public void runOnMainThread(Runnable task) {
service.submit(task);
}
@Override
public void runOnMainThreadLaterInTicks(Runnable task, int ticks) {
service.schedule(task, ServerScheduler.ticksToMillis(ticks), TimeUnit.MILLISECONDS);
}
@Override
public void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) {
service.scheduleAtFixedRate(task, ServerScheduler.ticksToMillis(initialTicks), ServerScheduler.ticksToMillis(rateTicks), TimeUnit.MILLISECONDS);
}
}